There are a lot of different ways to read and write files (text files, not binary) in C#.
I just need something that is easy and uses the least amount of code, because I am going to be working with files a lot in my project. I only need something for string since all I need is to read and write strings.
Use File.ReadAllText and File.WriteAllText.
MSDN example excerpt:
// Create a file to write to.
string createText = "Hello and Welcome" + Environment.NewLine;
File.WriteAllText(path, createText);
...
// Open the file to read from.
string readText = File.ReadAllText(path);
In addition to File.ReadAllText, File.ReadAllLines, and File.WriteAllText (and similar helpers from File class) shown in another answer you can use StreamWriter/StreamReader classes.
Writing a text file:
using(StreamWriter writetext = new StreamWriter("write.txt"))
{
writetext.WriteLine("writing in text file");
}
Reading a text file:
using(StreamReader readtext = new StreamReader("readme.txt"))
{
string readText = readtext.ReadLine();
}
Notes:
You can use readtext.Dispose() instead of using, but it will not close file/reader/writer in case of exceptions
Be aware that relative path is relative to current working directory. You may want to use/construct absolute path.
Missing using/Close is very common reason of "why data is not written to file".
FileStream fs = new FileStream(txtSourcePath.Text,FileMode.Open, FileAccess.Read);
using(StreamReader sr = new StreamReader(fs))
{
using (StreamWriter sw = new StreamWriter(Destination))
{
sw.Writeline("Your text");
}
}
The easiest way to read from a file and write to a file:
//Read from a file
string something = File.ReadAllText("C:\\Rfile.txt");
//Write to a file
using (StreamWriter writer = new StreamWriter("Wfile.txt"))
{
writer.WriteLine(something);
}
using (var file = File.Create("pricequote.txt"))
{
...........
}
using (var file = File.OpenRead("pricequote.txt"))
{
..........
}
Simple, easy and also disposes/cleans up the object once you are done with it.
#AlexeiLevenkov pointed me at another "easiest way" namely the extension method. It takes just a little coding, then provides the absolute easiest way to read/write, plus it offers the flexibility to create variations according to your personal needs. Here is a complete example:
This defines the extension method on the string type. Note that the only thing that really matters is the function argument with extra keyword this, that makes it refer to the object that the method is attached to. The class name does not matter; the class and method must be declared static.
using System.IO;//File, Directory, Path
namespace Lib
{
/// <summary>
/// Handy string methods
/// </summary>
public static class Strings
{
/// <summary>
/// Extension method to write the string Str to a file
/// </summary>
/// <param name="Str"></param>
/// <param name="Filename"></param>
public static void WriteToFile(this string Str, string Filename)
{
File.WriteAllText(Filename, Str);
return;
}
// of course you could add other useful string methods...
}//end class
}//end ns
This is how to use the string extension method, note that it refers automagically to the class Strings:
using Lib;//(extension) method(s) for string
namespace ConsoleApp_Sandbox
{
class Program
{
static void Main(string[] args)
{
"Hello World!".WriteToFile(#"c:\temp\helloworld.txt");
return;
}
}//end class
}//end ns
I would never have found this myself, but it works great, so I wanted to share this. Have fun!
These are the best and most commonly used methods for writing to and reading from files:
using System.IO;
File.AppendAllText(sFilePathAndName, sTextToWrite);//add text to existing file
File.WriteAllText(sFilePathAndName, sTextToWrite);//will overwrite the text in the existing file. If the file doesn't exist, it will create it.
File.ReadAllText(sFilePathAndName);
The old way, which I was taught in college was to use stream reader/stream writer, but the File I/O methods are less clunky and require fewer lines of code. You can type in "File." in your IDE (make sure you include the System.IO import statement) and see all the methods available. Below are example methods for reading/writing strings to/from text files (.txt.) using a Windows Forms App.
Append text to an existing file:
private void AppendTextToExistingFile_Click(object sender, EventArgs e)
{
string sTextToAppend = txtMainUserInput.Text;
//first, check to make sure that the user entered something in the text box.
if (sTextToAppend == "" || sTextToAppend == null)
{MessageBox.Show("You did not enter any text. Please try again");}
else
{
string sFilePathAndName = getFileNameFromUser();// opens the file dailog; user selects a file (.txt filter) and the method returns a path\filename.txt as string.
if (sFilePathAndName == "" || sFilePathAndName == null)
{
//MessageBox.Show("You cancalled"); //DO NOTHING
}
else
{
sTextToAppend = ("\r\n" + sTextToAppend);//create a new line for the new text
File.AppendAllText(sFilePathAndName, sTextToAppend);
string sFileNameOnly = sFilePathAndName.Substring(sFilePathAndName.LastIndexOf('\\') + 1);
MessageBox.Show("Your new text has been appended to " + sFileNameOnly);
}//end nested if/else
}//end if/else
}//end method AppendTextToExistingFile_Click
Get file name from the user via file explorer/open file dialog (you will need this to select existing files).
private string getFileNameFromUser()//returns file path\name
{
string sFileNameAndPath = "";
OpenFileDialog fd = new OpenFileDialog();
fd.Title = "Select file";
fd.Filter = "TXT files|*.txt";
fd.InitialDirectory = Environment.CurrentDirectory;
if (fd.ShowDialog() == DialogResult.OK)
{
sFileNameAndPath = (fd.FileName.ToString());
}
return sFileNameAndPath;
}//end method getFileNameFromUser
Get text from an existing file:
private void btnGetTextFromExistingFile_Click(object sender, EventArgs e)
{
string sFileNameAndPath = getFileNameFromUser();
txtMainUserInput.Text = File.ReadAllText(sFileNameAndPath); //display the text
}
Or, if you are really about lines:
System.IO.File also contains a static method WriteAllLines, so you could do:
IList<string> myLines = new List<string>()
{
"line1",
"line2",
"line3",
};
File.WriteAllLines("./foo", myLines);
It's good when reading to use the OpenFileDialog control to browse to any file you want to read. Find the code below:
Don't forget to add the following using statement to read files: using System.IO;
private void button1_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
textBox1.Text = File.ReadAllText(openFileDialog1.FileName);
}
}
To write files you can use the method File.WriteAllText.
class Program
{
public static void Main()
{
//To write in a txt file
File.WriteAllText("C:\\Users\\HP\\Desktop\\c#file.txt", "Hello and Welcome");
//To Read from a txt file & print on console
string copyTxt = File.ReadAllText("C:\\Users\\HP\\Desktop\\c#file.txt");
Console.Out.WriteLine("{0}",copyTxt);
}
}
private void Form1_Load(object sender, EventArgs e)
{
//Write a file
string text = "The text inside the file.";
System.IO.File.WriteAllText("file_name.txt", text);
//Read a file
string read = System.IO.File.ReadAllText("file_name.txt");
MessageBox.Show(read); //Display text in the file
}
Reading from file
string filePath = #"YOUR PATH";
List<string> lines = File.ReadAllLines(filePath).ToList();
Writing to file
List<string> lines = new List<string>();
string a = "Something to be written"
lines.Add(a);
File.WriteAllLines(filePath, lines);
Simply:
String inputText = "Hello World!";
File.WriteAllText("yourfile.ext",inputText); //writing
var outputText = File.ReadAllText("yourfile.ext"); //reading
You're looking for the File, StreamWriter, and StreamReader classes.
So I'm making a program to type what's in my clipboard into a text file, I plan on later transporting this information into an AHK script, but I want to do this all in one program, so if possible it will append to the .ahk file, but instead of it appending to the very last line, I need it to append to the line before return, which is the final line of the file.
Send ::redeem N4E2vzCEp {enter}
Sleep 1000
return
That's the end of the file, if possible I want my program to do something like:
string pasted = Clipboard.GetText();
sw.WriteLine.SecondLastLine("Send ::redeem " + pasted + " {enter}");
sw.WriteLine.SecondLastLine("Sleep 1000"); //Fully aware that secondlastline is not a valid command
But I don't know what the proper way of actually coding this would be.
Current code:
private void paste_Click(object sender, EventArgs e)
{
string path = #"c:\users\john\desktop\auths.txt";
using (StreamWriter sw = File.AppendText(path))
{
string pasted = Clipboard.GetText();
sw.WriteLine("Send ::redeem " + pasted + " {enter}");
sw.WriteLine("Sleep 1000");
}
}
What you can do is reading all lines into a List and then insert the new line at a specific position and write the lines back to the file.
List<string> lines = File.ReadAllLines("your file").ToList();
lines.Insert(lines.Count - 2, "new line");
File.WriteAllLines("your file", lines);
I have a small winform app with a button, which, when clicked, I want to search a text file (file.txt) for a specific word and replace the entire line on which it was found by something else.
Let's say my text file is:
ohad yes no
box cat dog
etc...
I want to search for ohad and once find it replace the line "ohad yes no" to new line "yes I did it"
so the txt file will be:
yes I did it
box cat dog
etc...
This is my code so far:
string lineX;
StringBuilder sb = new StringBuilder();
using (System.IO.StreamReader file = new System.IO.StreamReader(textBox20.Text))
{
while ((lineX = file.ReadLine()) != null)
{
if (lineX.Contains("SRV"))
{
sb.AppendLine(lineX.ToString());
}
}
}
StreamReader streamReader;
streamReader = File.OpenText(textBox20.Text);
string contents = streamReader.ReadToEnd();
streamReader.Close();
StreamWriter streamWriter = File.CreateText(textBox20.Text);
streamWriter.Write(contents.Replace(sb.ToString(), textBox26.Text + textBox29.Text + textBox30.Text + textBox27.Text + textBox28.Text));
streamWriter.Close();
Thanks you all in advance
Ohad
Try this:
// Read file into a string array (NOTE: You should check if exists first!)
string[] Lines = File.ReadAllLines(textBox20.Text);
for(int i=0;i<Lines.Length;i++) {
if(Lines[i].Contains("SRV")) {
Lines[i] = "New value for line";
// if you only want to replace one line, uncomment the next row:
// break;
}
}
// Write array back to file
File.WriteAllLines(textBox20.Text, Lines);
for a starter, how about following these comments i put together.
var s = #"
ohad yes no
box cat dog
";
//split string into array
//go through each item in array
//check if it contains "ohad"
//if so, replace that line with my text
//convert array to string
I am reading a small csv file on 2 pages using the same code. On localhost using a local csv file everything works! On the server, however it works on Page1 but Page2 appears to be showing old data.
I call getDataCSV() from each page and return a string
string getDataCSV()
{
StringBuilder s = new StringBuilder();
string filePath = utility.GetAbsPathFile(orgWebSite, "files", "UDAP_Donors.csv");
IEnumerable<string[]> lines = File.ReadAllLines(filePath).Select(a => a.Split(','));
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`
s.Append("<div class='donor_level'>Level 1</div>|");
s.Append(getData2(lines,"C"));
s.Append("<div class='donor_level'>Level 2</div>|");
s.Append(getData2(lines, "R"));
....
return s.ToString();
}
string getData2(IEnumerable<string[]> lines, string x)
{
StringBuilder s = new StringBuilder();
var corp = from line in lines where line[1].Equals(x) orderby line[0] select line;
foreach (var c in corp)
{
s.Append(getString(c[0].ToString()));
}
return s.ToString();
}
string getString(string c)
{
return string.Format(#"<div class='donor'><div class='donor_name'>{0}</div></div> |", c.Replace("'", "\'"));
}
On Page 1 I am taking this string and adding it into a js scroller - works fine.
On Page 2 I am just putting the string into a literal control. The data shown here, tho, is from the 1st csv file I uploaded, I have since overwritten (or deleted and reuoloaded) several times.
I have added some dummy characters to the return strings and these characters show on both pages so I know the code is being called.
Any ideas would be greatly appreciated.
this is the code for page 2
public string GetDonations2(string yr)
{
StringBuilder s = new StringBuilder();
s.AppendFormat(#"<div class='donor_thanks'>Thank You to the Sponsors</div><div class='donor'><br /></div>");
s.Append(getDataCSV());
return s.ToString();
}
this then gets assigned to a literal
the string going to page 1 gets wrapped in some js ... but that works... the only reference to the file is the string filePath way above
Problem solved ... page 2 was not getting the value for orgWebSite and by accident was reading an old file that had been uploaded to that same location - aargh
So, I am creaing a "Hangman" game, with a word editor to put your own word in the game. I have a form which opens a text file and displays the content in a multi-line textbox. After that the user can edit the textbox. If you press "save" the content from the textbox will be saved to the text file.
Now, everything works good, the reading and the writing. But now if I want to play my words, its always longer than the word I entered. I found out via debugging that somehow my programm adds "/r" behind every word. For example if I enter "Test" in the wordeditor, the game would use it as "Test/r".
I believe it is an error in the wordeditor so here is the code:
namespace Hangman
{
public partial class WordEditor : Form
{
public WordEditor()
{
InitializeComponent();
using (StreamReader sr = new StreamReader(new FileStream("C:\\Users\\tstadler\\Desktop\\Hangman.txt", FileMode.Open)))
{
string[] Lines = sr.ReadToEnd().Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < Lines.Length; i++)
{
textBox1.Text += Lines[i] + Environment.NewLine;
}
}
}
private void saveToolStripMenuItem_Click(object sender, EventArgs e)
{
string[] words = textBox1.Text.Split('\n');
FileStream overwrite = new FileStream("C:\\Users\\tstadler\\Desktop\\Hangman.txt", FileMode.Create);
using (StreamWriter file = new StreamWriter(overwrite))
{
for (int i = 0; i < words.Length; i++)
{
file.Write(words[i] + Environment.NewLine);
}
}
MessageBox.Show("Words saved. ");
}
Can anyone tell me if he recognizes the error?
Thanks.
Everywhere you insert new lines you use Environment.NewLine - except for one line:
string[] words = textBox1.Text.Split('\n');
Which results in a string splitted by \n whereas Environment.NewLine consists of \r\n on a Windows system. Thus after the split the \rremains at the end of the string.
To resolve that issue simple replace the line mentioned above with
string[] words = textBox1.Text.Split(new string[] { Environment.NewLine });
Use File.ReadAllLines:
Opens a text file, reads all lines of the file, and then closes the file:
A line is defined as a sequence of characters followed by a carriage return \r, a line feed \n, or a carriage return immediately followed by a line feed.
and File.WriteAllLines:
Creates a new file, write the specified string array to the file, and then closes the file.
sample:
string[] lines = File.ReadAllLines("filePath");
File.WriteAllLines("filePath", textBox.Text.Split(new[] {Environment.NewLine}));
Your solution is almosut correct but very verbose look at this:
File.ReadAllLines;
and
File.WriteAllText;
so your read section would be:
textBox1.Text = string.Join(Environment.NewLine,
File.ReadAllLines(filePath).Where(x=>!string.IsNullOrWhiteSpace(x)));
and write
File.WriteAllText(filePath,textBox1.Text);