I have the following problem:
I use this code to open a file and write to it:
using (FileStream fileStream = new FileStream(saveDir + #"\" + saveFile, FileMode.Open, FileAccess.ReadWrite,FileShare.ReadWrite))
{
StreamWriter streamWriter = new StreamWriter(fileStream);
streamWriter.Write("Test");
streamWriter.Close();
}
but in the "using" line it tells me that it can not open the file because it is used by another process but the file is not open and isn't used. What's wrong?
I searched around this forum and the internet but I can't find a solution.
You could try using FileMode.OpenOrCreate instead of creating the file "manually":
using (FileStream fileStream = new FileStream(saveDir + #"\" + saveFile,
FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite))
{
StreamWriter streamWriter = new StreamWriter(fileStream);
streamWriter.Write("Test");
streamWriter.Close();
}
Related
I'm trying to read and write to the same file in a way such that no other program can access the file in between:
FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
StreamReader sr = new StreamReader(fs);
StreamWriter sw = new StreamWriter(fs);
newString = sr.ReadToEnd() + "somethingNew";
sw.Write(newString);
fs.Close();
The file is never written to. If I debug I can see that the reader manages to fetch the contents of the file, but the writer does not seem to be able to write to the file. Nothing happens.
I've been looking at this question which seems to be the same as mine. However I'm not able to get it to work.
Just Flush your changes to file, Have sw.Flush(); before closing the stream. like:
string filePath = "test.txt";
FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
StreamReader sr = new StreamReader(fs);
StreamWriter sw = new StreamWriter(fs);
newString = sr.ReadToEnd() + "somethingNew";
sw.Write(newString);
sw.Flush(); //HERE
fs.Close();
You may see this post simultaneous read-write a file in C# (open multiple streams for reading and writing)
As mentioned above - just add the Flush() to force the data held in the stream to be written to the file. In a comment you mentioned that you had previously used a 'using' statement but this hadn't worked.
Briefly here's why:
A using statement automatically calls Flush() so you don't have
to.
When you dispose of a StreamReader (or StreamWriter) - like by using a 'using' statement - the inner stream object is also disposed and you lose the handle to the stream.
#EJS a simple static method that you can use to create a new file if it does not exist as well as write to the same file if it does exist
Simple usage
string path = #"C:\SomePath\Name.txt";
if (!System.IO.File.Exists(path))
{
WriteAndOrAppendText(path, "File Created");
}
else if (System.IO.File.Exists(path))
{
WriteAndOrAppendText(path, "New Boot.");
}
private static void WriteAndOrAppendText(string path, string strText)
{
if (!File.Exists(path))
{
using (StreamWriter fileStream = new StreamWriter(path, true))
{
fileStream.WriteLine(strText);
fileStream.Flush();
fileStream.Close();
}
}
else
{
using (StreamWriter fileStream2 = new StreamWriter(path, true))
{
fileStream2.WriteLine(strText);
fileStream2.Flush();
fileStream2.Close();
}
}
}
For being able to create a file, append to it, and read the data in it while still allowing an application to write to it, as I believe you are trying to do, here's a set up I created:
string path = #"C:\SomePath\MyLogFile.txt";
public static string Log(string Message)
{
try
{
if (File.Exists(path) == false)
File.Create(path).Close(); // need this .Close()!!!
logCounter++;
string logString = logCounter + " " + DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToShortTimeString() + ": " + Message + Environment.NewLine;
using (FileStream fs = new FileStream(path, FileMode.Append, FileAccess.Write, FileShare.ReadWrite))
{
using (StreamWriter sw = new StreamWriter(fs))
{
sw.Write(logString);
}
}
return logString; // only necessary so we can return an error in the Exception block
}
catch (Exception ex)
{
return "Logger: Cannot log data. " + ex.ToString();
}
}
It's actually required to use FileAccess.Write if you do FileMode.Append - instead of being able to use FileAccess.ReadWrite - but I found that didn't matter because whatever had been written would have been closed and flushed to the file, and I could still open the file and read it (it wouldn't be locked & blank) using these. I have sw.Write() because I have Environment.NewLine that I added into my logString, but I could've done sw.WriteLine() and removed that, if I had wanted to.
One caveat: File.Exists() has issues if the path is long - can't remember the limit, but just know that there is one, so don't put your file you're writing to several layers deep. Less is always better.
/*Initialize FileStreams for both writing and reading*/
writeStream = new FileStream(logfilePath, FileMode.Append, FileAccess.Write, FileShare.Read);
readStream = new FileStream(logfilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
/*Initialize the Writer and Reader*/
fileWrite = new StreamWriter(writeStream);
fileRead = new StreamReader(readStream);
So this is what I use to be able to constantly write and read to the same file. How can I clear the file without the need to close both streams temporarily, clear file, and reopen them again?
using System.IO;
class test
{
public static void Main()
{
string path=#"c:\mytext.txt";
if(File.Exists(path))
{
File.Delete(path);
}
FileStream fs=new FileStream(path,FileMode.OpenOrCreate);
StreamWriter str=new StreamWriter(fs);
str.BaseStream.Seek(0,SeekOrigin.End);
str.Write("mytext.txt.........................");
str.WriteLine(DateTime.Now.ToLongTimeString()+" "+DateTime.Now.ToLongDateString());
string addtext="this line is added"+Environment.NewLine;
File.AppendAllText(path,addtext); //Exception occurrs ??????????
string readtext=File.ReadAllText(path);
Console.WriteLine(readtext);
str.Flush();
str.Close();
Console.ReadKey();
//System.IO.IOException: The process cannot access the file 'c:\mytext.txt' because it is //being used by another process.
// at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
}
}
Try This
string path = #"c:\mytext.txt";
if (File.Exists(path))
{
File.Delete(path);
}
{ // Consider File Operation 1
FileStream fs = new FileStream(path, FileMode.OpenOrCreate);
StreamWriter str = new StreamWriter(fs);
str.BaseStream.Seek(0, SeekOrigin.End);
str.Write("mytext.txt.........................");
str.WriteLine(DateTime.Now.ToLongTimeString() + " " +
DateTime.Now.ToLongDateString());
string addtext = "this line is added" + Environment.NewLine;
str.Flush();
str.Close();
fs.Close();
// Close the Stream then Individually you can access the file.
}
File.AppendAllText(path, addtext); // File Operation 2
string readtext = File.ReadAllText(path); // File Operation 3
Console.WriteLine(readtext);
In every File Operation, The File will be Opened and must be Closed prior Opened. Like wise in the Operation 1 you must Close the File Stream for the Further Operations.
You are writing to the file prior to closing your filestream:
using(FileStream fs=new FileStream(path,FileMode.OpenOrCreate))
using (StreamWriter str=new StreamWriter(fs))
{
str.BaseStream.Seek(0,SeekOrigin.End);
str.Write("mytext.txt.........................");
str.WriteLine(DateTime.Now.ToLongTimeString()+" "+DateTime.Now.ToLongDateString());
string addtext="this line is added"+Environment.NewLine;
str.Flush();
}
File.AppendAllText(path,addtext); //Exception occurrs ??????????
string readtext=File.ReadAllText(path);
Console.WriteLine(readtext);
The above code should work, using the methods you are currently using. You should also look into the using statement and wrap your streams in a using block.
File.AppendAllText does not know about the stream you have opened, so will internally try to open the file again. Because your stream is blocking access to the file, File.AppendAllText will fail, throwing the exception you see.
I suggest you used str.Write or str.WriteLine instead, as you already do elsewhere in your code.
Your file is created but contains nothing because the exception is thrown before str.Flush() and str.Close() are called.
using (var fs = new FileStream(filePath, FileMode.Append, FileAccess.Write, FileShare.ReadWrite))
using (var sw = new StreamWriter(fs))
{
sw.WriteLine(message);
}
In the following, streamwriter is not throwing an exception if the file does not exist.
I expected it to raise an exception, why doesn't it and how can I get it to do so?
var fileName = HttpContext.ApplicationInstance.Server.MapPath("~/App_Data/emails.txt");
FileStream fs = new FileStream(fileName, FileMode.Append);
StreamWriter sw = new StreamWriter(fs);
sw.WriteLine(String.Format("{0}\t{1}", email, name));
sw.Flush();
sw.Close();
fs.Close();
Why?
FileStream fs = new FileStream(fileName, FileMode.Append);
This will create the file if it doesn't exist (and append to it if it does).
Assuming from your post (there is no question in it!) you don't want it to create a file first call File.Exists to ensure the file exists.
If you want to make sure you're appending to an existing file, use FileMode.Open and then Seek to the end before writing.
With File.Exists there is a (very slim) chance of an other process deleting the file after checking but before the construction of the FileStream.
Try this:
try
{
var fileName = HttpContext.ApplicationInstance.Server.MapPath("~/App_Data/emails.txt");
if (System.IO.File.Exists(fileName ))
{
FileStream fs = new FileStream(fileName, FileMode.Append);
StreamWriter sw = new StreamWriter(fs);
sw.WriteLine(String.Format("{0}\t{1}", email, name));
sw.Flush();
sw.Close();
fs.Close();
}
else
{
//Throw error here
}
}
catch()
{
}
In the following code I get the error "stream was not writable":
class Class1
{
private static void Main()
{
FileStream fs = new FileStream("C:\\fFile.txt",
FileMode.OpenOrCreate,
FileAccess.ReadWrite,
FileShare.ReadWrite);
StreamReader r = new StreamReader(fs);
string t = r.ReadLine();
r.Close();
Console.WriteLine(t);
StreamWriter w = new StreamWriter(fs);
w.WriteLine("string");
w.Flush();
w.Close();
fs.Close();
}
}
The error occurs at this line StreamWriter w = new StreamWriter(fs);
Why is this?
from msdn
Closes the StreamReader object and the underlying stream, and releases any system resources associated with the reader.
So the stream you try to write to is invalid you need to reopen the stream and reopen the file.
r.Close();
There's your problem after you read. The close() methods close the underlying stream.
You'll have to re-open the file since the read closes it:
FileStream fs = new FileStream("C:\\test.txt",
FileMode.OpenOrCreate,
FileAccess.ReadWrite,
FileShare.ReadWrite);
using (StreamReader r = new StreamReader(fs))
{
string t = r.ReadLine();
r.Close();
Console.WriteLine(t);
}
fs = new FileStream("C:\\test.txt",
FileMode.OpenOrCreate,
FileAccess.ReadWrite,
FileShare.ReadWrite);
using (StreamWriter w = new StreamWriter(fs))
{
w.WriteLine("string");
w.Flush();
w.Close();
}
fs.Close();
Dont close the first StreamWriter, it will close the underlying stream.
And use using statements as Oscar suggests.
using (FileStream fs = new FileStream("C:\\temp\\fFile.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite))
{
StreamReader r = new StreamReader(fs);
string t = r.ReadLine();
Console.WriteLine(t);
StreamWriter w = new StreamWriter(fs);
w.WriteLine("string");
w.Close();
r.Close();
fs.Close();
}
Do not close the StreamReader. Just comment the line below and it will work.
r.Close();