要求: 1)創建多段(比如大小爲1 GB/500 MB)的分割zip文件,以便可以通過瀏覽器下載。所有分段的總壓縮量可能超過10 GB 2)壓縮內容可能是多個文件或包含子文件夾和文件的文件夾 3)文件的內容以流的形式從雲中讀取。文件的元信息(如文件夾層次結構)在本地可用如何在使用DotNetZip庫從內存流創建zip文件時傳遞文件夾層次結構
我正在使用DotNetZip庫來實現此任務。該代碼是如下:
long length = default(long);
Stream fileReadStream;
long Space = default(long);
string tempZipFile = string.Empty;
FileZipStatus oldStatue = new FileZipStatus();
byte[] Buffer = new byte[1024 * 1024];
if (zipFileName != null && !zipFileName.ToUpper().EndsWith(".ZIP")) zipFileName += ".zip";
string strTempFolder = "";
using (Ionic.Zip.ZipFile zip = new Ionic.Zip.ZipFile())
{
try
{
strTempFolderPath = tempZipOutPutFilePath + "\\";
string strTempFolderName = DateTime.Now.Ticks.ToString();
strTempFolder = strTempFolderPath + strTempFolderName;
if (userFileList.Count > 0)
{
if (Directory.Exists(strTempFolder))
{
Directory.Delete(strTempFolder);
}
Directory.CreateDirectory(strTempFolder);
}
foreach (UserFile userFile in userFileList)
{
WebResponse response = null;
try
{
WebRequest request = null;
IDictionary<string, object> _dictionary = new Dictionary<string, object>();
/// First
FileSystemEnum fileSysEnum = FileSystemBase.GetFileSystemEnumByStorageId(userFile.StorageId);
IFileSystemLib ifileSystemLocal = FileSystemFactory.GetSpecificInstance(fileSysEnum);
fileReadStream = ifileSystemLocal.GetFile(userFile.FilePath, userFile.GuidName, ref request, ref response, _dictionary);
long filesize = default(long);
long.TryParse(ifileSystemLocal.GetFileContentLength(userFile.FilePath, userFile.GuidName).ToString(), out filesize);
Space = (Space > default(long)) ? (Space + filesize) : filesize;
//Now we have to store the data, so that we must access the file
int dataToRead;
FileStream writeStream = new FileStream(strTempFolder + "\\" + userFile.FileName, FileMode.Create, FileAccess.Write);
while ((dataToRead = fileReadStream.Read(Buffer, 0, Buffer.Length)) > 0)
{
writeStream.Write(Buffer, 0, dataToRead);
}
writeStream.Close();
zip.AddFile(strTempFolder + "\\" + userFile.FileName, userFile.RelativePath);
fileReadStream.Close();
}
catch (Exception ex)
{
LogManager.Trace(ex, "ZIpping Block - ZIPFileName", zipFileName + "File to zip" + userFile.GuidName);
}
finally
{
if (response != null) response.Close();
}
}
}
catch (Exception ex)
{
_currentStatus = FileZipStatus.NotAvailable;
oldStatue = UpdateZipStatus(ObjectZipID, Space, FileZipStatus.Failed);
throw ex;
}
finally
{
}
try
{
zip.Comment = "This zip was created at " + System.DateTime.Now.ToString("G");
zip.MaxOutputSegmentSize = 200 * 1024 * 1024; // 200 mb
zip.Save(strTempFolderPath + "\\" + zipFileName);
oldStatue = UpdateZipStatus(ObjectZipID, Space, FileZipStatus.Available);
length = new FileInfo(strTempFolderPath + "\\" + zipFileName).Length;
_currentStatus = FileZipStatus.Available;
// deleting temp folder
Directory.Delete(strTempFolder, true);
}
catch (Exception ex)
{
_currentStatus = FileZipStatus.NotAvailable;
oldStatue = UpdateZipStatus(ObjectZipID, Space, FileZipStatus.Failed);
length = default(long);
throw ex;
}
}
有在上面的代碼中使用的DotNetZip libray的限制。它需要 a)保存在磁盤上的文件作爲輸入。在這種情況下,可以爲每個文件傳遞文件夾層次結構信息。 或 2)如果流作爲輸入傳遞,文件夾層次結構信息不能傳遞給文件。
我需要傳遞每個文件的文件夾層次結構信息以及從流中讀取輸入。由於zip內容可能很大(可能超過10 GB),因此 不希望將文件保存在Web服務器的臨時存儲中。任何人都可以幫助像創建zip文件時如何傳遞文件夾層次結構?謝謝
可以討論如何寫入fileOutputStream映射到具有提示和示例代碼位的物理文件。謝謝 – Mou 2015-04-17 19:36:27