예제 #1
0
        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);
                    }
                }
            }
        }
예제 #2
0
        /**
         * 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);
        }
예제 #3
0
        ///<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;
        }
예제 #4
0
        /**
         * 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);
        }