Having issues setting up a simple filestream - c#

I am writing an application that allows the user to import a picture from the computer and view it in my application. The user also has an import button under the picture and he/she can select the picture's destination in the computer.
My problem is that I get following exception:
System.IO.IOException: 'The process cannot access the file 'D:\Workspaces_Foo\Foo\Theme\MyPic.png' because it is being used by another process.'
when I debug it I find the line where it's breaking. It is in:
string image = Constants.ImageName;
if (image != "NONE")
{
using (var stream = File.OpenRead(SourceDir + ImageName))
{
Directory.CreateDirectory(Path.GetDirectoryName(DestinationDir + "\\" + image));
File.Copy(SourceDir + "\\" + image, DestinationDir + "\\" + image, true); //breaks here...
}
}
I assumed that by using a filestream it would've allowed me to continue with my picture transfer. Can anyone tell me why I am getting this error?

You are opening a stream for the file. This opens the file and marks it as in use.
Then you use File.Copy to copy it, but the Operating system says the file is in use (it isn't clever enough to notice that it is in use by your own process!)
Forget the stream, try this instead.
string image = Constants.ImageName;
if (image != "NONE")
{
Directory.CreateDirectory(Path.GetDirectoryName(DestinationDir + "\\" + image));
File.Copy(SourceDir + "\\" + image, DestinationDir + "\\" + image, true);
}

Related

IOException thrown from Image class or byte array

I'm extracting a ZIP file. This ZIP contains image files and an Excel file with a product list. When articles of different sizes are listed the article refers to the same image. I copy the image file to a local folder and write the (compressed) binary data to SQL server database.
So when it gets to the point where a JPG file shall be processed a second time, I get this exception, although I dispose the image object.
Worksheet ws;
string root = "C:\\images\\";
string file;
string importFolder = "C:\\import\\;
Dictionary <string, object> ins;
Image im;
Image th;
//Worksheet has been opened before
//ZIP has been extracted before to C:\import\
for (i = 2; i <= ws.Dimension.End.Row; i++) {
ins = new Dictionary<string, object>(); //Dictionary to write data to database
file = ws.Cells[i, 4].Text;
System.IO.File.Copy(importFolder + "\\" + file, root + "\\" + file, true); // <-- Here the exception is thrown in the second iteration
im = Image.FromFile(root + "\\" + file);
im = im.GetBetterThumbnail(1024);
byte[] im_data = im.GetJpgByteArray(85);
ins.Add("url", "www.test.de/images/" + file);
ins.Add("image_data", im_data);
ins.Add("image_size", im_data.Length);
//image will be written to database
im.Dispose();
im = null;
im_data = null;
//With these initializations there shouldn't be thrown an exception
} // end for
What am I missing? With resetting the Image object and byte array, there shouldn't be another reference to the image file.
I had a look on this
IOException: The process cannot access the file 'file path' because it is being used by another process
but I couldn't figure out, how to adept to my topic.
Yes, I could store all file names just to copy them once, but I think that's the lazy way.
Kind regards
You assign a value to the variable im two times.
One time you use im = Image.FromFile(root + "\\" + file) and the other time you use im = im.GetBetterThumbnail(1024). Could it be that this opens two handles that need to be closed?
Besides, it's better to use the using statement. Then you don't have to take care of the disposing by yourself.
For example like this:
for (i = 2; i <= ws.Dimension.End.Row; i++)
{
ins = new Dictionary<string, object>(); //Dictionary to write data to database
file = ws.Cells[i, 4].Text;
System.IO.File.Copy(importFolder + "\\" + file, root + "\\" + file, true);
using (im = Image.FromFile(root + "\\" + file))
{
// I guess that this method creates its own handle
// and therefore also needs to be disposed.
using (thumbnail = im.GetBetterThumbnail(1024))
{
byte[] im_data = thumbnail.GetJpgByteArray(85);
ins.Add("url", "www.test.de/images/" + file);
ins.Add("image_data", im_data);
ins.Add("image_size", im_data.Length);
//image will be written to database
}
}
} // end for
I got the issue solved by using a stream. The memory management works really better now.
New code:
//im = Image.FromFile(root + "\\" + file);
im = Image.FromStream(File.Open(root + "\\" + file, FileMode.Open));
So could it be that this is another 'Microsoft feature'?

Cant Update Image in a quick succession

I'm doing a simple code to update profile pics, by saving uploaded file into a folder and processing its required versions using Bitmap.
Issue is that i cant change image in quick succession, After changing once, it shows file is being used by another process. It works after logging out and logging in again.
fuPic.SaveAs(Server.MapPath("/assets/user_images_raw/" + Session["userid"].ToString() + ".jpg"));
flag = "yes";
Bitmap map = new Bitmap(System.Drawing.Image.FromFile(Server.MapPath("/assets/user_images_raw/" + Session["userid"].ToString() + ".jpg")), new Size(60, 60));
map.Save(Server.MapPath("/assets/user_images/" + Session["userid"].ToString() + ".jpg"), System.Drawing.Imaging.ImageFormat.Jpeg);
map.Dispose();
Bitmap map_2 = new Bitmap(System.Drawing.Image.FromFile(Server.MapPath("/assets/user_images_raw/" + Session["userid"].ToString() + ".jpg")), new Size(125, 125));
map_2.Save(Server.MapPath("/assets/user_thumbnails/" + Session["userid"].ToString() + ".jpg"), System.Drawing.Imaging.ImageFormat.Jpeg);
map_2.Dispose();
What am i missing ?
Edit: I'm not seeing any issue at localhost. Its just after hosting on IIS.

How to rewrite txt file-why my code doesn't work

I want rewrite my txt file(I need delete lines). I use this code:
string cesta3 = cesta + "database.txt";
string file = new StreamReader(cesta3).ReadToEnd();
var linesToKeep = File.ReadLines(cesta3)
.Where(l => l != "Meno: " + textBox1.Text + " PN " + textBox2.Text);
But I don't know how to save my file with that same name.I try this:
File.WriteAllLines(cesta3, linesToKeep); // <== exception
var tempFile = Path.GetTempFileName();
File.Move(tempFile + ".txt", cesta3);
But it throws exception:
Additional information: Access to the path "'C:\Users\Lenovo\documents\visual studio 2015\Projects\attendancer\attendancer\bin\Debug\database.txt‌​' is denied."
How can I do ?
This line of code locks the file and prevent it from moving: string file = new StreamReader(cesta3).ReadToEnd();.
Fix:
you can properly close StreamReader after reading file text from it with using
alternatively since there is nothing in the sample using that StreamReader or result of ReadToEnd (file variable) you can simply remove that line.
Side note: File.Move will throw more exceptions after you are done with the first one as source file is unlikely to exist - I'm not sure what you were trying to do with that call.

Ensure directory exists or create if needed before saving a file

I have a file name that I am generating from data that is coming from a database. I need to save the file to a folder location that is coming from a database query. How do I ensure the path exists so that when I save my file it will not throw an exception about a missing directory? My file saving code is listed below. When I call saveTemp.Save I am getting an exception because the directory does not exist.
Image<Bgr, Byte> newImage = sourceImage.WarpPerspective(mywarpmat, 355, 288, Emgu.CV.CvEnum.INTER.CV_INTER_LINEAR, Emgu.CV.CvEnum.WARP.CV_WARP_FILL_OUTLIERS, new Bgr(0, 0, 0));
Image<Bgr, Byte> savetemp = newImage.Copy();
savetemp.ROI = new Rectangle(lokasiX, lokasiY, templatewidth, templateheight);
savetemp.Save(#"D:\Dokumen\Alfon\TA Alfon\CobaFitur\Template\Kotak\" + simpantmp["namakamera"].ToString() + "Template_" + DateTime.Now.ToString("yyyyMMdd_hhmmss") + cnt + ".jpg");
You need to ensure the directory exists before you can save a file to it. You can do this using the Directory.CreateDirectory method. I would also modify your code to use the Path.Combine method to build your path.
var fileName = "Template_" + DateTime.Now.ToString("yyyyMMdd_hhmmss") + cnt + ".jpg");
var filePath = Path.Combine(#"D:\Dokumen\Alfon\TA Alfon\CobaFitur\Template\Kotak", simpantmp["namakamera"].ToString());
Directory.CreateDirectory(filePath);
saveTemp.Save(Path.Combine(filePath, fileName));

Error occured While writing to the file

I am creating the File. At first time after creating the file, I'm immediately going to open a file but it shows error:
"The process cannot access the file 'C:\ProjectWork\Websites3\LogsArpita\ErrorLogs\Error_Log_24_4_2014.txt' because it is being used by another process."
What does it means? How can I open a file immediately for further write operation. I have tried with following code.
FileName = String.Concat("Error_Log_", DateTimeStamp + ext);
if (!File.Exists(Server.MapPath("~/LogsArpita/ErrorLogs/" + FileName)))
{
File.Create(Server.MapPath("~/LogsArpita/ErrorLogs/" + FileName));
}
//Error occured here, below line
StreamWriter tw = new StreamWriter(Server.MapPath("~/LogsArpita/ErrorLogs/" + FileName), true);
tw.WriteLine("");
tw.Write("\"" + DateTimeStampLog + "\",");
tw.Write("\"Assignments.aspx\",");
tw.Write("\"" + ErrorMessage + "\",");
tw.Write("\"" + TransactVariable + "\"");
tw.Close();
You do not need the File.Create because the StreamWriter constructor will create the file if it does not exist
This is what the msdn documentation says:
Initializes a new instance of the StreamWriter class for the specified file by using the default encoding and buffer size. If the file exists, it can be either overwritten or appended to. If the file does not exist, this constructor creates a new file.

Categories