Find regex in file with StreamReader and overwrite it with StreamWriter - c#

I am reading text file with StreamReader and doing Regex.Match to find specific info, now when I found it I want to replace it with Regex.Replace and I want to write this replacement back to the file.
this is text inside my file:
///
/// <Command Name="Press_Button" Comment="Press button" Security="Security1">
///
/// <Command Name="Create_Button" Comment="Create button" Security="Security3">
/// ... lots of other Commands
now I need to find : Security="Security3"> in Create_Button command, change it to Security="Security2"> and write it back to the file
do {
// read line by line
string ReadLine = InfoStreamReader.ReadLine();
if (ReadLine.Contains("<Command Name"))
{
// now I need to find Security1, replace it with Security2 and write back to the file
}
}
while (!InfoStreamReader.EndOfStream);
any ideas are welcome...
EDITED:
Good call was from tnw to read and write to the file line by line. Need an example.

I'd do something more like this. You can't directly write to a line in the file like you're describing there.
This doesn't use regex but accomplishes the same thing.
var fileContents = System.IO.File.ReadAllText(#"<File Path>");
fileContents = fileContents.Replace("Security1", "Security2");
System.IO.File.WriteAllText(#"<File Path>", fileContents);
Pulled pretty much directly from here: c# replace string within file
Alternatively, you could loop thru and read your file line-by-line and write it line-by-line to a new file. For each line, you could check for Security1, replace it, and then write it to the new file.
For example:
StringBuilder newFile = new StringBuilder();
string temp = "";
string[] file = File.ReadAllLines(#"<File Path>");
foreach (string line in file)
{
if (line.Contains("Security1"))
{
temp = line.Replace("Security1", "Security2");
newFile.Append(temp + "\r\n");
continue;
}
newFile.Append(line + "\r\n");
}
File.WriteAllText(#"<File Path>", newFile.ToString());
Source: how to edit a line from a text file using c#

Related

Creating files using c#, like an evernote

I currently am making a UI for a note keeper and was just going to preview documents etc, but i was wondering what file type i would need to create if instead i wanted to do things like tag the file etc, preferably in c#, basically make my own evernote, how do these programs store the notes?
I dont know how to directly tag the file, but you could create your own system to do it. I mentioned two ways to do it:
The first way is to format the note's / file's contents so that there are two parts, the tags and the actual text. When the program loads the note / file, it seperates the tags and the text. This has the downside that the program have to load the whole file to just find the tags.
The second way is to have a database with the filename and it's associated tags. In this way the program doesn't have to load the whole file just to find the tags.
The first way
In this solution you need to format your files in a specific way
<Tags>
tag1,tag2,tag3
</Tags>
<Text>
The text you
want in here
</Text>
By setting up the file like this, the program can separate the tags from the text. To load it's tags you'd need this code:
public List<string> GetTags(string filePath)
{
string fileContents;
// read the file if it exists
if (File.Exists(filePath))
fileContents = File.ReadAllText(filePath);
else
return null;
// Find the place where "</Tags>" is located
int tagEnd = fileContents.IndexOf("</Tags>");
// Get the tags
string tagString = fileContents.Substring(6, tagEnd - 6).Replace(Environment.NewLine, ""); // 6 comes from the length of "<Tags>"
return tagString.Split(',').ToList();
}
Then to get the text you'd need this:
public string GetText(string filePath)
{
string fileContents;
// read the file if it exists
if (File.Exists(filePath))
fileContents = File.ReadAllText(filePath);
else
return null;
// Find the place where the text content begins
int textStart = fileContents.IndexOf("<Text>") + 6 + Environment.NewLine.Length; // The length on newLine is neccecary because the line shift after "<Text>" shall NOT be included in the text content
// Find the place where the text content ends
int textEnd = fileContents.LastIndexOf("</Text>");
return fileContents.Substring(textStart, textEnd - textStart - Environment.NewLine.Length); // The length again to NOT include a line shift added earlier by code
}
Then I'll let you find out how you do the rest.
The second way
In this solution you have a database file over all your files and their associated tags. This database file would look like this:
[filename]:[tags]
file.txt:tag1, tag2, tag3
file2.txt:tag4, tag5, tag6
The program will then read the file name and the tags in this way:
public static void LoadDatabase(string databasePath)
{
string[] fileContents;
// End process if database doesn't exist
if (File.Exists(databasePath))
return;
fileContents = File.ReadAllLines(databasePath); // Read all lines seperately and put them into an array
foreach (string str in fileContents)
{
string fileName = str.Split(':')[0]; // Get the filename
string tags = str.Split(':')[1]; // Get the tags
// Do what you must with the information
}
}
I hope this helps.

How can I write and read a text doucument in a folder?

string curetn = Environment.CurrentDirectory;
string path = curetn.ToString() + #"\DATA\SaveGame.txt";
Console.WriteLine(path);
TextReader tr = new StreamReader(path);
Hello, I am making a text-adventure, and I do not like having all my save files, and mp3 file in the same place as my application. I would like for the files to be in a folder. I want to be able to use StreamWriter and StreamReader, to be able to write and read files that are in a folder. This file is also in a distributable folder, not just in the Visual Studios Projects folders. I have tried everything I can, and this is what I have. I also have one of these for StreamWriter. Please help!
Edit:
The thing that does not work, is that it does not read the lines, and assigns them to a variable. I have it in a try-catch, and it catches, and displays the error message that I wrote.
If you are looking for simply read and write lines from file you can try this
using (StreamReader sr = new StreamReader(path))
{
while (!sr.EndOfStream)
{
sr.ReadLine();
}
}
string s;
using (StreamWriter sw = new StreamWriter(path))
{
sw.WriteLine(s);
}
So basically what you want to do is read the text file:
string data[] = File.ReadAllLines(path); // Read the text file.
var x = data[1]; // Replace the '1' with the line number you want.
Console.WriteLine(x);
This is a good way to read the text file, I think it's better than opening a stream.
You can also write to it, so every time you want to save, just do this:
// When you want to write:
File.WriteAllText(path, "");
File.AppendAllText(path, "Add a data line" + Environment.NewLine); // Environment.NewLine adds a line.
Keep appending text to the file for the data you need.

Replace one specific line in a huge text file

I want to replace one specific line in a text file. The simplest solution would be:
public void ModifyFile(string path, int line, string targetText) {
var lines = File.ReadAllLines(path);
lines[line] = targetText;
File.WriteAllLines(path, lines);
}
The thing is, if the file is huge enough, I will get a System.OutOfMemoryException because File.ReadAllLines() tries to load the whole file in memory, instead of a line-by-line way.
I know there is another way to read a specific line with less memory cost:
var line = File.ReadLines(path).Skip(line-1).Take(1).ToString();
How can I replace over that line in the file?
I'm looking for something like FileStream.Write Method:
var writer = File.OpenWrite(path);
writer.Write(Encoding.UTF8.GetBytes(targetText),
offset, Encoding.UTF8.GetByteCount(targetText));
But it's difficult to know offset.
Is there a better way to do that?
-- UPDATE --
The temporary file solution suggested by answers works great.
At the same time, I am wondering, is there a specific case solution without creating a temporary file, if I know line is a small number (line < 100 let's say)? There must be a better solution if I want to change the 10th line in a text file having 100m lines.
You could just read the file a line at a time using streams, and copy the contents into a new file, or rename the old file with a backup name and then process with;
string line;
int couinter = 0;
// Read the file and display it line by line.
System.IO.StreamReader reader = new System.IO.StreamReader(path);
System.IO.StreamWriter writer = new System.IO.StreamWriter(new_path);
while((text = reader.ReadLine()) != null)
{
// Check for your content and replace if required here
if ( counter == line )
text = targetText;
writer.writeline(text);
counter++;
}
reader.Close();
writer.Close();
What you can do is open the FileStrem with StreamReader (which provides ReadLine method). Now read line by line and write the output to a temporary file line by line. When you are on the desired line just change the line.

How can I edit a text file using C#?

Lets say i have a text file with following content:
Hello!
How are you?
I want to call the file via a simple application that produces an output file with the following contents:
buildLetter.Append("Hello!").AppendLine();
buildLetter.Append("How are you?").AppendLine();
As you see, every line should be put between " ".
Any help will be appreciated.
void ConvertFile(string inPath, string outPath)
{
using (var reader = new StreamReader(inPath))
using (var writer = new StreamWriter (outPath))
{
string line = reader.ReadLine();
while (line != null)
{
writer.WriteLine("buildLetter.Append(\"{0}\").AppendLine();",line.Trim());
line = reader.ReadLine ();
}
}
}
You should add some I/O exception handling on your own.
If you want to append "" to each line you could try combining the ReadAllLines and WriteAllLines methods:
File.WriteAllLines(
"output.txt",
File
.ReadAllLines("input.txt")
.Select(line => string.Format("\"{0}\"", line))
.ToArray()
);
Notice that this loads the whole file contents into memory so it wouldn't work well with very large files. In this case stream readers and writers are more adapted.
Use the StreamReader class from System.IO
Refer this link for sample code
All you probably need to do is change the line
Console.WriteLine(sr.ReadLine());
to
Console.WriteLine(""""" + sr.ReadLine() + """""); // handwritten code - not tested :-)
For a small text files this works for me.
private void EditFile(string path, string oldText, string newText)
{
string content = File.ReadAllText(path);
content = contenido.Replace(oldText, newText);
File.WriteAllText(path, content);
}

Formatting a text file, how to update the file after I finished parsing it?

How would I open a file, perform some regex on the file, and then save the file?
I know I can open a file, read line by line, but how would I update the actual contents of a file and then save the file?
The following approach would work regardless of file size, and will also not corrupt the original file in anyway if the operation would fail before it is complete:
string inputFile = Path.Combine(Environment.GetFolderPath(
Environment.SpecialFolder.MyDocuments), "temp.txt");
string outputFile = Path.Combine(Environment.GetFolderPath(
Environment.SpecialFolder.MyDocuments), "temp2.txt");
using (StreamReader input = File.OpenText(inputFile))
using (Stream output = File.OpenWrite(outputFile))
using (StreamWriter writer = new StreamWriter(output))
{
while (!input.EndOfStream)
{
// read line
string line = input.ReadLine();
// process line in some way
// write the file to temp file
writer.WriteLine(line);
}
}
File.Delete(inputFile); // delete original file
File.Move(outputFile, inputFile); // rename temp file to original file name
string[] lines = File.ReadAllLines(path);
string[] transformedLines = lines.Select(s => Transform(s)).ToArray();
File.WriteAllLines(path, transformedLines);
Here, for example, Transform is
public static string Transform(string s) {
return s.Substring(0, 1) + Char.ToUpper(s[1]) + s.Substring(2);
}
Open the file for read. Read all the contents of the file into memory. Close the file. Open the file for write. Write all contents to the file. Close the file.
Alternatively, if the file is very large:
Open fileA for read. Open a new file (fileB) for write. Process each line of fileA and save to fileB. Close fileA. Close fileB. Delete fileA. Rename fileB to fileA.
Close the file after you finish reading it
Reopen the file for write
Write back the new contents

Categories