I have a C# app that tries to read a log file which is being written to by another app. When I try to read the file, I get IOException
"The process cannot access the file ... because it is being used by
another process."
What I tried using so far are the following, but none of them fix the problem
var log = File.ReadAllText(logPath);
var stream = new FileStream(logPath, FileMode.Open);
using (var stream = File.Open(logPath, FileMode.Open))
{
}
try this:
FileStream logFileStream = new FileStream("c:\test.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
StreamReader logFileReader = new StreamReader(logFileStream);
while (!logFileReader.EndOfStream)
{
string line = logFileReader.ReadLine();
// Your code here
}
// Clean up
logFileReader.Close();
logFileStream.Close();
edited with MethodMan's suggestions
using(FileStream logFileStream = new FileStream(#"c:\test.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
using(StreamReader logFileReader = new StreamReader(logFileStream))
{
string text = logFileReader.ReadToEnd();
// Your code..
}
}
You can do nothing, if the "another app" does not use Share.Read while creating/opening the file.
Related
I am creating a new excel file using a template file, but I am unable to edit the contents in the new file created, please assist with the same.
Thanks in advance.
FileStream fileStream = new FileStream(filepath, FileMode.Open, FileAccess.Read);
using (ExcelPackage package = new ExcelPackage(fileStream))
{
package.Save();
}
string name = "filecreated.xlsx";
string fileType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
fileStream.Position = 0;
//return file
return File(fileStream, fileType, name);```
It Seems like you are opening the file in read only access mode
FileStream fileStream = new FileStream(filepath, FileMode.Open,
FileAccess.Read);
Will you please try like
FileInfo existingFile = new FileInfo(filepath);
using (ExcelPackage package = new ExcelPackage(existingFile))
{
//As we have not modified the file, its useless to call Save()
//This will override the opened file
package.Save();
}
Like in title:
FileStream fs = new FileStream ("test.mkv", FileMode.Open);
FileStream fs1 = new FileStream ("test.mkv", FileMode.Open);
It throw an error: The process cannot access the file '...' because it is being used by another process.
But why, if it is opened for read only (?). If not, how to open file as read only?
You need to specify that you're opening it read only and that you're sharing it.
var fs1 = new FileStream("test.mkv", FileMode.Open, FileAccess.Read, FileShare.Read);
var fs2 = new FileStream("test.mkv", FileMode.Open, FileAccess.Read, FileShare.Read);
I am working with IsolatedStorage in Windows Phone 7.5. I am trying to read some text from a file. But the debugger says the operation is not permitted on IsolatedStorageFileStream. Why?
//Read the file from the specified location.
fileReader = new StreamReader(new IsolatedStorageFileStream("info.dat", FileMode.Open, fileStorage));
//Read the contents of the file (the only line we created).
string textFile = fileReader.ReadLine();
//Write the contents of the file to the MEssageBlock on the page.
MessageBox.Show(textFile);
fileReader.Close();
UPD my new code
object _syncObject = new object();
lock (_syncObject)
{
using (var fileStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
using (FileStream stream = new FileStream("/info.dat", FileMode.Open, FileAccess.Read, FileShare.Read))
{
using (var reader = new StreamReader(stream))
{
string textFile = reader.ReadLine();
MessageBox.Show(textFile);
}
}
}
}
}
Try this, it works for me: Hope it works for you too
String sb;
using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
if (myIsolatedStorage.FileExists(fileName))
{
StreamReader reader = new StreamReader(new IsolatedStorageFileStream(fileName, FileMode.Open, myIsolatedStorage));
sb = reader.ReadToEnd();
reader.Close();
}
if(!String.IsNullOrEmpty(sb))
{
MessageBox.Show(sb);
}
}
If this doesn't work, then maybe your file doesn't exist.
Normally when I've used isolated storage, I've done something like:
using (var stream = fileStorage.OpenFile("info.dat", FileMode.Open))
{
using (var reader = new StreamReader(stream))
{
...
}
}
... rather than calling the constructor directly on IsolatedStorageFileStream. I can't say for sure whether that'll sort it out, but it's worth a try...
Just a guess:
WP emulator will reset all Isolatd Storage contents when it's closed
if you used FileMode.Open with a path to a non existing file you'll get Operation not permited exception.
You can use fileStorage.FileExists() to check if the file is there or use FileMode.OpenOrCreate.
I have posted a question previous regarding editing my xml document via c#
C# write to XML error
However im now having trouble with it again. Im using the exact code that worked then but getting problems again!
When I first click the button it seems to work however when I click it again I get the error
Data at the root level is invalid. Line 83, position 10
When you then open the XML document for some reason the characters "" get added to the start of the xml document so I get
"<?xml version="1.0" encoding="UTF-8"?>"
I dont understand why and its really driving me insane. I'm sure it was working before.
My code:
path = test.xml
using (FileStream READER = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
System.Xml.XmlDocument Temp = new System.Xml.XmlDocument();
Temp.Load(READER);
using (FileStream WRITER = new FileStream(path, FileMode.Open, FileAccess.Write, FileShare.ReadWrite))
{
Temp.Save(WRITER);
}
}
UPDATE #2:
I compiled your sample as is and it worked perfectly for me. I tested it with a file created straight from code and also with a xaml file created in Visual Studio. So it seems the file you're working with is corrupted or have an encoding problem.
As far as I know you can't do anything about corrupted file, but as for encoding you can specify it when reading by using a StreamReader object. You just pass a desired encoding and your reader stream to StreamReader's constructor. Also it has an option to detect the encoding from byte order marks.
using (TextReader txtreader = new StreamReader(new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite), Encoding.GetEncoding(1251 /*desired codepage here*/)))
{
document.Load(txtreader);
}
or
using (TextReader txtreader = new StreamReader(new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite), true /*tries to detect the encoding*/))
{
document.Load(txtreader);
}
Of course, you should save the file using the same encoding or you'll have problems next time you run your loading code.
Also I'm attaching a code which creates a file if it doesn't exist or just modifies it if it already exists.
class Program
{
static readonly string path = #"C:\Users\Dmitry\Documents\test_3.xml";
static void Main(string[] args)
{
for (int i = 0; i < 10; i++)
test(path);
}
static void test(string path)
{
XmlDocument document = new XmlDocument();
if (File.Exists(path))
{
using (Stream readStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
document.Load(readStream);
}
}
else
{
document.AppendChild(document.CreateXmlDeclaration("1.0", "UTF-8", String.Empty));
document.AppendChild(document.CreateElement("Test"));
}
document.DocumentElement.AppendChild(document.CreateElement("Node"));
using (FileStream WRITER = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
{
document.Save(WRITER);
}
}
}
I hope it helps you.
I have a windows service writes its log in a text file in a simple format.
Now, I'm going to create a small application to read the service's log and shows both the existing log and the added one as live view.
The problem is that the service locks the text file for adding the new lines and at the same time the viewer application locks the file for reading.
The Service Code:
void WriteInLog(string logFilePath, data)
{
File.AppendAllText(logFilePath,
string.Format("{0} : {1}\r\n", DateTime.Now, data));
}
The viewer Code:
int index = 0;
private void Form1_Load(object sender, EventArgs e)
{
try
{
using (StreamReader sr = new StreamReader(logFilePath))
{
while (sr.Peek() >= 0) // reading the old data
{
AddLineToGrid(sr.ReadLine());
index++;
}
sr.Close();
}
timer1.Start();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void timer1_Tick(object sender, EventArgs e)
{
using (StreamReader sr = new StreamReader(logFilePath))
{
// skipping the old data, it has read in the Form1_Load event handler
for (int i = 0; i < index ; i++)
sr.ReadLine();
while (sr.Peek() >= 0) // reading the live data if exists
{
string str = sr.ReadLine();
if (str != null)
{
AddLineToGrid(str);
index++;
}
}
sr.Close();
}
}
Is there any problem in my code in reading and writing way?
How to solve the problem?
You need to make sure that both the service and the reader open the log file non-exclusively. Try this:
For the service - the writer in your example - use a FileStream instance created as follows:
var outStream = new FileStream(logfileName, FileMode.Open,
FileAccess.Write, FileShare.ReadWrite);
For the reader use the same but change the file access:
var inStream = new FileStream(logfileName, FileMode.Open,
FileAccess.Read, FileShare.ReadWrite);
Also, since FileStream implements IDisposable make sure that in both cases you consider using a using statement, for example for the writer:
using(var outStream = ...)
{
// using outStream here
...
}
Good luck!
Explicit set up the sharing mode while reading the text file.
using (FileStream fs = new FileStream(logFilePath,
FileMode.Open,
FileAccess.Read,
FileShare.ReadWrite))
{
using (StreamReader sr = new StreamReader(fs))
{
while (sr.Peek() >= 0) // reading the old data
{
AddLineToGrid(sr.ReadLine());
index++;
}
}
}
new StreamReader(File.Open(logFilePath,
FileMode.Open,
FileAccess.Read,
FileShare.ReadWrite))
-> this doesn't lock the file.
The problem is when you are writing to the log you are exclusively locking the file down so your StreamReader won't be allowed to open it at all.
You need to try open the file in readonly mode.
using (FileStream fs = new FileStream("myLogFile.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
using (StreamReader sr = new StreamReader(fs))
{
while (!fs.EndOfStream)
{
string line = fs.ReadLine();
// Your code here
}
}
}
I remember doing the same thing a couple of years ago. After some google queries i found this:
FileStream fs = new FileStream(#”c:\test.txt”,
FileMode.Open,
FileAccess.Read,
FileShare.ReadWrite);
i.e. use the FileShare.ReadWrite attribute on FileStream().
(found on Balaji Ramesh's blog)
Have you tried copying the file, then reading it?
Just update the copy whenever big changes are made.
This method will help you to fastest read a text file and without locking it.
private string ReadFileAndFetchStringInSingleLine(string file)
{
StringBuilder sb;
try
{
sb = new StringBuilder();
using (FileStream fs = File.Open(file, FileMode.Open))
{
using (BufferedStream bs = new BufferedStream(fs))
{
using (StreamReader sr = new StreamReader(bs))
{
string str;
while ((str = sr.ReadLine()) != null)
{
sb.Append(str);
}
}
}
}
return sb.ToString();
}
catch (Exception ex)
{
return "";
}
}
Hope this method will help you.