how to delete a zip file after copying into another folder...I am getting exception while deleting..It is saying that "The file is being used by another process".
string pathString1 = FullFilePath;
string sourceFileName = Path.GetFileName(pathString1);
string foldername = Path.GetDirectoryName(pathString1);
string pathString = Path.Combine(foldername, "Uploaded");
if (!System.IO.Directory.Exists(pathString))
{
System.IO.Directory.CreateDirectory(pathString);
string destFile = System.IO.Path.Combine(pathString, sourceFileName);
File.Copy(pathString1, destFile);
File.Delete(pathString1);
File.Delete(FileName);
}
If you decompress the zip-file, then do this in a using block or .Dispose() the object that is responsible for decompressing. What lib are you using?
To prevent the locking of files, the using statement will release the file when it's done with the operation:
using (FileStream stream = File.Open("path to file", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
...
}
Then again, if you're deleting the file right after you copy it, then why not just move it?
File.Move(from, to);
since there is this theory that a virus checker goes into your .zip file, you could re-try waiting for it to finish with retries
string pathString1 = FullFilePath;
string sourceFileName = Path.GetFileName(pathString1);
string foldername = Path.GetDirectoryName(pathString1);
string pathString = Path.Combine(foldername, "Uploaded");
if (!System.IO.Directory.Exists(pathString))
{
System.IO.Directory.CreateDirectory(pathString);
string destFile = System.IO.Path.Combine(pathString, sourceFileName);
File.Copy(pathString1, destFile);
int itries = 0;
int maxtries = 30; //suitable time of retrying
while (itries++ < maxtries)
{
try
{
File.Delete(pathString1);
itries = 999999;
}
catch (Exception ex)
{
if (itries > maxtries) throw ex;
Thread.Sleep(1000);
}
}
//File.Delete(FileName);
}
Related
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)
{
}
I want to upload a file in azure using C#.net no matter what format it will be. I want to check whether the file exists or not. If it exists then create a folder dynamically to save the uploaded file.
How can I pass another parameter which will check if the uploaded file exists or not, then if it exists, then create a subfolder in the Uploads folder to save it?
public UploadedFile Upload(Stream Uploading)
{
try
{
string filename = Guid.NewGuid().ToString() + ".png";
string FilePath = Path.Combine(HostingEnvironment.MapPath("~/Uploads"), filename);
UploadedFile upload = new UploadedFile
{
FilePath = FilePath
};
int length = 0;
using (FileStream writer = new FileStream(upload.FilePath, FileMode.Create))
{
int readCount;
var buffer = new byte[8192];
while ((readCount = Uploading.Read(buffer, 0, buffer.Length)) != 0)
{
writer.Write(buffer, 0, readCount);
length += readCount;
}
}
upload.FileLength = length;
return new UploadedFile { FilePath = "/Uploads/" + filename };
}
catch (Exception ex)
{
_logger.Error("Error Occured in Upload", ex);
ErrorData errorData = new ErrorData("Error Occured ", ex.Message);
throw new WebFaultException<ErrorData>(errorData, HttpStatusCode.OK);
}
}
Before you upload the file check if the same file name exists in the path. You can check if file exists using below code
//Read the path of your file
string curFile = #"c:\temp\test.txt";
Console.WriteLine(File.Exists(curFile) ? "File exists." : "File does not exist.");
https://msdn.microsoft.com/en-us/library/system.io.file.exists%28v=vs.110%29.aspx
I use this simple code for log files.
private string LogFile
{
get
{
if (String.IsNullOrEmpty(this.LogFile1))
{
string fn = "\\log.txt";
int count = 0;
while (File.Exists(fn))
{
fn = fn + "(" + count++ + ").txt";
}
this.LogFile1 = fn;
}
return this.LogFile1;
}
}
How can I move every log file into another directory ( folder ) and make it archive like .zip?
This will run once per and I will have one file per day.
File moving:
public static void Move()
{
string path = "";
string path2 = "";
try
{
if (!File.Exists(path))
{
using (FileStream fs = File.Create(path)) { }
}
if (File.Exists(path2))
File.Delete(path2);
File.Move(path, path2);
}
catch (Exception e)
{
Console.WriteLine("The process failed: {0}", e.ToString());
}
}
For move files, you can use the static method Move of File class. And for zip files, you can look at GZipStream or ZipArchive class.
If you want windows zipping.
Then check this out :
https://msdn.microsoft.com/en-us/library/system.io.compression.zipfile(v=vs.110).aspx
using System;
using System.IO;
using System.IO.Compression;
namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
string startPath = #"c:\example\start";
string zipPath = #"c:\example\result.zip";
string extractPath = #"c:\example\extract";
ZipFile.CreateFromDirectory(startPath, zipPath);
ZipFile.ExtractToDirectory(zipPath, extractPath);
}
}
}
// for moving
File.Move(SourceFile, DestinationFile); // store in dateTime directory to move file.
//method for zip file
private static void CompressFile(string path)
{
FileStream sourceFile = File.OpenRead(path);
FileStream destinationFile = File.Create(path + ".gz");
byte[] buffer = new byte[sourceFile.Length];
sourceFile.Read(buffer, 0, buffer.Length);
using (GZipStream output = new GZipStream(destinationFile,
CompressionMode.Compress))
{
Console.WriteLine("Compressing {0} to {1}.", sourceFile.Name,
destinationFile.Name, false);
output.Write(buffer, 0, buffer.Length);
}
// Close the files.
sourceFile.Close();
destinationFile.Close();
}
I have a small upload application where i upload a file using a webservice (asmx), check the MD5 and verify it. Problem is that when i verify the file it says that the file is locked by another process. Below is my code for uploading and verifying:
private static object padlock = new object();
Chunking the upload file in smaller bites and uploading each of them
[WebMethod]
public void LargeUpload(byte[] content, string uniqueName)
{
lock (padlock)
{
string path = Server.MapPath(PartialDir + "/" + uniqueName);
BinaryWriter writer = new BinaryWriter(File.Open(path, FileMode.Append, FileAccess.Write));
writer.Write(content);
writer.Flush();
writer.Close();
writer = null;
}
}
After the last one insert it into my database. After this the client verifies the file by requesting the MD5:
[WebMethod]
public int EndLargeUpload(string name, int folderId, long length, string uniqueName, int customerid)
{
lock (padlock)
{
string path = Server.MapPath(PartialDir + "/" + uniqueName);
string newPath = Server.MapPath(RepositoryDir + "/" + uniqueName);
File.Copy(path, newPath);
//delete partial
File.Delete(path);
string extension = Path.GetExtension(uniqueName);
string newFileName = uniqueName;
GWFile newFile = new GWFile();
newFile.DiscName = newFileName;
newFile.FileName = name;
newFile.FolderId = folderId;
newFile.Description = "";
newFile.Size = (int)length;
newFile.DiscFolder = Server.MapPath("/Repository");
newFile.DiscRelativePath = "/Repository/" + newFile.DiscName;
newFile.CustomerId = customerid;
IGWFileRepository fileRepository = ObjectFactory.GetInstance<IGWFileRepository>();
fileRepository.SaveFile(newFile);
return newFile.Id;
}
}
After the EndLargeUpload() method the client calls the RequestMD5 method with the id of the file, this call excepts with an exception that it cannot open the file ".....xxx..." because it s being used by another process...
private string GetMD5HashFromFile(string fileName)
{
lock (padlock)
{
using (FileStream file = new FileStream(fileName, FileMode.Open)) // <-- excepts here
{
MD5 md5 = new MD5CryptoServiceProvider();
byte[] retVal = md5.ComputeHash(file);
file.Close();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < retVal.Length; i++)
{
sb.Append(retVal[i].ToString("x2"));
}
return sb.ToString();
}
}
}
I used the process explorer from sysinternals to view the file, it says that the file is locked by the web server ( pls refer to this img: http://screencast.com/t/oqvqWXLjku) - how can the web server lock it? can I work around this?
How about the last two lines in the EndLargeUpload method:
IGWFileRepository fileRepository = ObjectFactory.GetInstance<IGWFileRepository>();
fileRepository.SaveFile(newFile);
Is it possible that IGWFileRepository.SaveFile() is not closing the file properly?
Switched to IIS, and the problem seems to go away...
I am using the SharpZipLib open source .net library from www.icsharpcode.net
My goal is to unzip an xml file and read it into a dataset. However I get the following error reading the file into a dataset: "Data at the root level is invalid. Line 1, position 1."
I believe what is happening is the unzipping code is not releasing the file for the following reasons.
1.) If I unzip the file and exit the application. When I restart the app I CAN read the unzipped file into a dataset.
2.) If I read in the xml file right after writing it out (no zipping) then it works fine.
3.) If I write the dataset to xml, zip it up, unzip it, then attempt to read it back in I get the exception.
The code below is pretty straight forward. UnZipFile will return the name of the file just unzipped. Right below this call is the call to read it into a dataset. The variable fileToRead is the full path to the newly unzipped xml file.
string fileToRead = UnZipFile(filepath, DOViewerUploadStoreArea);
ds.ReadXml(fileToRead )
private string UnZipFile(string file, string dirToUnzipTo)
{
string unzippedfile = "";
try
{
ZipInputStream s = new ZipInputStream(File.OpenRead(file));
ZipEntry myEntry;
string tmpEntry = String.Empty;
while ((myEntry = s.GetNextEntry()) != null)
{
string directoryName = dirToUnzipTo;
string fileName = Path.GetFileName(myEntry.Name);
string fileWDir = directoryName + fileName;
unzippedfile = fileWDir;
FileStream streamWriter = File.Create(fileWDir);
int size = 4096;
byte[] data = new byte[4096];
while (true)
{
size = s.Read(data, 0, data.Length);
if (size > 0) { streamWriter.Write(data, 0, size); }
else { break; }
}
streamWriter.Close();
}
s.Close();
}
catch (Exception ex)
{
LogStatus.WriteErrorLog(ex, "ERROR", "DOViewer.UnZipFile");
}
return (unzippedfile);
}
Well, what does the final file look like? (compared to the original). You don't show the zipping code, which might be part of the puzzle, especially as you are partially swallowing the exception.
I would also try ensuring everything IDisposable is Dispose()d, ideally via using; also - in case the problem is with path construction, use Path.Combine. And note that if myEntry.Name contains sub-directories, you will need to create them manually.
Here's what I have - it works for unzipping ICSharpCode.SharpZipLib.dll:
private string UnZipFile(string file, string dirToUnzipTo)
{
string unzippedfile = "";
try
{
using(Stream inStream = File.OpenRead(file))
using (ZipInputStream s = new ZipInputStream(inStream))
{
ZipEntry myEntry;
byte[] data = new byte[4096];
while ((myEntry = s.GetNextEntry()) != null)
{
string fileWDir = Path.Combine(dirToUnzipTo, myEntry.Name);
string dir = Path.GetDirectoryName(fileWDir);
// note only supports a single level of sub-directories...
if (!Directory.Exists(dir)) Directory.CreateDirectory(dir);
unzippedfile = fileWDir; // note; returns last file if multiple
using (FileStream outStream = File.Create(fileWDir))
{
int size;
while ((size = s.Read(data, 0, data.Length)) > 0)
{
outStream.Write(data, 0, size);
}
outStream.Close();
}
}
s.Close();
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
return (unzippedfile);
}
It could also be that the problem is either in the code that writes the zip, or the code that reads the generated file.
I compared the original with the final using TextPad and they are identical.
Also I rewrote the code to take advantage of the using. Here is the code.
My issue seems to be centered around file locking or something. If I unzip the file quit the application then start it up it will read find.
private string UnZipFile(string file, string dirToUnzipTo)
{
string unzippedfile = "";
try
{
using (ZipInputStream s = new ZipInputStream(File.OpenRead(file)))
{
ZipEntry theEntry;
while ((theEntry = s.GetNextEntry()) != null)
{
string directoryName = dirToUnzipTo;
string fileName = Path.GetFileName(theEntry.Name);
string fileWDir = directoryName + fileName;
unzippedfile = fileWDir;
if (fileName != String.Empty)
{
using (FileStream streamWriter = File.Create(fileWDir))
{
int size = 2048;
byte[] data = new byte[2048];
while (true)
{
size = s.Read(data, 0, data.Length);
if (size > 0)
{
streamWriter.Write(data, 0, size);
}
else
{
break;
}
}
}
}
}
}
}
catch (Exception ex)
{
LogStatus.WriteErrorLog(ex, "ERROR", "DOViewer.UnZipFile");
}
return (unzippedfile);
}
This is a lot simpler to do with DotNetZip.
using (ZipFile zip = ZipFile.Read(ExistingZipFile))
{
zip.ExtractAll(TargetDirectory);
}
If you want to decide on which files to extract ....
using (ZipFile zip = ZipFile.Read(ExistingZipFile))
{
foreach (ZipEntry e in zip)
{
if (wantThisFile(e.FileName)) e.Extract(TargetDirectory);
}
}
If you would like to overwrite existing files during extraction:
using (ZipFile zip = ZipFile.Read(ExistingZipFile))
{
zip.ExtractAll(TargetDirectory, ExtractExistingFileAction.OverwriteSilently);
}
Or, to extract password-protected entries:
using (ZipFile zip = ZipFile.Read(ExistingZipFile))
{
zip.Password = "Shhhh, Very Secret!";
zip.ExtractAll(TargetDirectory, ExtractExistingFileAction.OverwriteSilently);
}