Not able to delete a file after File.WriteAllBytes() - c#

I am trying to write byte array to a file and sending it as email. After that I need to delete the file from the saved location.
But while deleting, it throws the error
'The process cannot access the file 'file path' because it is being
used by another process.'
As per the File.WriteAllBytes() documentation, it Creates a new file, writes the specified byte array to the file, and then closes the file. If the target file already exists, it is overwritten. Pls help me to find a solution.
string FolderPath = MyPath + "PaySlips";
string filePath = FolderPath + "/" + userID + "-PaySlip_" + ddlMonth.SelectedItem.Text + "_" + ddlYear.SelectedItem.Text + ".pdf";
if (!Directory.Exists(FolderPath))
{
Directory.CreateDirectory(FolderPath);
}
File.WriteAllBytes(filePath, bytes);
ArrayList attachments = new ArrayList();
attachments.Add(filePath);
SendEmail(emailID, cc, attachments);
if (File.Exists(attachments[0].ToString())) {
File.Delete(attachments[0].ToString()); //exception happens here
}
'''

string FolderPath = MyPath + "PaySlips";
string filePath = FolderPath + "/" + userID + "-PaySlip_" + ddlMonth.SelectedItem.Text + "_" + ddlYear.SelectedItem.Text + ".pdf";
if (!Directory.Exists(FolderPath))
{
Directory.CreateDirectory(FolderPath);
}
File.WriteAllBytes(filePath, bytes);
File.Close();
File.Dispose();
ArrayList attachments = new ArrayList();
attachments.Add(filePath);
SendEmail(emailID, cc, attachments);
if (File.Exists(attachments[0].ToString())) {
File.Delete(attachments[0].ToString());
}

I got the solution. Thanks #Cleptus
File.WriteAllBytes() is already closed and in the SendMail(), it's got opened again. So by disposing those objects, it worked
The SendEmail() method in my code has
SmtpClient smC= new SmtpClient();
MailMessage mM= new MailMessage();
I added dispose of SMTPClient and MailMessage in finally block
try
{
smC.Send(mM);
}
catch (Exception ex)
{
Err = ex.Message;
}
finally {
mM.Dispose();
smC.Dispose();
}

you need to delete the file after "close" not before. As long as the close has not executed, the file will be in the stream loop and it counts as its own process and thus cannot be deleted until the file is closed. Hope this helps. Im guessing your close statement is below that code. Move it before the delete statment.

Related

ASP.Net uploading image to wwwroot folder

I keep on getting the same error in uploading a image on the published project in IIS: "UnauthorizedAccessException: Access to the path 'C:\inetpub\wwwroot\TestProj\wwwroot\files\clients\1111_64d96158-2a74-4277-98ed-7b12ba290b2d_CJQYABUT-SAMPLE-ID.jpg' is denied."
I keep on chaging the codes from _webHostEnvironment.WebRootPath and ContentRootPath, i tried using var uniqueFileName = "wwwroot/files/clients/"; and still dont work.
Here are some of the codes i tried,
string uniqueFileName = null;
if (client.FirstFile != null)
{
string uploadsFolder ="wwwroot/files/clients/";
uniqueFileName = client.Number + "_" + Guid.NewGuid().ToString() + "_" + client.FirstFile.FileName;
string filePath = Path.Combine(uploadsFolder, uniqueFileName);
using (var fileStream = new FileStream(filePath, FileMode.Create))
{
await client.FirstFile.CopyToAsync(fileStream);
}
client.FilePath = "/files/UploadImages/" + uniqueFileName;
}
string uniqueFileName = null;
if (client.FirstFile != null)
{
string uploadsFolder = Path.Combine(_webHostEnvironment.WebRootPath, "files/clients/");
uniqueFileName = client.Number + "_" + Guid.NewGuid().ToString() + "_" + client.FirstFile.FileName;
string filePath = Path.Combine(uploadsFolder, uniqueFileName);
using (var fileStream = new FileStream(filePath, FileMode.Create))
{
await client.FirstFile.CopyToAsync(fileStream);
}
client.FilePath = "/files/UploadImages/" + uniqueFileName;
}
string uniqueFileName = null;
if (client.FirstFile != null)
{
string uploadsFolder = Path.Combine(_webHostEnvironment.ContentRootPath, "wwwroot/files/clients/");
uniqueFileName = client.Number + "_" + Guid.NewGuid().ToString() + "_" + client.FirstFile.FileName;
string filePath = Path.Combine(uploadsFolder, uniqueFileName);
using (var fileStream = new FileStream(filePath, FileMode.Create))
{
await client.FirstFile.CopyToAsync(fileStream);
}
client.FilePath = "/files/UploadImages/" + uniqueFileName;
}
I don't know if I'm missing something, please help. Thanks
The "UnauthorizedAccessException" error message you're seeing is indicating that the user account that the IIS worker process is running under does not have permission to access the specified file path.
There are a few things you can try to resolve this issue:
Make sure that the user account that the IIS worker process is running under (usually "IIS_IUSRS") has read and write access to the folder that you're trying to save the image in.
If you are using a version of IIS less than 8.5, you may need to configure the application pool to run as the "LocalSystem" account, which has the necessary permissions to access the folder.
You can also try to give the permissions for the folder to the "Everyone" group to confirm it's not a permission issue. But keep in mind that giving permissions to the "Everyone" group could be a security risk.
If you're still facing the same issue, you could try checking the file and folder permissions for the folder in Windows.
Another alternative is change the location of the image to be stored, to a folder outside the IIS.
Make sure that after you've made any changes to the file or folder permissions, you restart the IIS worker process for the changes to take effect.

Attempting to loop through a list of direct download links; first file downloads but second gets stuck at 0 bytes and never finishes (C#)

I'm attempting to run through a list of direct download links using the code below. The code runs and downloads the first file just fine, as it moves to the second file (second link in the list), it correctly creates the new file and initiates download, but stops at 0 bytes and does not continue.
I've attempted to run through with breakpoints and similar, and all data looks correct. I've moreover confirmed it is possible to download multiple files in rapid succession without any issues from the website in question.
Any help, feedback or suggestions would be greatly appreciated!
foreach (string s in links)
{
using (WebClient w = new WebClient())
{
try
{
Console.WriteLine("Attempting to download " + s);
w.OpenRead(s);
string content = w.ResponseHeaders["Content-Disposition"];
string filename = new ContentDisposition(content).FileName;
w.DownloadFile(new Uri(s), _directory + filename);
Console.WriteLine("Downloaded " + filename);
}
catch(WebException e)
{
Console.WriteLine(e.Message);
}
}
}
Furthermore, downloading directly, i.e. by using the below, works fine.
using (WebClient w = new WebClient())
{
w.DownloadFile(new Uri(downloadLinks[0]), _directory + "test");
w.DownloadFile(new Uri(downloadLinks[1]), _directory + "test1");
w.DownloadFile(new Uri(downloadLinks[2]), _directory + "test2");
w.DownloadFile(new Uri(downloadLinks[3]), _directory + "test3");
}
Thanks!
I suspect the problem is this line:
w.OpenRead(s);
That's returning a Stream that you never close. Now you could just close it... but it would be better to use it, and not bother with the DownloadFile call:
using (Stream responseStream = w.OpenRead(s))
{
string content = w.ResponseHeaders["Content-Disposition"];
string filename = new ContentDisposition(content).FileName;
using (Stream fileStream = File.Create(filename))
{
responseStream.CopyTo(fileStream);
}
Console.WriteLine("Downloaded " + filename);
}

decrypt pgp files from a folder and moving it - c#

I am trying to decrypt .pgp files from a location and then moving those files to another location. I looked into this article and code accordingly. In my code I am developing an application which will check to a certain location after every 100 seconds and if there are files then it will decrypt and move. but I am getting this exception The process cannot access the file 'c:\file.pgp' because it is being used by another process.
Here is my code where I am calling that class which I copied from that article.
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
//Do the stuff you want to be done every hour;
string sourcePath = #"files location";
string archivePath = #"move original file after decrypting location";
string targetPath = #"decrypted file location";
string pubkeyPath = #"public key location\PGPPublicKey.txt";
string privkeyPath = #"private key location\PGPPrivateKey.txt";
string fileName = "";
string destFile = "";
if (System.IO.Directory.Exists(sourcePath))
{
string[] files = System.IO.Directory.GetFiles(sourcePath);
// Copy the files and overwrite destination files if they already exist.
foreach (string s in files)
{
PGPDecrypt test = new PGPDecrypt(s,
privkeyPath,
"password",
targetPath + "decrypted.txt",
pubkeyPath);
FileStream fs = File.Open(s, FileMode.Open);
test.decrypt(fs, targetPath + "decrypted.txt");
// Use static Path methods to extract only the file name from the path.
fileName = System.IO.Path.GetFileName(s);
destFile = System.IO.Path.Combine(archivePath, fileName);
System.IO.File.Move(s, archivePath);
}
}
}
Where are you getting the error. If you are getting error while moving it might be because your filestream is not close. After decryption and before move close the filestream with fs.Close();
I believe the issue you are having is caused by the file not being closed, when you loop with the foreach loop the first iteration probably works. However, the next time, because it was never closed, it is still being used.
Try adding
fs.Close();
At the end of the foreach loop
This is I ended up and it is working
//Decrypt
using DidiSoft.Pgp;
PGPLib pgp = new PGPLib();
string inputFileLocation = file Location;
string privateKeyLocation = #"I posted my private at this location";
string privateKeyPassword = "Decryption Password";
string outputFile = #"Output Location";
// decrypt and obtain the original file name
// of the decrypted file
string originalFileName =
pgp.DecryptFile(inputFileLocation,
privateKeyLocation,
privateKeyPassword,
outputFile);
//Move decrypted file to archive
string path = Decrypted file Location;
string path2 = #"Archive file location" + Path.GetFileName(file); ;
try
{
if (!File.Exists(path))
{
// This statement ensures that the file is created,
// but the handle is not kept.
using (FileStream fs = File.Create(path)) { }
}
// Ensure that the target does not exist.
if (File.Exists(path2))
File.Delete(path2);
// Move the file.
File.Move(path, path2);
}
catch (Exception e)
{
}

Directory is locked after creation of file while program is running

After I created a file in a directory the directory is locked as long as my program which created the file is running. Is there any way to release the lock? I need to rename the directory couple of lines later and I always get an IOException saying "Access to the path "..." denied".
Directory.CreateDirectory(dstPath);
File.Copy(srcPath + "\\File1.txt", dstPath + "\\File1.txt"); // no lock yet
File.Create(dstPath + "\\" + "File2.txt"); // causes lock
File.Create(string path) Creates a file and leaves the stream open.
you need to do the following:
Directory.CreateDirectory(dstPath);
File.Copy(srcPath + "\\File1.txt", dstPath + "\\File1.txt");
using (var stream = File.Create(dstPath + "\\" + "File2.txt"))
{
//you can write to the file here
}
The using statement asures you that the stream will be closed and the lock to the file will be released.
Hope this helps
Have you tried closing your FileStream? e.g.
var fs = File.Create(dstPath + "\\" + "File2.txt"); // causes lock
fs.Close();
i suggest you use a using statement:
using (var stream = File.Create(path))
{
//....
}
but you should also be aware of using object initializers in using statements:
using (var stream = new FileStream(path) {Position = position})
{
//....
}
in this case it will be compiled in:
var tmp = new FileStream(path);
tmp.Position = position;
var stream = tmp;
try
{ }
finally
{
if (stream != null)
((IDisposable)stream).Dispose();
}
and if the Position setter throw exception, Dispose() will not being called for the temporary variable.

The process can not access the file 'directory\file' because it is being used by another process in C# File Writer

I receive this error when ever I attempt to save on the existing file:
the process can not access the file because it is being used by another process
It works when a file doesn't exist, but when I attempt to write in it again the error shows up. I'm not accessing or using the file that time.
here is the code:
string directory = filepath + "Updates\\" + dir;
if(!Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
remarks = remarks.Trim();
remarks = remarks.Replace("\r\n","<br>");
remarks = remarks.Replace(",","|");
string file = directory + "\\" + getIndex(barcode) + ".asdt";
StreamWriter writer = new StreamWriter(file,true);
writer.WriteLine(username + "," + barcode + "," + DateTime.Now.ToString("yyyy-MM-dd HH.mm")+ "," + remarks);
writer.Close();
When I checked it the error occurs on the line:
StreamWriter writer = new StreamWriter(file,true);
what could be the cause of this?
Your program is probably not disposing of the file stream properly, keeping the file open.
Use the using statement to ensure proper disposal:
using(StreamWriter writer = new StreamWriter(file,true))
{
writer.WriteLine(username + "," + barcode + "," + DateTime.Now.ToString("yyyy-MM-dd HH.mm")+ "," + remarks);
writer.Close();
}
Or you can nullify the writer object after closing.
try to use writer.Flush(); before writer.Close();

Categories

Resources