I'm running into an error that I can't catch and it should not be there.
if (System.IO.File.Exists (PathToMyFile))
{
try{
FileStream fs = new FileStream(PathToMyFile, FileMode.Open, FileAccess.Read);
BinaryReader br = new BinaryReader(fs);
Byte[] bytes = br.ReadBytes((Int32)fs.Length);
br.Close();
fs.Close();
myFile =Convert.ToBase64String (bytes) ;
}
catch{}
}
For some reason , sometimes I get a exception error that the file does not exist when It most definitely is there. The very first "If statement" even says it is there yet when trying to open the file I sometimes get a massive app crash that the catch does not "catch" .
Like I said, it's a random error, most of the time the code is perfect but the odd occasion seems to throw an error that the app stops working .
First thing is to make sure you close the file\stream
So you can call fs.Close() or using
if (File.Exists(pathToMyFile))
{
try
{
using (var fs = new FileStream(pathToMyFile, FileMode.Open, FileAccess.Read))
{
BinaryReader br = new BinaryReader(fs);
Byte[] bytes = br.ReadBytes((Int32) fs.Length);
br.Close();
fs.Close();
myFile = Convert.ToBase64String(bytes);
}
}
catch
{
// Log exception
}
}
Second, if you need to read the file as string, simply use
if (File.Exists(pathToMyFile))
{
try
{
myFile = File.ReadAllText(pathToMyFile);
}
catch
{
// Log exception
}
}
Related
I have a certain requirement. When current line of code throwing exception, I want to move to next line
FileStream fs = new FileStream("D:/temp/product.xml", FileMode.Open, FileAccess.Read);
sometimes D:/ drive don't have xml file, it throwing FileNotFoundException and jumping control out of scope. but then in next line I want to check another location
FileStream fs = new FileStream("//letp.rf.servername.com/products/product.xml", FileMode.Open, FileAccess.Read);
How can I fix this issue?
Use defensive check and check whether the file exists first using File.Exists(String) method before actually accessing it. Again, wherever possible we should use Defensive Check rather Exception Handling since exception handling is expensive operation. How expensive are exceptions in C#?
Finally, you can wrap this entirely in a try .. catch block to make sure catching any other exception down the line and logging them.
try
{
if (File.Exists("D:/temp/product.xml"))
{
FileStream fs = new FileStream("D:/temp/product.xml", FileMode.Open, FileAccess.Read);
}
else
{
// check another location
}
}
catch (Exception ex)
{
// perform logging
}
All you need to do is wrap your code in a try-catch block, for example:
FileStream fs = null;
try
{
fs = new FileStream("D:/temp/product.xml", FileMode.Open, FileAccess.Read);
}
catch (FileNotFoundException e)
{
// Retry another file,
}
If the retry can also fail, you'll have to wrap it also.
(Btw, Rahul's answer is better and easier)
To use this in a loop:
FileSystem fs = null;
foreach (var file in files) // files contains the file paths
{
// Solution #1
try
{
fs = new FileStream(file, FileMode.Open, FileAccess.Read);
break;
}
catch (FileNotFoundException e) { }
// Or you can use File.Exists as per Rahul's answer
// Solution #2
if (File.Exists(file))
{
fs = new FileStream(file, FileMode.Open, FileAccess.Read);
break;
}
}
Don't use exceptions to check whether a file exists, but check whether the file exists via File.Exists:
string defaultPath = "D:/temp/product.xml";
string alternativePath = "//letp.rf.servername.com/products/product.xml";
string path = File.Exists(defaultPath) ? defaultPath : alternativePath;
FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read);
If you want to check for another path if the second one is not found, you might want to use the following approach with an array of paths. With that, you are totally flexible how many paths you want to check.
string[] paths = new string[] { #"C:\first\path\product.xml", #"C:\second\path\product.xml", #"C:\third\path\product.xml"};
string path = paths.FirstOrDefault(p => File.Exists(p));
if(path == null)
{
Console.WriteLine("None of the files exists!");
}
else
{
FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read);
}
Just use try and catch and loop:
foreach (var file in files)
{
try
{
FileStream fs = new FileStream(file , FileMode.Open, FileAccess.Read);
}
catch(Exception ex)
{}
}
I'm making a program that reads file after I select a file and write file in hex. Problem is BinaryReader still open after .Close(); and it gives me System.IO.IOException: the process cannot access the file error when i try to write a file. I'm missing something?
Here is the code that read the file after i select file from dialogbox..
BinaryReader br = new BinaryReader(File.OpenRead(sfile.FileName));
string pted = null;
br.BaseStream.Position = 0x12;
pted += br.ReadByte().ToString("X2");
if (pted == "01")
{
}
else
{
}
br.Close();
And here is the code that writes file when you click a button
Stream st = File.Open(pathTextBox.Text, FileMode.Open);
st.Seek(0x12, SeekOrigin.Begin);
st.WriteByte(0x00);
st.Close();
add br.close in a try catch statement and dispose the binary reader after closing
for example:
try{
br.close();
br.dispose();
}
catch(Exception exp)
{
//Assuming you have included using 'namespace System.Diagnostics'
Debug.WriteLine(exp.ToString());
}
You can read more on BinaryReader here
First check if file is here, then try it with using directive.
As mentioned by Orgen:
if(File.Exists(#pathTextBox.Text)
{
using(Stream st = File.Open(pathTextBox.Text, FileMode.Open))
{
st.Seek(0x12, SeekOrigin.Begin);
st.WriteByte(0x00);
}
}
the using() will take care of the disposable.
Title sais it all really.
private bool addToBinary(byte[] msg, string filepath)
{
bool succ = false;
do
{
try
{
using (Stream fileStream = new FileStream(filepath, FileMode.Append, FileAccess.Write, FileShare.None))
{
using (BinaryWriter bw = new BinaryWriter(fileStream))
{
bw.Write(msg);
bw.Flush();
fileStream.Flush();
bw.Close();
}
}
succ = true;
}
catch (IOException ex) { Console.WriteLine("Write Exception (addToBinary) : " + ex.Message); }
catch (Exception ex) { Console.WriteLine("Some Exception occured (addToBinary) : " + ex.Message); return false; }
} while (!succ);
return true;
}
(bw.close also closes the underlying stream)
Using this in any loop causes an output such as;
A first chance exception of type 'System.IO.IOException' occurred in mscorlib.dll
Write Exception (addToBinary) : The process cannot access the file 'C:\test\test.png' because it is being used by another process.
The bigger the file gets, the more of these errors pop up. It does get through eventually but it significantly reduces file writing speed. It's the Stream fileStream = bit that causes the exception.
What did I do wrong?
Example usage;
do
{
serverStream = clientSocket.GetStream();
bytesRead = serverStream.Read(inStream, 0, buffSize); //How many bytes did we just read from the stream?
recstrbytes = new byte[bytesRead]; //Final byte array
Array.Copy(inStream, recstrbytes, bytesRead); //Copy from inStream to the final byte array
addToBinary(recstrbytes, #"C:\test\test.png"); //Append final byte array to binary
received += recstrbytes.Length; //Increment bytes received
}while (received < filesize);
You need to first check if you can access the file before using Stream to read the file.
You can have a look at this link :
Best way to handle errors when opening file
Have a look at the answers
Although I posted my answer
https://stackoverflow.com/a/9503939/448407 but you can look at the post marked as answer.
Only read the file contents if you can access the file and I think it will then work.
Some good advice style wise for those stacked using statements. When you start using more than one it is often neater to use the following style:
using (Stream fileStream = new FileStream(filepath, FileMode.Append, FileAccess.Write, FileShare.None))
using (BinaryWriter bw = new BinaryWriter(fileStream))
{
bw.Write(msg);
bw.Flush();
fileStream.Flush();
bw.Close();
}
I'm afraid I can't solve your question though, but I'm not sure how much of a good an idea it is to repeatedly try and write to the stream if it isn't successful the first time round.
I'm working with a file stream in C#. It's a storage cache, so if something goes bad writing the file (corrupted data, ...), I need to delete the file and rethrow the exception to report the problem. I'm thinking on how to implement it in the best way. My first attempt was:
Stream fileStream = null;
try
{
fileStream = new FileStream(GetStorageFile(),
FileMode.Create, FileAccess.Write, FileShare.Write);
//write the file ...
}
catch (Exception ex)
{
//Close the stream first
if (fileStream != null)
{
fileStream.Close();
}
//Delete the file
File.Delete(GetStorageFile());
//Re-throw exception
throw;
}
finally
{
//Close stream for the normal case
if (fileStream != null)
{
fileStream.Close();
}
}
As you will see, if something goes bad writing the file, the fileStream will be closed twice. I know that it works, but I don't think that is the best implementation.
I think that I could remove the finally block, and close the stream in the try block, but I have posted this here because you guys are experts and I want to hear the voice of an expert.
If you put the fileStream in a using block you don't need to worry about closing it, and then just leave the cleaning up (deleting of the file in the catch block.
try
{
using (FileStream fileStream = new FileStream(GetStorageFile(),
FileMode.Create, FileAccess.Write, FileShare.Write))
{
//write the file ...
}
}
catch (Exception ex)
{
File.Delete(GetStorageFile());
//Re-throw exception
throw;
}
I believe what you want is this:
var fs = new FileStream(result.FilePath, FileMode.Open, FileAccess.Read, FileShare.None, 4096, FileOptions.DeleteOnClose);
I've used it with ASP.Net to have the web server return a result to a temp file that's on disk, but to make sure it's cleaned up after the web server finishes serving it to the client.
public static IActionResult TempFile(string tempPath, string mimeType, string fileDownloadName)
{
var fs = new FileStream(tempPath, FileMode.Open, FileAccess.Read, FileShare.None, 4096, FileOptions.DeleteOnClose);
var actionResult = new FileStreamResult(fileStream: fs, contentType: mimeType)
{
FileDownloadName = fileDownloadName
};
return actionResult;
}
I have a problem. When I run my program, it comes up with an error, specifically the CS1023 error. I guess it's because I have a declaration inside a statement, but I don't know how else to write the code. Sometimes C# annoys me, because in C++ I could get away with similar things... anyway, here's the code. I would appreciate it if somebody could explain it to me.
Error Message Link
void BtnTotalSeasonsClick(object sender, EventArgs e)
{
using (var stream = new FileStream(drvFile, FileMode.Open, FileAccess.ReadWrite))
Byte[] bytes = System.Text.ASCIIEncoding.GetBytes(txtTotalSeasons.Text);
{
stream.Position = 4;
Stream.WriteByte(0xCD);
}
}
Fixed Code with CS0120 error.
{
using (var stream = new FileStream(drvFile, FileMode.Open, FileAccess.ReadWrite))
{
Byte[] bytes = System.Text.ASCIIEncoding.GetBytes(txtTotalSeasons.Text);
stream.Position = 4;
Stream.WriteByte(0xCD);
}
}
There's nothing apparently wrong with the code you pasted in. Perhaps the error is somewhere else above this, and the compiler is getting confused?
Ah, I see you've changed the code.
The problem here is you are declaring the Byte[] array outside the intended using block. Since the scope of the declaration as is is only one line, this constitutes a logic error, and the compiler catches it with a compile-time error.
The compiler is interpreting your code like this:
using (var stream = new FileStream(drvFile, FileMode.Open, FileAccess.ReadWrite))
{
Byte[] bytes = System.Text.ASCIIEncoding.GetBytes(txtTotalSeasons.Text);
}
{
stream.Position = 4;
stream.WriteByte(0xCD);
}
To fix it, move the Byte[] inside the braces, or outside the using block:
using (var stream = new FileStream(drvFile, FileMode.Open, FileAccess.ReadWrite))
{
Byte[] bytes = System.Text.ASCIIEncoding.GetBytes(txtTotalSeasons.Text);
stream.Position = 4;
stream.WriteByte(0xCD);
}
-or-
Byte[] bytes = System.Text.ASCIIEncoding.GetBytes(txtTotalSeasons.Text);
using (var stream = new FileStream(drvFile, FileMode.Open, FileAccess.ReadWrite))
{
stream.Position = 4;
stream.WriteByte(0xCD);
}
Personally, I like being annoyed by the compiler here, since it saves me from a run-time error.