【发布时间】:2020-01-27 17:22:11
【问题描述】:
我可以下载 byte[]'s 并将它们写入文件没有问题,much link this link does。但是,当我进行简单的更改,将 bytes[] 和 readCount 保存到一个列表中,然后在列表上进行 foreach 时,我得到了一个损坏的文件。
下面是部分代码,说明了我的意思。有两个注释路径:一个存储字节/计数(和顺序),然后在读取完成时写入。另一个写入与每次读取一致。
由于 order 字段,我已经验证了 foreach 正在以正确的顺序写入字节,但部分代码清单没有明确使用它。
private class ByteHolder
{
public byte[] Buffer { get; set; } = new byte[8192];
public int BytesRead { get; set; }
public int Order { get; set; }
}
var byteList = new List<ByteHolder>();
using (var fileStream = new FileStream(_fileBytes.SavingPath.RuntimePath(), FileMode.Create, FileAccess.Write, FileShare.None, 8192, true))
{
do
{
var bytesRead = await contentStream.ReadAsync(buffer, 0, buffer.Length);
if (bytesRead == 0)
{
//--- WRITING THE bytes and counts this way produces corrupt file -->
var offset = 0;
foreach (var byteHolder in byteList)
{
await fileStream.WriteAsync(byteHolder.Buffer, offset, byteHolder.BytesRead).ConfigureAwait(false);
offset += 8192;
}
isMoreToRead = false;
FileDownloadComplete?.Invoke(this, _fileBytes);
continue;
}
//--- Storing them in this class and list for writing above DOES NOT WORK -->
byteList.Add(new ByteHolder() { Buffer = buffer, BytesRead = bytesRead, Order = readCount });
//--- Writing inline with the read WORKS -->
//await fileStream.WriteAsync(buffer, 0, bytesRead);
readCount++;
totalBytesRead += bytesRead;
【问题讨论】:
-
所以你总是将数据从偏移量 0 写入文件,你需要在“foreach”循环中增加偏移量。
-
感谢您的回复。我在上面的示例代码中添加了偏移量。它仍然会生成损坏的文件。不确定我是否应该抵消缓冲区大小或读取大小,但两者都不起作用。我正在使用的文件是 xlsx。 (此外,内联 WriteAsync 使用偏移量 0 并且它有效!?)特定的 xlsx 需要四次读取才能下载。
-
看一下WriteAsync的文档,你传入的偏移量是buffer中的偏移量,而不是文件中的偏移量。它应该始终为 0;增量是不必要的。
-
buffer在哪里初始化?在这里,您在每个循环上重用相同的缓冲区数组,这就是导致问题的原因。每次阅读都必须创建一个新的缓冲区数组。 -
Mike Zboray,“每次阅读时创建一个新缓冲区”就是答案。非常感谢!这不是一个非常明显的解决方案。
标签: c# .net-core download httpclient