So I'm getting exception "Process cannot access file because its used by another process.
The exception will show when i call this particular method:
public async static Task<bool> DownloadFileFromFTP(string PathToFile, string AppName)
{
return await Task.Run(() => {
if (File.Exists("settings.xml"))
{
XmlSerializer xs = new XmlSerializer(typeof(Information));
FileStream read = new FileStream("settings.xml", FileMode.Open, FileAccess.Read, FileShare.Read);
Information info = (Information)xs.Deserialize(read);
try
{
FtpClient client = new FtpClient(info.HDSynologyIP);
string a = info.FtpPassword;
string FTPPassword = EncryDecryptor.Decrypt(a);
client.Credentials = new NetworkCredential(info.FtpUsername, FTPPassword);
client.Connect();
bool finish = client.DownloadFile(#info.Downloads + "\\" + AppName, PathToFile, FtpLocalExists.Overwrite, FluentFTP.FtpVerify.Retry);
if (finish == true)
{
client.Disconnect();
read.Close();
return true;
}
else
{
client.Disconnect();
read.Close();
return false;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
read.Close();
}
read.Close();
}
else
{
MessageBox.Show("Missing settings.xml file");
return false;
}
return false;
});
}
And call it in another class like this:
await General_Functions.DownloadFileFromFTP("Ultra_Script/Basic_SW/Adobe_Reader.exe", "Adobe_Reader.exe");
It wasn't asynchronous before but i had to remake it into asynchronous method. But i think I'm closing reader and client correctly. Can it be problem of async method? Because i don't had this problem before i made it asynchronous.
Can someone explain what I'm doing wrong?
Note, I am using FluentFTP from https://github.com/robinrodricks/FluentFTP .
use using to terminate the file reader process
using(FileStream read = new FileStream("settings.xml", FileMode.Open, FileAccess.Read, FileShare.Read))
{
// your code here.....
}
Related
Assuming I have a multi thread ForEach I would like that every cycle have the Console.WriteLine() converted into a file, the example I have found for mono thread is something like:
FileStream ostrm;
StreamWriter writer;
TextWriter oldOut = Console.Out;
try
{
ostrm = new FileStream("C:\\Users\\Public\\Documents/Redirect.txt", FileMode.OpenOrCreate, FileAccess.Write);
writer = new StreamWriter(ostrm);
}
catch (Exception e)
{
Console.WriteLine("Cannot open Redirect.txt for writing");
Console.WriteLine(e.Message);
return;
}
Console.SetOut(writer);
Now for multi thread I have try something like:
IList<String> testCaseList = ExcelDataAccess.GetTestCases();
Parallel.ForEach(testCaseList, new ParallelOptions { MaxDegreeOfParallelism = 1 }, currentTestCase =>`
{
FileStream ostrm;
StreamWriter writer;
TextWriter oldOut = Console.Out;
try
{
ostrm = new FileStream("C:\\Users\\Public\\Documents/Redirect" + currentTestCase +".txt", FileMode.OpenOrCreate, FileAccess.Write);
writer = new StreamWriter(ostrm);
}
catch (Exception e)
{
Console.WriteLine("Cannot open Redirect.txt for writing");
Console.WriteLine(e.Message);
return;
}
Console.SetOut(writer);
Console.WriteLine("Running test: " + currentTestCase);
//Do some other stuff and some Console.WriteLine();
}
But in this way inside every file what is written is not what expected and multi thread looks not handled correctly. How to solve this?
I get a "file in use by another process exception" when creating a email and wants to add this file as attachment.
When i try to copy the same file to an other directory there is no problem. (state of the file is still the same)
does anybody knows whats happening here? and how i can solve this?
here is the code:
public Boolean AddAttachment(string filePath, string newName = "")
{
try
{
MimeData mime = _message.AddAttachment(filePath);
if (!string.IsNullOrEmpty(newName))
{
mime.FileName = newName;
}
return true;
}
catch (Exception err)
{
if (! AddAttachmentIfInUse(filePath, newName))
{
AddErrorInfo(err.Message, "AddAttachment", err.Source);
return false;
}
else
{
return true;
}
}
}
private Boolean AddAttachmentIfInUse(string filePath, string newName = "")
{
byte[] data;
string contentType = "";
string fileName = Path.GetFileName(filePath);
try
{
using (FileStream stream = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
{
data = new byte[stream.Length];
stream.Read(data, 0, (int)stream.Length);
}
// data = File.ReadAllBytes(filePath);
MimeData mime = new MimeFactory().CreateMimeData();
mime.Data = data;
mime.ContentType = ContentType.Parse(contentType);
if (!string.IsNullOrEmpty(newName))
{
mime.FileName = newName;
}
else{
mime.FileName = fileName;
}
return true;
}
catch (Exception err)
{
AddErrorInfo(err.Message, "AddAttachmentIfInUse", err.Source);
return false;
}
}
thanks
The 1st function gets the the error in _message.AddAttachment(..) ...
I had to change the 2nd function: do not use File.Open() but use FileStream() and now it's working well.
using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)){
data = new byte[fs.Length];
fs.Read(data, 0, (int)fs.Length);
}
I have a problem on a few systems that when we are trying to load the RichTextBox the program becomes unresponsive, we cannot do anything and will have to kill it via Taskmanager.
its working on most systems but a few systems located in a different country there seems to be problem.
we have tried something as simple as :
private void testing4()
{
richTextBox1.LoadFile(#"C:\testing.logs", RichTextBoxStreamType.PlainText);
}
If we decide to use a normal TextBox it appears to be working using .net 4.5, but it still becomes unresponsive. Any ideas?
This may help you:
foreach(var line in File.ReadLines(#"C:\testing.logs"))
{
richTextBox1.AppendText(line+Environment.NewLine);
}
Since you are using framework 4.5, you can do it async, as in MSDN example:
public async void ReadFile()
{
string filePath = #"C:\testing.logs";
if (File.Exists(filePath) == false)
{
Debug.WriteLine("file not found: " + filePath);
}
else
{
try
{
string text = await ReadTextAsync(filePath);
richTextBox1.AppendText(text);
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
}
private async Task<string> ReadTextAsync(string filePath)
{
using (FileStream sourceStream = new FileStream(filePath,
FileMode.Open, FileAccess.Read, FileShare.Read,
bufferSize: 4096, useAsync: true))
{
StringBuilder sb = new StringBuilder();
byte[] buffer = new byte[0x1000];
int numRead;
while ((numRead = await sourceStream.ReadAsync(buffer, 0, buffer.Length)) != 0)
{
string text = Encoding.Unicode.GetString(buffer, 0, numRead);
sb.Append(text);
}
return sb.ToString();
}
}
Source: Using Async for File Access
I don't see what's the matter here:
Constructor:
IsolatedStorageFile isf;
public FileManagement()
{
isf = IsolatedStorageFile.GetUserStoreForApplication();
}
when I save files:
public bool saveCredentials(String username, String userpass)
{
bool res = false;
StreamWriter writeFile = new StreamWriter(new IsolatedStorageFileStream("usercred.custom",
FileMode.Create, FileAccess.Write, isf));
writeFile.WriteLine(username);
writeFile.WriteLine(userpass);
res = true;
return res;
}
and when I try to read them:
public String readUsername()
{
String username = "";
IsolatedStorageFileStream fileStream = isf.OpenFile("usercred.custom", FileMode.Open, FileAccess.Read);
StreamReader reader = new StreamReader(fileStream);
username = reader.ReadLine();
return username;
}
Reading returns null.
I try to save a file and write something into it, but it somehow doesn't work.
You have to close your streams. Please add reader.Close(), writefile.Close() and fileStream.Close() before return and try again.
public byte[] GetFile(string filename)
{
FileStream aStream = File.Open(filename, FileMode.Open, FileAccess.Read);
BinaryReader binReader = new BinaryReader(aStream);
binReader.BaseStream.Position = 0;
byte[] binFile = binReader.ReadBytes(Convert.ToInt32(binReader.BaseStream.Length));
binReader.Close();
return binFile;
}
I run this method for a number of filepaths, problem is whenever a file cannot be accessed with File.Open (because it is used by another process) I get:
'aStream.Position' threw an exception of type 'System.ObjectDisposedException'
on the following line:
binReader.BaseStream.Position = 0;
And seldom I get
{System.IO.IOException: The process can not access the file '\folder\file.txt' because it is being used by another process.}
This is the exception I want. So why is the object disposed most of the times?
Note: I first had the FileStream line in a using statement but removed it because I thought that might have disposed the object. But the problem remains.
Edit: Using Compact Framework, which doesn't have ReadAllBytes.
Maybe that part of the time your FileStream is throwing the IOException whenever your file is in use, and at other times, perhaps, you are getting the ObjectDisposedException because your array is not initialized.
Obviously, I can not test this theory.
See if you can copy-n-paste this one with good results:
public byte[] GetFile(string filename)
{
byte[] binFile = null;
try
{
using (var aStream = File.Open(filename, FileMode.Open, FileAccess.Read))
{
BinaryReader binReader = new BinaryReader(aStream);
binFile = new byte[binReader.BaseStream.Length];
binReader.BaseStream.Position = 0; // <= this step should not be necessary
binFile = binReader.ReadBytes(binReader.BaseStream.Length);
binReader.Close();
}
} catch (IOException err) {
// file is being used by another process.
} catch (ObjectDisposedException err) {
// I am guessing you would never see this because your binFile is not disposed
}
return binFile;
}
Be sure to check for null return variables!
EDIT:
I wrote (what I think is) a simpler version. I tested it, and it seems to work OK. I also prefer Read() overload to ReadBytes(), because I know how much data was pulled in.
First, is the test function that calls the method for every image in my Pictures folder:
public void Test() {
DirectoryInfo dir = new DirectoryInfo(Environment.GetFolderPath(Environment.SpecialFolder.Personal));
foreach (var subDir in dir.GetDirectories()) {
if (-1 < subDir.Name.ToLower().IndexOf("pictures")) {
foreach (var file in subDir.GetFiles()) {
byte[] data = GetFile(file.FullName);
if (data != null) {
Console.WriteLine(data.Length);
}
}
}
}
}
public byte[] GetFile(string filename) {
byte[] result = null;
try {
if (File.Exists(filename)) {
int len = 0;
FileInfo file = new FileInfo(filename);
byte[] data = new byte[file.Length];
using (BinaryReader br = new BinaryReader(file.Open(FileMode.Open, FileAccess.Read))) {
len = br.Read(data, 0, data.Length);
br.Close();
}
if (0 < len) {
if (len == data.Length) {
return data;
} else {
// this section of code was never triggered in my tests;
// however, it is good to keep it as a backup.
byte[] dat2 = new byte[len];
Array.Copy(data, dat2, len);
return dat2;
}
}
}
} catch (IOException err) {
// file is being used by another process.
} catch (ObjectDisposedException err) {
// I am guessing you would never see this because your binFile is not disposed
}
return result;
}
I don't see any reason why these would not work - unless you are having an int overflow.
Just use this:
byte[] contents = File.ReadAllBytes(filename);
Why don't you simply use
public byte[] GetFile(string filename)
{
try { return File.ReadAllBytes(filename); }
catch { return null; }
}
Just for fun, you could even define an extension method
public static class Extensions
{
public static byte[] GetFile(this string filename)
{
try { return File.ReadAllBytes(filename); }
catch { return null; }
}
}
so you could do byte[] myfile = filename.GetFile();.
Remember you must check that return is not null before proceed:
if (myfile != null)
{
// Do what you need
}