Reading from text file using StreamReader - c#

I have a text file and I'm using a StreamReader for read the entire file to a String array (String[]). So I'm using the StreamReader.ReadToEnd().Split() method for this. But the text file can contain for example a full name (so words which I want to use as one String) so I wrote this file using '|' as separator but when I use StreamReader.ReadToEnd().Split('|') the String array contains elements like this "\r\nSomeString". I think it occurs when I'm using StreamWriter.WriteLine().
Is there a way I can handle this problem?

Can you try System.IO.File
example:
string text = System.IO.File.ReadAllText(#"C:\Users\Public\TestFolder\WriteText.txt");
// Display the file contents to the console. Variable text is a string.
System.Console.WriteLine("Contents of WriteText.txt = {0}", text);
// Example #2
// Read each line of the file into a string array. Each element
// of the array is one line of the file.
string[] lines = System.IO.File.ReadAllLines(#"C:\Users\Public\TestFolder\WriteLines2.txt");
// Display the file contents by using a foreach loop.
System.Console.WriteLine("Contents of WriteLines2.txt = ");
foreach (string line in lines)
{
// Use a tab to indent each line of the file.
Console.WriteLine("\t" + line);
}
foreach (string line in System.IO.File.ReadAllLines(#"C:\Users\Public\TestFolder\WriteLines2.txt"))
{
var myArray = line.Split('\t');
}

Related

C# How to duplicate line in text file (.txt) when button is clicked?

I've a winform application and I want to ducplicate a line in a text file (.txt) when I click a button.
eg :
Hello world
and I want to have something like:
Hello world
Hello world
when I click a button.
void duplicateLine(string text, int line){
//Read text file
//duplicate the line
//insert (Write) the duplicate line in text file(.txt)
}
One way to duplicate a line in a text file in C# is to use the File.ReadAllLines method to read the file into a string array, then use a loop to insert the duplicate line at the desired index, and then use the File.WriteAllLines method to write the modified array back to the file. For example, the following code snippet duplicates the first line of a text file:
void duplicateLine(string text, int line)
{
//Read the file into a string array
string[] lines = File.ReadAllLines("textfile.txt");
//Create a list to store the modified lines
List<string> newLines = new List<string>();
//Loop through the array and insert the duplicate line
for (int i = 0; i < lines.Length; i++)
{
//Add the original line to the list
newLines.Add(lines[i]);
//If the line is the one to be duplicated, add it again
if (i == line)
{
newLines.Add(lines[i]);
}
}
//Write the modified list back to the file
File.WriteAllLines("textfile.txt", newLines);
}
This code will result in a text file like this:
Hello world
Hello world
Some other line
Another line
It is better to write the code yourself and ask questions about the code problems. Try the following method:
1-Read all line of file to list using File.ReadAllLines
2- check line if not exist in the file
3-Add a new line at a specific position of list( duplicate one line)
4-Write list to file
void duplicateLine(string text, int line){
string _path = "data.txt"; //path of your file
var txtLines = File.ReadAllLines(_path).ToList(); //1
if(line>=txtLines.Count) //2
{
MessageBox.Show("this line not exist in file..");
return;
}
txtLines.Insert(line, Text); //3
File.WriteAllLines(_path, txtLines); //4
}

How to add text to the line that starts with "hello" in a file

I have a file that contains many lines. There is a line here looking like below:
hello jim jack nina richi sam
I need to add a specific text salmon in this line and change it to below (it could be added anywhere in this line -end -begining - in the middle -doesnt matter ):
hello jim jack nina richi sam salmon
I tried:
string path = #"C:\testFolder\newTestLog.txt";
StreamReader myReader = new StreamReader(path);
string[] allLines = File.ReadAllLines(path);
foreach (string element in allLines) {
if (element.StartsWith("hello"))
{
Console.WriteLine(element);
}
}
myReader.Close();
}
Using this I'm able to read the file line by line and add each line to an array and print that line if that starts with "hello", but I'm not sure how to add text to this line
You should use what Joel answered it's nicer but if you're having trouble implementing it try this. After adding the salmon to the lines that start with hello you can overwrite the txt file by using File.WriteAllLines
string filePath = #"C:\testFolder\newTestLog.txt";
string[] allLines = File.ReadAllLines(filePath);
for(int i = 0; i < allLines.Length; i++)
{
if (allLines[i].StartsWith("hello"))
{
allLines[i] += " salmon";
}
}
File.WriteAllLines(filePath, allLines);
Try this:
string path = #"C:\testFolder\newTestLog.txt";
var lines = File.ReadLines(path).Select(l => l + l.StartsWith("hello")?" salmon":"");
foreach (string line in lines)
Console.WriteLine(line);
Note that this still only writes the results to the Console, as your sample does. It's not clear what you really want to happen with the output.
If you want this saved to the original file, you've opened up a small can of worms. Think of all of the data in your file as if it's stored in one contiguous block1. If you append text to any line in the file, that text has nowhere to go but to overwrite the beginning of the next. As a practical matter, if you need to modify file, this often means either writing out a whole new file, and then deleting/renaming when done, or alternatively keeping the whole file in memory and writing it all from start to finish.
Using the 2nd approach, where we keep everything in memory, you can do this:
string path = #"C:\testFolder\newTestLog.txt";
var lines = File.ReadAllLines(path).Select(l => l + l.StartsWith("hello")?" salmon":"");
File.WriteAllLines(path, lines);
1 In fact, a file may be split into several fragments on the disk, but even so, each fragment is presented to your program as part of a single whole.

How to not include data in a text file if it is already in there

I want to add data into a text file based on a specific output, it will read an XML file and write a certain line to a text file. If the data is already written into the text file, i dont want to write it again.
Code:
public void output(string folder)
{
string S = "Data" + DateTime.Now.ToString("yyyyMMddHHmm") + ".xml";
//Trades.Save(S);
string path = Path.Combine(folder, S);
Console.WriteLine(path);
XDocument f = new XDocument(Trades);
f.Save(path);
string[] lines = File.ReadAllLines(path);
File.WriteAllLines(path, lines);
using (System.IO.StreamWriter file = new System.IO.StreamWriter(#"H:\Test" + DateTime.Now.ToString("yyMMdd") + ".txt", true))
{
foreach (string line in lines)
{
if (line.Contains("CertainData"))
{
file.WriteLine(line);
if (File.ReadAllLines(path).Any(x => x.Equals(line)))
{
}
else
{
string[] tradeRefLines = File.ReadAllLines(path);
File.WriteAllLines(path, tradeRefLines); ;
}
}
}
}
}
The problem is it will still write the line even if the data is exactly the same elsewhere. I don't want duplicate lines
Any advice?
CLARIFICATION UPDATE
The "CertainData" is a reference number
I have a bunch of files that has data in it and the piece i want to seperate and put into a text file is "CertainData" field, which will have a reference number
Sometimes the files i get sent will have the same formatted information inside it with the "CertainData" appearing in their for reference
When i run this programme, if the text file i have already contains the "CertainData" reference number inside it, i dont want it to be written
If you need anymore clarification let me know and i will update the post
I think you want this: read all lines, filter out those containing a keyword and write it to a new file.
var lines = File.ReadAllLines(path).ToList();
var filteredLines = lines.Where(!line.Contains("CertainData"));
File.WriteAllLines(path, filteredLines);
If you also want to remove duplicate lines, you can add a distinct like this:
filteredLines = filteredLines.Distinct();
Why you don't use Distinct before for loop. This will filter your lines before write in file.
Try something like this
string[] lines = new string[] { "a", "b", "c", "a" };
string[] filterLines = lines.Distinct().ToArray<string>();

Replace Linefeeds in Text file

I got a text file where each row ends with CRLF which is fine, but file got some rows with LF within the row content.
Am trying to replace the LF which are within the row content as below:
var fileContent = File.ReadAllText(fileName);
fileContent = Regex.Replace(fileContent, #"(?<!\r)\n", " ");
File.WriteAllText(fileName, fileContent);
This works fine. But when am trying to deal with large file (more than 150mb), throws memory exception.
Tried with
List<string> text = File.ReadAllLines(filePath).ToList();
to read lines and replace by line. But this doesn't work as it splits like on LF
How can I force to split lines by CRLF
You can use the File.ReadLines that returns IEnumerable which means that it only extract one line at a time when needed using the yield functionality.
After successfully writing to anotherFilename we then deleting fileName and moving anotherFilename to his position.
foreach (var line in File.ReadLines(fileName))
{
File.WriteAllText(anotherFilename, line + Environment.NewLine);
}
File.Delete(fileName);
File.Move(anotherFilename, filename);
Note: Haven't been tested.

StreamReader does not read in carriage returns

I have to write a console application for a computer course that I'm taking. The program reads text in from a file using StreamReader, splits the string into single words and saves them in a String array and then prints the words out backwards.
Whenever there is a carriage return in the file, the file stops reading in the text. Could anyone help me with this?
Here is the main program:
using System;
using System.IO;
using System.Text.RegularExpressions;
namespace Assignment2
{
class Program
{
public String[] chop(String input)
{
input = Regex.Replace(input, #"\s+", " ");
input = input.Trim();
char[] stringSeparators = {' ', '\n', '\r'};
String[] words = input.Split(stringSeparators);
return words;
}
static void Main(string[] args)
{
Program p = new Program();
StreamReader sr = new StreamReader("input.txt");
String line = sr.ReadLine();
String[] splitWords = p.chop(line);
for (int i = 1; i <= splitWords.Length; i++)
{
Console.WriteLine(splitWords[splitWords.Length - i]);
}
Console.ReadLine();
}
}
}
And here is the file "input.txt":
This is the file you can use to
provide input to your program and later on open it inside your program to process the input.
You can use StreamReader.ReadToEnd instead of StreamReader.ReadLine.
// Cange this:
// StreamReader sr = new StreamReader("input.txt");
// String line = sr.ReadLine();
string line;
using (StreamReader sr = new StreamReader("input.txt"))
{
line = sr.ReadToEnd();
}
The addition of the using block will make sure the input file is closed properly, as well.
Another alterantive would just be to use:
string line = File.ReadAllText("input.txt"); // Read the text in one line
ReadLine reads a single line from the file, and strips off the trailing carraige return and line feed characters.
ReadToEnd will read the entire file as a single string, and preserve those characters, allowing your chop method to work as written.
You are just reading in one line. You need to read all lines till end of file.
The following should work:
String line = String.Empty;
using (StreamReader sr = new StreamReader("input.txt"))
{
while (!sr.EndOfStream)
{
line += sr.ReadLine();
}
}
The problem is that you're calling ReadLine() which does exactly that, it reads til it encounters a carriage return (you have to call it in a loop).
Typically if you want to read a file line by line with StreamReader the implementation looks more like this (from msdn);
using (StreamReader sr = new StreamReader("TestFile.txt"))
{
string line;
// Read and display lines from the file until the end of
// the file is reached.
while ((line = sr.ReadLine()) != null)
{
Console.WriteLine(line);
}
}
The condition in the while loop ensures that you will read til the end of the file because ReadLine will return null if there is nothing to read.
Another option is just to use File.ReadAllLines(MyPath) which will return an array of strings, each element being one line in the file. To give a more complete example of that;
string[] lines = File.ReadAllLines(MyFilePath);
foreach(string line in lines)
{
string[] words = line.Split(' ').Reverse();
Console.WriteLine(String.Join(" ", words));
}
Those three lines of code do the following; Reads the entire file into a string array where each element is a line. Loops over that array, on each line we split it into the words and reverse their order. Then I join all the words back together with spaces between them and print it to the console. If you want the whole file in reverse order then you need to start at the last line instead of the first, I'll leave that detail to you.

Categories

Resources