Why does my StreamWriter overwrite my whole .txt file? - c#

I'm changing a value within my text, but instead, it's overwriting my whole .txt file with nothing.
static void editClassMates(classMates[] classMateInfo)
{
StreamWriter sw = new StreamWriter(#"C:\Users\Callum\Documents\class.txt");
Console.Write("Who's number would you like to change? ");
string classMateInput = Console.ReadLine();
for (int i = 0; i < classMateInfo.Length; i++)
{
if (classMateInfo[i].last.Equals(classMateInput))
{
Console.Write("Enter new number: ");
string temp = Console.ReadLine();
int classMateNumber = Convert.ToInt32(temp);
classMateInfo[i].ID = classMateNumber;
}
}
sw.Close();
}
My code asks for a name within my .txt file. Once I have specified the name, it loops through until my input matches the same exact name in my .txt file. I now want to change his/her number. After I input a number, I then have a method that displays the list and the change I have made. That works, it shows me my original data along with the value I've edited.
However, I go into my class.txt file and it's completely blank now.
My question is, what part of my code is overwriting my whole file? Also, how can I properly change/edit/replace a specific value inside my .txt file?
Thanks

new StreamWriter(#"C:\Users\Callum\Documents\class.txt", true)
You are not using the overload to append. This is easily viewed in Intellisense as you type.
Hint: The File.Open-Method is even more easy to use. Topic in this SO article

Related

How to write text between certain lines using C# [duplicate]

This question already has answers here:
Adding a Line to the Middle of a File with .NET
(6 answers)
Closed 1 year ago.
I'd just like to start by saying the I am extremely new to C# and coding in general so please excuse the newbie mistakes.
I have a text document that looks something like this (inserted manually)
[VIDEO]
[!VIDEO]
And I want to be able to write some text in between these 2 "tags" without erasing them.
The current code I have to write things in the document is:
private void ReadVideoFiles()
{
string[] files =Directory.GetFiles(#"Z:\APP_LANX\VIDEOS", "*.mp4"); //Goes to the specific location of the file and gets the whole location
videoID = 0;
for (int i = 0; i < files.Length; i++)
{
videoID++;
files[i] = videoID.ToString() + ": " + files[i]; //changes the previous string so that it now contains the ID and the location
}
foreach (string file in files)
{
sw.WriteLine(file); //Uses the StreamWriter, declared previously
}
sw.Close();
}
But as you can imagine this just fully replaces everything in the document and adds the code, and the result is something like this:
1: Z:\APP_LANX\VIDEOS\vid1.mp4
2: Z:\APP_LANX\VIDEOS\vid2.mp4
3: Z:\APP_LANX\VIDEOS\vid3.mp4
4: Z:\APP_LANX\VIDEOS\vid4.mp4
instead of this
[VIDEO]
1: Z:\APP_LANX\VIDEOS\vid1.mp4
2: Z:\APP_LANX\VIDEOS\vid2.mp4
3: Z:\APP_LANX\VIDEOS\vid3.mp4
4: Z:\APP_LANX\VIDEOS\vid4.mp4
[!VIDEO]
Is there any way to check for these tags in specific so that I can write in between? Thank you!
Edit*: Later on I'll be adding new things to this text file, for example after the [!VIDEO] line I'll have other lines with something like EX1: 4 and multiple other lines that shouldn't be overwritten, only the part in between those tags can be changed.
TL:DR - Basically I want to be able to add text between those two tags (overwriting whatever is in between) while the rest of the text file remains unchanged
Assuming that your method ReadVideoFiles is called only, you could do something like this:
private void ReadVideoFiles()
{
string[] files =Directory.GetFiles(#"Z:\APP_LANX\VIDEOS", "*.mp4"); //Goes to the specific location of the file and gets the whole location
videoID = 0;
for (int i = 0; i < files.Length; i++)
{
videoID++;
files[i] = videoID.ToString() + ": " + files[i]; //changes the previous string so that it now contains the ID and the location
}
// Add header to file
sw.WriteLine($"[VIDEO]{Environment.NewLine}{Environment.NewLine}");
foreach (string file in files)
{
sw.WriteLine(file); //Uses the StreamWriter, declared previously
}
// Add footer to file
sw.WriteLine($"{Environment.NewLine}{Environment.NewLine}[!VIDEO]");
sw.Close();
}
Instead of inserting your input between the "tags", this code produces the complete file from scratch including the tags.
Maybe this is already sufficient for you? 🤔
If you don't want to spend too much time on it, you can just change :
sw.WriteLine(file);
by :
sw.WriteLine("[VIDEO]\n\n" + file + "\n\n[!VIDEO]");
You'll have the expected result.
You can insert your text at the index of the end tag in your list without overwriting any previous text you had in the file.
using System.IO;
using System.Linq;
endTag = "[!VIDEO]"
foreach (string file in files)
{
sw.Insert(sw.IndexOf(endTag), "text you want to add");
// You can replace "text you want to add" with your file variable
}
sw.Close();

Trying to print List into .txt only getting first line of contents

I am very new to C# so please dont judge me a lot :/
So i want the contents of the lists (Jazz,metal,pop,folk) to be added in a .txt file. when i do run the program it runs successfully and generates the file. But the file only has the word jazz in it. Of course i want all 4 lists to be working but i am trying only with jazz for now.
static void Main(string[] args)
{
List<Vocalist> jazz = new List<Vocalist>();
List<Vocalist> metal = new List<Vocalist>();
List<Vocalist> pop = new List<Vocalist>();
List<Vocalist> folk = new List<Vocalist>();
string recGenre;
Console.WriteLine("Which type of genre records you want to extract");
recGenre = Console.ReadLine();
if (recGenre == "jazz")
foreach (Vocalist i in jazz)
{
//FileStream Vocal = new FileStream("C:/Users/NikolaosParadeisanos/Desktop/jazz.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite);
File.WriteAllText("C:/Users/NikolaosParadeisanos/Desktop/jazz.txt", Convert.ToString(i.name));
File.WriteAllText("C:/Users/NikolaosParadeisanos/Desktop/jazz.txt", Convert.ToString(i.origin));
File.WriteAllText("C:/Users/NikolaosParadeisanos/Desktop/jazz.txt", Convert.ToString(i.vocalistType));
File.WriteAllText("C:/Users/NikolaosParadeisanos/Desktop/jazz.txt", Convert.ToString(i.genre));
}
//
}
As pointed in the method description if the target file already exists, it is overwritten. That means that every time you write in the specified file it gets overwritten with the last content (as you add the genre last it is the only thing left in the file. Try File.AppendAllLines instead.
File.AppendAllLines(#"C:/Users/NikolaosParadeisanos/Desktop/jazz.txt", new[] { Convert.ToString(i.name), Convert.ToString(i.origin), Convert.ToString(i.vocalistType), Convert.ToString(i.genre) });

How can I use Streamwriter to write in one line and whenever called again, to essentially delete that line and write on it again

Another way to say it is this: I want a program that logs the amount of times you've pressed a button. To do this I'd need a StreamWriter to write to a text document the number of times and a StreamReader to read the number of times as to display it when you start up the program.
If there is an easier way, feel free to share it. But my question is:
How can I make it so that it only writes in one line, and whenever it wants to write again to it, deletes the whole thing and puts in the new input?
The below will write to the file C:\log.txt. By setting the 2nd parameter to false, it will overwrite the contents of the file.
using (StreamWriter writer = new StreamWriter("C:\\log.txt", false))
{
writer.Write("blah");
}
To guarantee the file is always overwritten every time it is used, place the StreamWriter call in a different method like so:
public void DoStuff()
{
for(int i = 0; i < 20; i++)
{
WriteStuff("blah" + i);
}
}
private void WriteStuff(string text)
{
using (StreamWriter writer = new StreamWriter("C:\\log.txt", false))
{
writer.Write(text);
}
}

How to get "date modified" file properties to be copied line by line onto text file?

I am working on a code that copies information line by line from one text file and pastes it onto another. Each line contains "|" and after that symbol the timestamp of the date modified of each line is displayed. I am having trouble with finding a way that will allow me to access the date modified property from a build server when I run my utility and replaces the old date modified in the old text file with the new date modified property in the new text file. Here is what I have so far:
class Program
{
class NewTime
{
public DateTime Current { get; set; }
}
static void Main(string[] args)
{
int counter = 0;
string line;
// Read the file and display it line by line.
System.IO.StreamReader file = new System.IO.StreamReader(args[0]);
System.IO.StreamWriter filewriter = new System.IO.StreamWriter(args[1], false);
while ((line = file.ReadLine()) != null)
{
Thread.Sleep(10);
string [] pieces = line.Split(new char[] { '|' });
if(pieces.Length == 2)
{
*DateTime outDate;
if(DateTime.TryParse(pieces[1], out outDate))
{
string outputstring = string.Format(" {0:yyyy-MM-dd-hh-mm-ss-ff-tt}", DateTime.Now);
filewriter.WriteLine(pieces[0] + "|" + outputstring);
}*
else
filewriter.WriteLine(line);
}
else
filewriter.WriteLine(line);
System.Console.WriteLine(line);
counter++;
}
file.Close();
filewriter.Close();
System.Console.ReadLine();
}
}
The portion in between the stars was my first attempt, but that didn't give me what I want. It simply replaced the old time with the current time of when I ran the utility on my computer.
Any help is appreciated =)
If I'm understanding correctly, its looks like a timing problem: You want to replace the old date modified in the old text file with the new date modified property in the new text file. But DateTime.Now is not close enough, and you can't get the filesystem-generated DateModified (actually LastWriteTime) until the file has been saved on the file system.
If so, since you have to flush and close the new file for the file system to write the LastModified value, even re-reading the LastAccessTime on the newly created file FileInfo may not give you the value you are after.
It's a little messy because NTFS updates to the last write access time for a file can take an indeterminate amount of time to resolve after the last access. Even FAT systems have a write time resolution of ~2 seconds, according to Windows SDK
[http://msdn.microsoft.com/en-us/library/windows/desktop/ms724933(v=vs.85).aspx]
So, if replacing the old time with the current time (as you are doing) is not close enough, you would need to complete your initial file-creation loop, then derive a FileSystemInfo object on the file and call its Refresh method to get the latest value, and then re-write the value (LastWriteTime or LastAccessTime) into the file.
Refer to .Net Framework documentation for FileSystemInfo.LastAccessTime property for details: http://msdn.microsoft.com/en-us/library/system.io.filesysteminfo.lastaccesstime(v=vs.110).aspx

How to replace a data from a file if already exists and write a new data

Hi all i write a code to write my last row of datagrid view to a file as follows
private void Save_Click(object sender, EventArgs e)
{
if (dataGridView1.Rows.Count > 0)
{
List<string> lstContent = new List<string>();
foreach (DataGridViewRow row in dataGridView1.Rows)
{
if ((string)row.Cells[0].Value == "FileControl")
{
lstContent.Add((string)row.Cells[1].Value);
string mydata = string.Join(",", lstContent.ToArray());
using (StreamWriter sw = new StreamWriter(Append.FileName, true))
{
sw.WriteLine();
sw.Write(mydata);
}
}
}
}
}
But if i click multiple times on save this is writing that line multiple times what i need is if already that line exists in the file i have to replace that line with new line. Any help please
Your StreamWriter is explicitly using the file with append = true. Change the second parameter of the constructor to false if you want to overwrite the file each time. Docs are here. Quote:
append
Type: System.Boolean
Determines
whether data is to be appended to the
file. If the file exists and append is
false, the file is overwritten. If the
file exists and append is true, the
data is appended to the file.
Otherwise, a new file is created.
Revised code:
using (StreamWriter sw = new StreamWriter(Append.FileName, false))
{
sw.WriteLine();
sw.Write(mydata);
}
Replacing a given line in your file rather than just overwriting the whole file is a lot more difficult - this code is not going to get it done. StreamWriter is not great for this, you need random access and the ability to replace one data segment (line) by a different data segment of different length, which is an expensive operation on disk.
You might want to keep the files in memory as a container of Strings and do your required line replacement within the container, then write out the file to disk using File.WriteAllLines - that's if the file is not too big.

Categories

Resources