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.
I know this is a bit of a "Day one" question, but I'm still having trouble understanding why my Stream writer is writing empty lines after each time it writes
namespace PostFinder
{
class HistorySaver
{
public static void Save(string item, string path)
{
StreamReader sre = new StreamReader(path);
string historyList = sre.ReadToEnd();
sre.Dispose();
StreamWriter sr = new StreamWriter(path);
sr.WriteLine(historyList+sr.NewLine+item);
sr.Dispose();
}
}
}
sr.WriteLine(historyList+sr.NewLine+item);
The .WriteLine() method puts an end-of-line character after the contents you pass to it. If you don't want that character, use .Write().
It looks like all you are wanting to do is append text to a file, so there is really no need to open a streamreader to read in the existing contents and then write them back out with your new content.
You can use the below to do all that you want in one step. If the input path file doesn't exist it will create a new one, and if it already exists it will just append your new item.
namespace PostFinder
{
class HistorySaver
{
public static void Save(string item, string path)
{
File.AppendAllText(path, item + Environment.NewLine);
}
}
}
I have trying to mirror the output screen to .txt file.By my below code i can able to mirror the output screen to text file. When executing the obj.OutputFile("First text"); there is no problem But some times i need print like obj.OutputFile("Second text {0}",text);
I got the exception during the second line execution
No overload for method 'OutputFile' takes 2 arguments test document
How do i clear my exception?
I want to my code which is to be accept different number of arguments passing.
My Code
class Program
{
static void Main(string[] args)
{
string text = "Sample";
Program obj = new Program();
obj.OutputFile("First text");
obj.OutputFile("Second text {0}",text);
Console.ReadKey();
}
public void OutputFile(string text)
{
string path = "Example.txt";
if (!File.Exists(path))
{
using (TextWriter tw = new StreamWriter(path))
{
tw.WriteLine(text);
Console.WriteLine(text);
}
}
else if (File.Exists(path))
{
using (TextWriter tw = new StreamWriter(path,true))
{
tw.WriteLine(text);
Console.WriteLine(text);
}
}
}
}
I am totally new to this c#. So i hope your answer would be simple.
Your call for OutputFile doesn't seem correct. You have obj.OutputFile("Second text {0}",text); while the method signature is public void OutputFile(string text), which means it requires one parameter.
All you have to do is to change your call to:
obj.OutputFile(string.Format("Second text {0}", text));
And if you are using C# 6 you can make it even better:
obj.OutputFile($"Second text {text}");
change
obj.OutputFile("Second text {0}",text);
to
obj.OutputFile(string.Format("Second text {0}",text));
EDIT:
Your function definition for OutputFile has one parameter. With the comma between the strings you have two parameters instead of the expected one parameter.
I'm making a log for my program using a StreamWriter to write to a file. I have some code that looks like it works, but its only doing part of what it should.
I made a simple class called Log (code below).
public class Log
{
string path;
StreamWriter fs;
public Log(string fullPathToLogFile)
{
path = fullPathToLogFile;
fs = new StreamWriter(path);
writeLog("Starting log");
}
public void writeLog(string s)
{
fs.WriteLine(DateTime.Now.ToString("dd-MM-yyyy H:mm:ss ") + s);
}
public void closeLog()
{
writeLog("Closing log");
fs.WriteLine(); //add a blank line at the end
fs.Close();
}
}
I made a simple test program that works perfectly. It executes these three lines:
Log l = new Log(#"C:\Users\SADunkerton\Desktop\l.txt");
l.writeLog("testing log");
l.closeLog();
But in my much larger program, where I actually want to use the Log class, all I get is an empty file --no text inside. Its code looks like this:
Log log = new Log(folderPDFs + #"\Log.txt"); //folderPDFs is a parameter of this method--it is a string that is a complete path to a destination folder.
log.writeLog("Beginning conversions");
//do some stuff, including write to the log
log.writeLog("Finished converting. Success = " + success);
Can anyone tell me why the program version of this code isn't working?
I would rewrite your Log class to avoid the close part.
Just open, write and close after finishing the write part
class MySimpleLog
{
private string _filename;
public MySimpleLog(string filename)
{
_filename = filename;
}
public void AppendText(string msg)
{
// Create an instance of StreamWriter to write text to a file.
// The using statement also closes the StreamWriter.
using (StreamWriter sw = new StreamWriter(_filename, true))
{
// Add some text to the file.
sw.WriteLine(msg);
}
}
}
In this way the using statement will close the stream and you don't have to worry about closing it. Indeed closing the stream could be very troublesome if something unexpected happens in your code. (Like an exception that change your code flow).
This is just a starting point to have the code tested and verified, but you could add some more complex logic following the pattern given. For example you could add a constructor with a flag to add a timestamp for everyline (or a flag to add a separator line, or a flag to recreate the file if exists...)
class MySimpleLog
{
private string _filename;
private bool _addtime;
public MySimpleLog(string filename)
{
_filename = filename;
}
public MySimpleLog(string filename, bool addtime)
{
_filename = filename;
_addtime = addtime;
}
public void AppendText(string msg)
{
// Create an instance of StreamWriter to write text to a file.
// The using statement also closes the StreamWriter.
using (StreamWriter sw = new StreamWriter(_filename, true))
{
// Add some text to the file.
msg = (_addtime ? DateTime.Now.ToString() + ": " + msg : msg);
sw.WriteLine(msg);
}
}
}
FINALLY: Keep in mind that specialized log libraries exists well tested and free to use. Perhaps you could invest some of your time in learning them
Log4Net
NLog
1. You do not close the stream in the second example - and what will happen on garbage collection I am not sure. Call the l.closeLog(); in the end to at least get some output. But it is not a good idea. What will happen if some method throws between l.write(); and l.closeLog;. Something not good - file will left opened till GC deals with it.
2. You overwrite the file with each call. Probably what you need is to append the data - http://msdn.microsoft.com/en-us/library/3zc0w663(v=vs.110).aspx or even better change your code to use File.AppendText method:
public void writeLog(string s)
{
using (StreamWriter sw = File.AppendText(path))
{
sw.WriteLine(DateTime.Now.ToString("dd-MM-yyyy H:mm:ss ") + s);
}
}
And remove the closeLog method, because it is unnecessary.
EDIT:
The best idea is to just use stateless standard methods(as pointed by #leppie), that won't leak any resources:
It is File.WriteAllText if you create one logfile for each log instance:
public void writeLog(string s)
{
File.WriteAllText(path,
DateTime.Now.ToString("dd-MM-yyyy H:mm:ss ") + s);
}
or File.AppendAllText if you need to continue already existing logs:
public void writeLog(string s)
{
File.AppendAllText(path,
DateTime.Now.ToString("dd-MM-yyyy H:mm:ss ") + s);
}
I'm building a program that uses a WriteAllLines generic function:
private static void WriteAllLines(string file, string[] contents)
{
using (StreamWriter writer = new StreamWriter(file))
{
foreach (string line in contents)
{
writer.Write(line);
}
}
}
But the problem is that when I use it like this:
string temp = Path.GetTempFileName();
string file = ReadAllText(inputFile);
WriteAllLines(temp, value);
I know why this problem happens, it's because value is a string and I'm putting it in a place of a string array(string[]), but how I can change my code to solve this? Thanks.
Two options; params, or just new[] {value}
Meaning:
WriteAllLines(string file, params string[] contents) {...}
or
WriteAllLines(temp, new[] {value});
or (C# 2.0)
WriteAllLines(temp, new string[] {value});
Note that all do exactly the same thing in terms of creating arrays etc. The final option is to create a more-specific overload:
WriteAllLines(string file, string contents) {...}
why dont you WriteAllText method in File Class..
using System;
using System.IO;
using System.Text;
class Test
{
public static void Main()
{
string path = #"c:\temp\MyTest.txt";
// This text is added only once to the file.
if (!File.Exists(path))
{
// Create a file to write to.
string createText = "Hello and Welcome" + Environment.NewLine;
File.WriteAllText(path, createText);
}
// This text is always added, making the file longer over time
// if it is not deleted.
string appendText = "This is extra text" + Environment.NewLine;
File.AppendAllText(path, appendText);
// Open the file to read from.
string readText = File.ReadAllText(path);
Console.WriteLine(readText);
}
}