Write lines in file when the file exists c# - c#

i try to write line in file when this exists:
My code is next:
string strRuta = "C:\File.txt"
if (!Directory.Exists(strRuta))
Directory.CreateDirectory(strRuta);
string psContenido = "Hola";
if (!(File.Exists(strRuta + strNombreArchivo)))
{
swArchivo = File.CreateText(strRuta + strNombreArchivo);
}
if (!psContenido.ToLower().Contains("error"))
{
swArchivo.WriteLine(psContenido);
swArchivo.Flush();
swArchivo.Close();
swArchivo.Dispose();
File.SetCreationTime(strRuta + strNombreArchivo, DateTime.Now);
}
but when run this program i have a error in WriteLine, i donĀ“t undertand which is the reason, could you help me?
I would like to know how to write in the file(in the next line the word)

There are a couple of problems, I think. First, you're specifying what looks like a file name and creating a directory with that name (not sure if this is intentional or not). Second, you can use the static helper method AppendAllText of the File class to both create the file if it doesn't exist, and to write the contents to the end of the file. It handles all the streamwriter stuff for you, so you don't have to worry about calling close and dispose.
private static void Main(string[] args)
{
string directory = #"C:\private\temp";
string fileName = "MyFile.txt";
string filePath = Path.Combine(directory, fileName);
string fileContents = "This will be written to the end of the file\r\n";
// This will create the directory if it doesn't exist
Directory.CreateDirectory(directory);
// This will create the file if it doesn't exist, and then write the text at the end.
File.AppendAllText(filePath, fileContents);
File.SetCreationTime(filePath, DateTime.Now);
}

Related

Stream using behavior

I got simple code, which basically copies file from one dir to another.
string fileName = "kur.csv";
var path = #"D:\" + fileName;
Stream stream = File.OpenRead(fileName);
using Stream s = File.Create(path); // remove "using" from this line
stream.CopyTo(s);
But if I remove "using" (from 4th line start) - code doesn't work on *.csv or *.txt files. But works on *.jpg, *.docx files.
Why it works on some and why it doesn't work on others?
If I had to write a method that copies a file, I'd do something like this:
static void CopyFile(string fileName)
{
var scourceFilePath = Path.Combine(#"D:", fileName);
var destinationFilePath = Path.Combine(#"D:", "destination", fileName);
File.Copy(scourceFilePath, destinationFilePath);
}
This works for all filetypes. You could also check if the directory exists (Directory.Exists(directoryPath)) before referencing it which prevents the program from crashing if the directory does in fact not exist.
I use Path.Combine since by using it I don't have to keep track of the backslashes used.
Every method I mentioned and used is contained in the System.IO namespace.
I hope, that's what you were looking for.

Empty file saved after stream object write line command [duplicate]

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.

Code not creating a text file C#

I am trying to create a program that checks if the following file exists and if not, create one and write name to it. But the program doesn't create a file and doesn't throw any exceptions.
string verify;
string name = textBox1.Text;
string path = Path.Combine(#"C:\assets\"+ name + ".txt");
if (!File.Exists(path))
{
File.Create(path);
File.WriteAllText(path, name);
}
else if (File.Exists(path))
{
verify = File.ReadAllText(path);
if (verify == name)
{
return;
}
}
Make sure that the folder C:\assets exists, otherwise your program will throw an exception.
File.Create(path) will create the file, but when you call File.WriteAllText(path, name) it would throw an exception because your file may still be opened. Therefore you should remove File.Create(path), File.WriteAllText(path, name); will create a file and then close it after writing to it.
I would eliminate File.Create(path); from your code and see what happens. File.WriteAllText(path, name); will Create the file for you so it is unnecessary, and you may be getting an IO exception that is being swallowed up elsewhere in your code that is throwing you off the scent.

IO Exception - File being used by another process (Can't open file following directory creation)

I have got a project on the go that monitors patients for a vet while they are being operated on and writes the result to a text file. While I was experimenting with the outputting I just let the files save in the Debug folder, which worked fine. However, I've now created a full directory that creates or opens a main folder, and then a sub folder (based on input text from the program), to save the text file into.
private void createDirectory()
{ //create output file in this folder using owner name and current date
//main folder path (contains all files output from system)
string rootDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\\Horse Monitoring Records";
//sub folder path (each patient has individual subfolder)
string subDirectory = rootDirectory + "\\" + txtPatName.Text + "-" + txtOwnerName.Text;
//file name (patient has file created for each operation)
fileName = subDirectory + "\\" + txtOwnerName.Text + "-" + DateTime.Now.Date.ToString("ddMMyyyy") + ".txt";
if (!Directory.Exists(rootDirectory)) //if main folder does not exist...
{
Directory.CreateDirectory(rootDirectory); //create it in My Documents
}
if (!Directory.Exists(subDirectory)) //if patient sub folder does not exist...
{
Directory.CreateDirectory(subDirectory); //create it in Patient-Owner format
}
if (!File.Exists(fileName)) //if monitoring file does not exist...
{
File.Create(fileName); //create it in Owner-Date format
}
}
This stage works fine, but as soon as you try to save some data to the text file, it throws to a run time error stating that
The file cannot be accessed because it is being used by another process.
The exception is brought up here:
private void saveFileDetails()
{
//Once case details have been entered, create new file using these details and add data input structure
StreamWriter consoleFile = new StreamWriter(fileName);
...
}
When I went and checked out the folder, the relevant sub-folder and file had been created but the text file was blank.
I'm guessing it's something to do with closing the text file after creating the directory, which means it's already open when the system tries to open it. I can't figure out how to sort this issue out though!
The two functions shown above are called like this:
private void btnStart_Click(object sender, EventArgs e)
{
...
//file details entered upon load written to new file - according to PatID
createDirectory();
saveFileDetails();
}
Any suggestions on where to go from here would be very much appreciated!
Thanks,
Mark
The issue here is that you do
if (!File.Exists(fileName)) //if monitoring file does not exist...
{
File.Create(fileName); //create it in Owner-Date format
}
Right before you try to write to the file. Because you've just created it (if it didn't exist), chances are that the operating system hasn't released the file yet.
Like #Jauch mentioned in the comments, you could skip this check completely and use the StreamWriter overload which will create file if it doesn't exist, or append to it if it does.
private void saveFileDetails()
{
//Once case details have been entered, create new file using these details and add data input structure
using (StreamWriter consoleFile = new StreamWriter(fileName, true))
{
// ...
}
}
Alternatively you can use the following to write all of your text at once:
File.AppendAllText(textToWrite, fileName);
File.Create(fileName) returns an open stream to the file which is never closed.
To create an empty file use File.WriteAllBytes(fileName, new byte[0]);
Otherwise the 2 methods can be shortend
private void SaveFileDetails()
{
string subDirectory = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
"Horse Monitoring Records");
// create the folder hierarchy if not exists. does nothing if already there
Directory.CreateDirectory(subDirectory);
// each patient has individual file
var filepath = Path.Combine(subDirectory,
txtPatName.Text + "-" + txtOwnerName.Text + "-" + DateTime.Now.Date.ToString("yyyyMMdd") + ".txt");
// creates the file if not exists
using (var writer = new StreamWriter(filepath, append: true, encoding: Encoding.UTF8))
{
// write details
}
}
Note:
merged 2 methods
.NET naming conventions applied
changed dateformat to better sort by name in explorer
StreamWriter implements IDisposable, so wrapping it in a using block can manage closing and disposing the writer and ensuring it is available the next time you want to touch that file. It can also manage creating the text file if it doesn't exist, removing the need to explicitly call File.Create.
StreamWriter consoleFile = new StreamWriter(fileName);
becomes
using (StreamWriter writer = File.AppendText("log.txt"))
{
// writing, etc.
}
or
using (StreamWriter writer = new StreamWriter(fileName, true))
{ // true says "append to file if it exists, create if it doesn't"
// writing, etc.
}
Whatever seems more readable to you will work fine.

Why does my StreamWriter not write to file?

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);
}

Categories