Apo*_*llo 2 c# asp.net-mvc stream
我有一个包含 zip 文件的 URL。需要从 URL 中解压缩文件。使用 webclient 打开和读取 URL,然后将其添加到流中。然后在 ZipArchive 对象中使用它,该对象将解压缩文件并将它们存储在 D:\ 驱动器中。当文件大小约为 400Mb 时,我会收到'System.OutOfMemoryException'。
由于 webClient.OpenRead(Uri Address) 返回一个 Stream,因此必须使用 Stream。以及使用ZipArchive(Stream流)。
我怎样才能停止收到此消息?
string zipFileUrl = "https://www.dropbox.com/s/clersbjdcshpdy6/oversize_zip_test_0.zip?dl=0"
string output_path = @"D:\";
using (WebClient webClient = new WebClient())
{
using (Stream streamFile = webClient.OpenRead(zipFileUrl))
{
using (ZipArchive archive = new ZipArchive(streamFile))//ERROR HERE
{
var entries = archive.Entries;
//Loops thru each file in Zip and adds it to directory
foreach (var entry in entries)
{
if (entry.FullName != "/" && entry.Name != "")
{
string completeFileName = Path.Combine(output_path, entry.FullName);
string directory = Path.GetDirectoryName(completeFileName);
//If directory does not exist then we create it.
if (!Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
//Extracts zip from URL to extract path, and overwrites if file exists.
entry.ExtractToFile(completeFileName, true);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
从方法上看,我认为这可能是你的问题ZipArchive.Init
private void Init(Stream stream, ZipArchiveMode mode, Boolean leaveOpen)
{
Stream extraTempStream = null;
try
{
_backingStream = null;
//check stream against mode
switch (mode)
{
case ZipArchiveMode.Create:
// (SNIP)
case ZipArchiveMode.Read:
if (!stream.CanRead)
throw new ArgumentException(SR.ReadModeCapabilities);
if (!stream.CanSeek)
{
_backingStream = stream;
extraTempStream = stream = new MemoryStream();
_backingStream.CopyTo(stream);
stream.Seek(0, SeekOrigin.Begin);
}
break;
case ZipArchiveMode.Update:
// (SNIP)
default:
// (SNIP)
}
// (SNIP)
}
Run Code Online (Sandbox Code Playgroud)
如果streamFile.CanSeek为 false(来自 WebClient 的情况为 false),则会将整个文件复制到内存中,然后处理该文件。这就是耗尽所有内存的原因。
尝试找到一个处理 Zip 文件并且不需要支持查找的流的第 3 方库。如果不能,请先将文件复制到磁盘的临时文件夹中并传入FileStream选项FileOptions.DeleteOnClose,然后在关闭流之前在 zip 中使用该流。
string zipFileUrl = "https://www.dropbox.com/s/clersbjdcshpdy6/oversize_zip_test_0.zip?dl=0";
string output_path = @"D:\";
using (var tempFileStream = new FileStream(Path.GetTempFileName(), FileMode.Create,
FileAccess.ReadWrite, FileShare.None,
4096, FileOptions.DeleteOnClose))
{
using (WebClient webClient = new WebClient())
{
using (Stream streamFile = webClient.OpenRead(zipFileUrl))
{
streamFile.CopyTo(tempFileStream);
}
}
tempFileStream.Position = 0;
using (ZipArchive archive = new ZipArchive(tempFileStream))
{
var entries = archive.Entries;
//Loops thru each file in Zip and adds it to directory
foreach (var entry in entries)
{
if (entry.FullName != "/" && entry.Name != "")
{
string completeFileName = Path.Combine(output_path, entry.FullName);
string directory = Path.GetDirectoryName(completeFileName);
//If directory does not exist then we create it.
if (!Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
//Extracts zip from URL to extract path, and overwrites if file exists.
entry.ExtractToFile(completeFileName, true);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2536 次 |
| 最近记录: |