How do i properly update information in a text file? - c#

I want to save some data in a text file like this:
Name = Frank
Age = 28
Registered = False
Now i want to read/update the Data contained in each row. For example I need to change the Name to "Tim", I have to find row Name and than replace the string after the "="
Im not quiet sure how to solve this properly and i couldnt find anything on Google that satisfied me
I tried to update it with the text.Replace() method but it only chances the string it actually finds.
I expect to read the correct data out of the row and replace it if needed

There are a wide variety of ways to do this. I'll contribute one of them (which I think is simpler to understand).
Step 1: Read the entire file into a string.
Step 2: Convert it to string.
Step 3: Process the string using simple methods like split and join.
Step 4: Overwrite the previous file with the processed string.
The code is below:
if (File.Exists(your_file_path)){
string yourfile = File.ReadAllText(your_file_path);
// Now the file is a simple string that you can manipulate using
// string split functions.
// For Example:
// break by lines
string[] lines = yourfile.Split('\n');
foreach (string line in lines){
if (line.Substring(0,4) == "Name"){
// replace the necessary line
line = "Name = Tim";
break;
}
}
// Join the array again
yourfile = lines.Join("\n", lines);
File.WriteAllText(your_file_path, yourfile);
}

Try to save the file in Json format. Like
{
"Name" : "Frank"
"Age" : 28
"Registered" : False
}
Then read the file deserialize it to object by using Newtonsoft json
Then update your property(Name) serialize it to string again and then write again to the same file.
In this Approach very less chances of errors.

Related

How to search string in large text file?

I want to get the line containing a certain word that cannot be repeated like profile ID without make loop to read each of line separately, Because if the word I am looking for is in the last line of the text file, this will take a lot of time to get it, and if the search process is for more than one word and extract the line that contains it, I think it will take a lot of time.
Example for line text file
name,id,image,age,place,link
string word = "13215646";
string output = string.Empty;
using (var fileStream = File.OpenRead(FileName))
using (var streamReader = new StreamReader(fileStream, Encoding.UTF8))
{
String line;
while ((line = streamReader.ReadLine()) != null)
{
string[] strList = line.Split(',');
if (word == strList[1]) // check if word = id
{
output = line;
break;
}
}
}
You can use this to search the file:
var output = File.ReadLines(FileName).
Where(line => line.Split(',')[1] == word).
FirstOrDefault();
But it won't solve this:
if the word I am looking for is in the last line of the text file, this will take a lot of time to get it, and if the search process is for more than one word and extract the line that contains it, I think it will take a lot of time.
There's not a practical way to avoid this for a basic file.
The only ways around actually reading through the file is either maintaining an index, which requires absolute control over everything that might write into the file, or if you can guarantee the file is already sorted by the columns that matter, in which case you can do something like a binary search.
But neither is likely for a random csv file. This is one of the reasons people use databases.
However, we also need to stop and check whether this is really a problem for you. I'd expect the code above to handle files up to a couple hundred MB in around 1 to 2 seconds on modern hardware, even if you need to look through the whole file.
You can optimise the code. Here are few ideas:
var ids = new ["13215646", "113"];
foreach(var line in File.ReadLines(FileName))
{
var id = line.Split(',', count: 3)[1]; // Optimization 1: Use: `count: 3`
if(ids.Contains(id) // Optimization 2: Search for multiple ids
{
//Do what you need with the line
}
}

Display string after certain words are found

Basically what I'm trying to do is find the first string that starts with "/Game/Mods" but the problem is how do i tell the program where to end the string? here's an example what a string can look like: string example
As you can see the string starts with "/Game/Mods", i want it to end after the word "TamingSedative", the problem is that the ending word (TamingSedative)is different for every file it has to check, for example: example 2
There you can see that the ending word is now "WeapObsidianSword" (instead of TamingSedative) so basically the string has to end when it comes across the "NUL" but how do i specify that in c# code?
This a simple example using Regex.
Dim yourString As String = "/Game/Mods/TamingSedative/PrimalItemConsumable_TamingSedative"
Dim M As System.Text.RegularExpressions.Match = System.Text.RegularExpressions.Regex.Match(yourString, "/Game/Mods/(.+?)/")
MessageBox.Show(M.Groups(0).Value) 'This should show /Game/Mods/TamingSedative/
MessageBox.Show(M.Groups(1).Value) 'This should show TamingSedative
Since you need only the first occurance, this is the simplest solution I could think of:
(In case you cannot see the image, click on it to open in new tab)
EDIT:
In case the existence of a path like this is not guaranteed in the string, you can do an additional check before proceeding to use Substring, like this:
int exists = fullString.IndexOf("/Game/Mods");
if (exists == -1) return null;
Note: I have included "ENDED" in order to see in case any NULL chars have been included (white spaces)
From your comments: "the string just has to start at /Game/Mods and end when it reaches the whitespace".
In that case, you can easily get the matches using Linq, like this (assuming filePath is a string that has the path to your file):
var text = File.ReadAllText(filePath);
var matches = text.Split(null).Where(s => s.StartsWith("/Game/Mods"));
And, if you only need the first occurrence, it would be:
var firstMatch = matches.Any() ? matches.First() : null;
Check this post.

parsing text from HTML source

I have this Html (xml form) result in my program
All I want is get info from this source(director - music .....)
is there any way to grouping text like 1 and 2 in picture with c# ?
The quickest option you have is to use .Split. First I will split the entire source with the character { (this will give you your sections) and then I will .Split again each one of those sections with the character | From there you only need to parse what you need, you'll end up with an array of Name=Values.
Something like this will help:
var blocks = YourVariableHoldingSource.Split('{')
foreach(var block in blocks){
var details = blocks.Split('|')
foreach(var data in details){
MessageBox.Show(data);
}
}

Find and replace file lines

I have a text file with over 12,000 lines. In that file I need to replace certain lines.
Some lines begin with a ;, some have random words, some start with space. However, I am only concerned with the two types of lines I describe below.
I have a line like
SET avariable:0 ;Comments
and I need to replace it to look like
set aDIFFvariable:0 :Integer // comments
The only CASE that is necessary is in the word Integer I needs to be capitalized.
I also have
String aSTRING(7) ;Comment
that needs to look like
STRING aSTRING(7) :array [0..7] of AnsiChar; // Comments
I need to keep all the spacing the same.
Here is what I have so far
static void Main(string[] args)
{
string text = File.ReadAllText("C:\\old.txt");
text = text.Replace("old text", "new text");
File.WriteAllText("C:\\new.txt", text);
}
I think I need to use REGEX, which I have tried to make for my first example:
\s\s[set]\s*{4}.*[:0]\s*[;].* <-- I now know this is invalid - please advise
I need help with properly setting up my program to find and replace those lines. Should I read one line at a time and if it matches then do something? I am confused really as to where to start.
BRIEF pseudo code of what I want to do
//open file
//step through file
//if line == [regex] then add/replace as needed
//else, go to next line
//if EOF, close file
Taking a stab at this separately because each line is so radically different that capturing both in the same expression will be a nightmare.
To match your first example and replace it:
String input = "SET avariable:0 ;Comments";
if (Regex.IsMatch(input, #"\s?(set)\s*(\w+):?(\d)\s+;?(.*)?"))
{
input = Regex.Replace(input, #"\s?(set)\s*(\w+):?(\d)\s+;?(.*)?", "$1 $2:$3 :Integer // $4";
}
Give that a shot (Play with it here: http://regex101.com/r/zY7hV2)
To match your second example and replace it:
String input = "String aSTRING(7) ;Comments";
if (Regex.IsMatch(input, #"\s?(string)\s*(\w+)\((\d)\)\s*;(.*)"))
{
input = Regex.Replace(input, #"\s?(string)\s*(\w+)\((\d)\)\s*;(.*)", "$1 $2($3) :array [0..$3] of AnsiChar; // $4";
}
And play around with this one here: http://regex101.com/r/jO5wP5

Retrieving a Single File and the Behavior of Directory.GetFiles C#

public int RunStageData(string rootDirectory, stringdataFolder)
{
string[] files = new string[] { };
files = Directory.GetFiles(rootDirectory + dataFolder);
string[] tableOrder = new string[] { };
tableOrder = Directory.GetFiles(#"C:\_projects\ExampleProject\src", "TableOrder.txt");
System.IO.StreamReader tableOrderReader = new System.IO.StreamReader(tableOrder[0]);
for (int count = 0; count < files.Length; count++)
{
string currentTableName =tableOrderReader.ReadLine();
//files[count] = Directory.GetFiles(#"C:\_projects\ExampleProject\src", currentTableName);
}
}
Hi everyone, sorry if my code is a bit sloppy. I'm having an issue primarily with the line I have commented out. So basically what I'm trying to do here is to populate a string array of file names based on the ordering of these names in a txt file. So I read the first line from the txt file, then retrieve the name of that file in the directory(assuming it exists) and put it in the first spot of the array, then move on.
For Example if the txt file had these words in the following order:
Dog
Sheep
Cat
I would want the array to have Dog first, then Sheep, then Cat. My issue is that the line that I have commented gives me an error that says "Error 41 Cannot implicitly convert type 'string[]' to 'string'"
I'm guessing the reason for this is that Directory.GetFiles has the possibility of returning multiple files. So, is there another method I could use to achieve the results I'm looking for? Thank you.
I am assuming you want the contents of the file (if you just want the file name and need to check for existance a different solution will be required).
files[count] = File.ReadAllText(Path.Combine(#"C:\_projects\ExampleProject\src", currentTableName));
And a couple other suggestions:
Don't initialize your variables with bogus data, = new string[] {} can be removed
Don't use count as an indexer, it is confusing (count is a property of the array after all)
Use Path.Combine when joining paths. It is much easier as it handles the \ for you.
From your question:
So basically what I'm trying to do here is to populate a string array
of file names based on the ordering of these names in a txt file. So I
read the first line from the txt file, then retrieve the name of that
file in the directory(assuming it exists) and put it in the first spot
of the array, then move on.
So, your TableOrder.txt already contains the files in the correct order, thus you can do:
string[] files = File.ReadAllLines(#"C:\_projects\ExampleProject\src\TableOrder.txt")
If your array files contains only paths, you can do it as:
path = #"C:\_projects\ExampleProject\src\" + currentTableName;
If(File.Exists(path))
{
files[count] = path;
}

Categories