protected override void onIteratorClosed(FileIterator iterator) { JobFileIterator ftiterator = (JobFileIterator)iterator; lock (dictionaryLock) { long fileLength = new System.IO.FileInfo(ftiterator.filePath).Length; int count; if (openedFiles.TryGetValue(ftiterator.filePath, out count)) { count -= 1; if (count == 0) { openedFiles.TryRemove(ftiterator.filePath, out count); File.Delete(ftiterator.filePath); //if (ftiterator.Job.Task.Info.Count != 1) if (Path.GetDirectoryName(ftiterator.filePath) != zipTempFolder) { Directory.Delete(Path.GetDirectoryName(ftiterator.filePath)); } } else { openedFiles.TryUpdate(ftiterator.filePath, count, count + 1); } } } }
/** * Creates an iterator which allows the owner to navigate in the file specified by * the path given as parameter. * The ZIPStorageModule registers the Iterator so that he can take trace of the * numbero of active iterator pointing to that file. */ public override FileIterator getIterator(string path) { long fileLength = new System.IO.FileInfo(path).Length; int count; lock (dictionaryLock) { if (openedFiles.TryGetValue(path, out count)) { openedFiles.TryUpdate(path, count + 1, count); } else { openedFiles.TryAdd(path, 1); } } FileIterator iterator = new JobFileIterator(this, path); return(iterator); }
///<summary> /// Prepares a Job performing the operations needed to execute the transfer. /// The file relative to the Job is zipped (but only if necessary) and a /// JobFileIterator is created and returned in order to allow the caller to /// access to the temporary file to trasnfer. ///</summary> public FileIterator prepareJob(SendingJob j) { //DateTime lastModify = j.Task.RequestTimestamp; // The timestamp string zipName = null; JobFileIterator jobIterator = null; try { // Check zipped file existence //if (!File.Exists(zipName)) { // NO MORE NEEDED ManualResetEvent zippedEvent; if (j.FilePaths.Count == 1 /*&& j.Task.Info[0].Type == FileTransfer.FileInfo.FType.DIRECTORY*/) { FileAttributes attr = 0; attr = File.GetAttributes(j.FilePaths.Last()); bool toZip = true; //DateTime lastModify; string uniquetoken; if ((attr & FileAttributes.Directory) == FileAttributes.Directory) { var directory = new DirectoryInfo(j.FilePaths[0]); //lastModify = RealLastModify(directory); uniquetoken = UniqueTokenFromDirectory(directory); } else { DateTime lastModify = new System.IO.FileInfo(j.FilePaths[0]).LastWriteTimeUtc; uniquetoken = "_" + lastModify.Year + lastModify.Month + lastModify.Day + lastModify.Hour + lastModify.Minute + lastModify.Second + lastModify.Millisecond; } zipName = Path.Combine(zipTempFolder, j.Task.Info[0].Name + uniquetoken); lock (dictionaryLock) { if (File.Exists(zipName)) { toZip = false; events.TryGetValue(zipName, out zippedEvent); } else { zippedEvent = new ManualResetEvent(false); events.TryAdd(zipName, zippedEvent); } } if (toZip) { if ((attr & FileAttributes.Directory) == FileAttributes.Directory) { // zip directory (including base directory) ZipFile.CreateFromDirectory(j.FilePaths.Last(), zipName, CompressionLevel.NoCompression, false); } else // otherwise // Note: if it's a file, ZipArchive has to work on a new file in order to zip { ZipArchive newFile = null; try { newFile = ZipFile.Open(zipName, ZipArchiveMode.Create); //string p = Path.GetDirectoryName(filePath); newFile.CreateEntryFromFile(j.FilePaths.Last(), Path.GetFileName(j.FilePaths.Last()), CompressionLevel.NoCompression); } finally { if (newFile != null) { newFile.Dispose(); } } } zippedEvent.Set(); lock (dictionaryLock) { events.TryRemove(zipName, out zippedEvent); zippedEvent = null; } } else { //TODO //WAIT UNITL FILE IS READY; if (zippedEvent != null) { zippedEvent.WaitOne(); } } } else { ZipArchive newFile = null; try { // Constructs the zip file name Directory.CreateDirectory(Path.Combine(zipTempFolder, j.Id)); zipName = Path.Combine(zipTempFolder, j.Id, j.Id + ".tmp");// + @"\" + Path.GetFileNameWithoutExtension(filePath) + date + ".zip"; newFile = ZipFile.Open(zipName, ZipArchiveMode.Create); foreach (string filePath in j.FilePaths) { /* Retrieves the file attributes to check if the file is a directory or not * because the way to zip is different in the two cases. */ FileAttributes attr = 0; attr = File.GetAttributes(filePath); if ((attr & FileAttributes.Directory) == FileAttributes.Directory) { string tmpArchivePath = Path.Combine(Path.GetDirectoryName(zipName), Path.GetFileName(filePath) + ".zip"); try { ZipFile.CreateFromDirectory(filePath, tmpArchivePath, CompressionLevel.NoCompression, false); newFile.CreateEntryFromFile(tmpArchivePath, Path.GetFileName(filePath), CompressionLevel.NoCompression); } finally { File.Delete(tmpArchivePath); } } else { newFile.CreateEntryFromFile(filePath, Path.GetFileName(filePath), CompressionLevel.NoCompression); } } //} } finally { newFile.Dispose(); } } // Intializes the remaining info in the task (SentName and Size) j.Task.SentName = Path.GetFileName(zipName); // name of the zipped file j.Task.Size = new System.IO.FileInfo(zipName).Length; // size of the zipped file // Returns an iterator to the file jobIterator = (JobFileIterator)getIterator(zipName); jobIterator.Job = j; //} } catch (IOException e) { if (zipName != null && File.Exists(zipName)) { File.Delete(zipName); } if (Directory.Exists(Path.Combine(zipTempFolder, j.Id))) { Directory.Delete(Path.Combine(zipTempFolder, j.Id)); } throw e; } return(jobIterator); // File not found //return null; }
/** * Given a Task as parameter, creates a related Job in the receiving jobs list, * prepares a file coherent with what specified by the Task and returns a FileIterator * for this file. */ public FileIterator createJob(FileTransfer.Task task, string receivePath) { // Retrieves current date and computes a string to uniquely identify the task string zipTempFolder = Settings.Instance.AppDataPath + "\\temp"; Directory.CreateDirectory(Path.Combine(zipTempFolder, task.Id)); String path = Path.Combine(zipTempFolder, task.Id, task.Id + ".tmp"); ReceivingJob job = new ReceivingJob(task, receivePath); // Creates or retrieves the directory selected for the reception DirectoryInfo di = Directory.CreateDirectory(receivePath); // Creates the new file. Note: the file is zipped // This file is created in the temp directory File.Create(path).Close(); // Creates a new iterator to the file JobFileIterator iterator = (JobFileIterator)getIterator(path); iterator.Job = job; // Defines the behavior when the iterator is going to be closed // registering a callback on the related event. iterator.BeforeIteratorClosed += () => { // Job not completed: nothing to extract if (job.SentByte != job.Task.Size) { return; } List <String> createdFiles = new List <String>(); List <String> createdDirs = new List <String>(); string tempPath; try { // If there is only one file in the archive if (job.Task.Info.Count == 1 /* && job.Task.Info[0].Type == FileTransfer.FileInfo.FType.DIRECTORY*/) { //ZipFile.ExtractToDirectory(path, GetUniqueFilePath(receivePath + "\\" + job.Task.Info.Last().Name)); if (job.Task.Info.Last().Type == FileTransfer.FileInfo.FType.DIRECTORY) { tempPath = GetUniqueFilePath(receivePath + "\\" + job.Task.Info.Last().Name); createdDirs.Add(tempPath); ZipFile.ExtractToDirectory(path, tempPath); } else { using (ZipArchive archive = ZipFile.OpenRead(path)) { foreach (ZipArchiveEntry entry in archive.Entries) { tempPath = GetUniqueFilePath(Path.Combine(job.DestinationPath, entry.Name)); createdFiles.Add(tempPath); entry.ExtractToFile(tempPath); } } } } else // more than one file { using (ZipArchive archive = ZipFile.OpenRead(path)) { foreach (FileTransfer.FileInfo fileInfo in job.Task.Info) { foreach (ZipArchiveEntry entry in archive.Entries) { if (fileInfo.Name == entry.Name) { if (fileInfo.Type == FileTransfer.FileInfo.FType.DIRECTORY) { // This temporary unique path will be used as the path of the zip file that will be then unzipped again to obtain the final file string uniqueFileName = GetUniqueFilePath(Path.Combine(Path.GetDirectoryName(path), entry.Name)); try { entry.ExtractToFile(uniqueFileName + ".zip"); // extraxt entry to the temp zip archive // Now we perform the real extraction to unzip the directory in the selcted location tempPath = GetUniqueFilePath(Path.Combine(receivePath, fileInfo.Name)); createdDirs.Add(tempPath); ZipFile.ExtractToDirectory(uniqueFileName + ".zip", tempPath); } finally { // we need to delete the temporary file we created // this must be done even if an exception occours File.Delete(uniqueFileName + ".zip"); } } else { tempPath = GetUniqueFilePath(Path.Combine(job.DestinationPath, entry.Name)); createdFiles.Add(tempPath); entry.ExtractToFile(tempPath); } } } } } } } catch (Exception e) { // In the case any exception occours, we // must delete any file we have created // Delete all files foreach (String s in createdFiles) { if (File.Exists(s)) { File.Delete(s); } } // Delete all directories foreach (String d in createdDirs) { if (Directory.Exists(d)) { Directory.Delete(d, true); // delete recursive } } // Re-throw exception so that can be catched on upper levels throw e; } //JobsList.Receiving.remove(job.Id); }; return(iterator); }