I am describing my work process bellow:
I get image files from a directory.
Creating a PictureBox array for displaying the images.
Creating a Image array from the files that I got from the directory. I am creating this array for making the image source of PictureBox.
I am copying the files to another directory. By this:
File.Copy(allFiles[i],fullPath+fullName+"-AA"+nameString+ext);
Now I want to delete the files from the directory. For this I am doing this:
File.Delete(allFiles[i]);
But its giving me this error:
The process cannot access the file 'C:\G\a.jpg' because it is being used by another process.
Please tell me how to resolve this? I didn't attach the full code here because it'll be large. Please ask me if you want to see any part of my code.
Chances are you are loading the image directly from the file. For example,
PictureBox[i] = Image.FromFile(allFiles[i]);
If you look up the documentation for the Image.FromFile method, you will find that it actually locks the file until the Image is disposed. (In fact, most other loading methods in the Image class also locks the file until the Image is disposed.)
So to work around this problem, copy the picture file contents to memory and load it from there. For example,
PictureBox[i] = Image.FromStream(new MemoryStream(File.ReadAllBytes(allFiles[i])));
That way, the file itself will remain unlocked and you can freely move/delete it.
Of course it's being used.
Copy the files to another directory first (Step 4),
Delete the old directory
then do the third step (assigning it to a array and loading it to PictureBox) from the newly copied directory.
Alternative:
You must close the stream handler before deleting the files..
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
using (PictureBox[i] = Image.FromStream(fs))
{
...
}
Related
With the following piece of code, i read a file and keep the stream open.
static void Main(string[] args)
{
FileStream fileStream = new FileStream(#"C:\temp\test1.txt", FileMode.Open);
Console.ReadLine();
}
If i now try to rename this file, the message "File in use" is shown.
It looks like the rename of a file should be possible(on os level), even if it is in use: Why does rename a loaded .net assembly work?
Why can't a file be renamed when it is loaded in a stream by .net?
About assemblies, .NET should open the assembly using something like FileShare.ReadWrite so, even if it's loaded into the domain, any other process can write or rename the whole file.
AFAIK, .NET doesn't have a managed FileShare enum value for allowing or disallowing renaming the file share (something like FileShare.Rename), but Win32 should have thus assembly loading would be creating the file stream with a mask like FileShare.ReadWrite | FileShare.Rename (FileShare.Delete includes renaming but also removing the whole file...).
For demonstrating this, I've tried the following code:
FileStream a = File.Open(#"C:\blah.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
a.Dispose();
While the file stream was opened and until it's disposed, I couldn't delete the whole file but I could rename it.
Note that assemblies are loaded into the AppDomain when they're needed, meaning that maybe you can write, delete or rename an assembly because it's not loaded yet.
Try to delete an assembly already loaded into the AppDomain: you can't (I've tried myself just now, the test code runs in a console app and I couldn't remove the executable while running it). Now try to rename it: it works.
Summary
It's all about how a file is opened and which file mask configuration was used when the file stream was opened: this is why your file can't be renamed but you can rename an already loaded assembly.
Modify your code like the next one and you'll be able to rename the whole file (even delete it!):
FileStream fileStream = File.Open(#"C:\temp\test1.txt", FileMode.Open, FileShare.ReadWrite | FileShare.Delete);
Console.ReadLine();
When you create a FileStream you don't load it's data to the memory.
when you are seeking the stream, the file content is still read from the disk - a good thing to do when you need to read big files.
If all you want to do is to load the whole content to memory you can use File.ReadAllBytes.
You can read more about it here: http://msdn.microsoft.com/en-us/library/system.io.file.readallbytes.aspx.
Note: If you want to use a stream and not a byte array, you can use MemoryStream and pass the read file content to it.
I have a c# application which shows images in a form. I'm trying to overwrite these images and regenerate them. I get an exception while I'm trying to delete an existing image (it's a png in this case). I tried disposing the image that the picturebox is using and then setting it to null, but I still get an exception due to a sharing violation. Nevertheless, I can go to explorer and delete the file without any problem.
In trying to figure out what process has this image locked, Process Monitor tells me it's the vhost.exe which is hosting my application.
How can I get around this? Is there some way I can get the host to release the lock on the file so that I can delete/recreate it? Ultimately I have large number of images which are generated as thumbnails which would need updating anytime my database incurs changes which affect the graphics. I'd hate to think I need to call a command shell to do this.
Thanks for any advice.
Gary
You can try loading images using file streams and closing them after reading.
FileStream fileStream = new FileStream("ImageName.jpg", FileMode.Open, FileAccess.Read);
yourPictureBox.Image = Image.FromStream(fileStream);
fileStream.Close();
Or instead of explicitly closing; you can employ using statement;
using(FileStream fileStream = new FileStream("ImageName.jpg", FileMode.Open, FileAccess.Read))
{
yourPictureBox.Image = Image.FromStream(fileStream);
}
I want to view presentation in PowerPoint viewer, ppt file is in a resources. so the problem is that how can i access it and view in PowerPoint viewer.
Here is sample code
Process.Start(#"C:\Program Files\Microsoft Office\Office12\PPTVIEW.exe",**#"e:\presentation.ppt")**;
How can i replace this path by ppt containing in resources?
Actually, what you ask for is a common pattern and there are some related questions and answers here on SO.
Basically what you do in general is the following:
locate the resource in question and open a resource stream to it.
Save the stream to a (temporary) file if your target API cannot deal with streams or byte arrays directly.
Perform whatever operation on the file or directly on the stream/byte array (as I said, if supported).
Eventually remove the temporary file, if any, from step 1.
So, you first extract the PPT file (actually it doesn't really matter that it is a PPT file, could by any file or byte blob for that matter).
string tempFile = Path.GetTempFileName();
using (Stream input = assembly.GetManifestResourceStream("MyPresentation.PPT"))
using (Stream output = File.Create(tempFile))
{
input.CopyTo(output); // Stream.CopyTo() is new in .NET 4.0, used for simplicity and illustration purposes.
}
Then you open it using Process.Start(). You don't need to specify the path to the Powerpoint executable, as PPT should be a registered file extension with either PowerPoint or the PowerPoint Viewer. If you have both installed, you may still want to provide the path to the relevant executable to prevent launching the wrong application. Make sure that you don't hardcode the path though, but try to retrieve it from the registry (or similar, I haven't checked because that gets too specific now).
using (var process = Process.Start(tempFile))
{
process.WaitForExit();
// remove temporary file after use
File.Delete(tempFile);
}
Note: I left out quite some error handling that you might want to add in a real application.
Camera will capture image and store in a folder(.bmp file).Simultaneously our application needs to get one by one image file from the folder for processing.(captured images will update the folder dynamically.If we use FileSystemWatcher , it may cause problem for us.(We are selecting the directory before processing of the image,so updated images will not process.Is there any solution for this problem)how to get one by one image from the folder at run time?
One solution would be to use a FileSystemWatcher to get notified when a new file is put into the folder. Then, process the file(s).
To get the file names of all BMP files in a folder you can use:
string[] fileNames = Directory.GetFiles("<path>", "*.bmp");
Then you can load the bitmaps normally.
You can use FileSystemWatcher but you need to be aware of a few quirks. The watcher will raise a Created event when a file is first created and one or more Modified events as data is written to the files. There is no Close event so you can't know when the camera has stopped writing to the file.
As long as the file is open for writing, you won't be able to read it for processing and any attempt to read it will raise an exception
There are several ways you can handle this:
You can log all events in a list and periodically process all files in the list. If you fail to open a file, just leave it in the list to process in the next processing round.
You can delay reading the file hoping that the camera will finish writing by the time you try to read the file. If you still receive an exception, wait for a while and then retry.
You can keep track of the Created and Modified events eg. in a dictionary keyed by the file name and try to open the file only if no event is received for a file after a specific timeout.
Polling and timeouts can be implemented using timers.
If you don't like the delay introduced by polling, you can use a separate thread to wait on the list of events and process new events as they appear. You can use the functionality of the BlockingCollection in C# 4 to do this in a relatively simple way.
Use FileSystemWatcher http://msdn.microsoft.com/en-us/library/system.io.filesystemwatcher.aspx
Any image development will require to know how to load an image in C#.
FromFile
There are two direct ways to read an image file and load it into either a Bitmap or Image. Behold the C# code:
Image myImg = Image.FromFile("path here");
Bitmap myBmp = Bitmap.FromFile("path here");
Alternatively a Bitmap object can also be loaded with:
Bitmap myBmp = new Bitmap("path here");
The code above does not work with Image objects though, so it is best to stick with FromFile.
Dialog Box
Finally, to write an application that loads an image from a file, your C# program needs a dialogbox to select files. Using the .Net OpenFileDialog is simple enough. Just apply the image-loading code to the Filename chosen by the user, so for example:
Bitmap loadedBitmap = Bitmap.FromFile(openFileDialog1.Filename);
Of course, you don't have to necessarily load an image from a file in this manner, but it is a useful thing to know.
For more information HERE
My application need to download multiple files in Silverlight, and because I don't want to ask user multiple times for permission to save the files, I save the files in IsolatedStorage first and then I want to zip them all to a file and ask once for saving permission.
therefore I used SharpZipLib to zip multiple files which are located in IsolatedStorage, the problem is that SharpZipLib just accept file address as ZipEntery:
ZipEntry z= new ZipEntry(name);
and as you know cause the files are located in IsolatedStorage I don't have the address of them.
I saw sample on Create a Zip from/to a memory stream or byte array but I cant use it for multiple files.
Please help me to find a way to use SharpZipLib or introduce me another way to downloading multiple files without asking multiple times for permission.
The name in ZipEntry z= new ZipEntry(name); is a logical/relative name inside your zip, you can establish it any way you want.
So as long as you can re-open you IsoStorage files as a Stream, you should be able to use SharpZip.