将文件拆分为块

时间:2018-06-10 14:04:36

标签: c# .net

我试图将大文件(3gb +)拆分成100mb的块,然后通过HTTP发送这些块。 为了测试,我正在处理一个29 MB的文件,大小:30380892,磁盘大小:30384128 (所以目前没有使用100mb的限制条件)。

这是我的代码:

List<byte[]> bufferList = new List<byte[]>();
byte[] buffer = new byte[4096];
FileInfo fileInfo = new FileInfo(file);
long length = fileInfo.Length;
int nameCount = 0;
long sum = 0;
long count = 0;

using (FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read))
{    
    while (count < length)
    {
        sum = fs.Read(buffer, 0, buffer.Length);
        count += sum;

        bufferList.Add(buffer);
    }

    var output2 = new byte[bufferList.Sum(arr => arr.Length)];
    int writeIdx2 = 0;
    foreach (var byteArr in bufferList)
    {
        byteArr.CopyTo(output2, writeIdx2);
        writeIdx2 += byteArr.Length;
    }

    HttpUploadBytes(url, output2, ++nameCount + fileName, contentType, path);
}

在此测试代码中,我将我读取的每个缓冲区添加到列表中, 完成阅读后,我将缓冲区阵列组合成一个完整的数组。 问题是,我得到的结果(output2大小)是30384128(作为磁盘上的大小),因此在服务器中收到的文件已损坏。

我做错了什么?

1 个答案:

答案 0 :(得分:4)

问题是您要继续向buffer添加大小为4KB的bufferList buffer。这就是为什么你收到的文件大小与磁盘上的大小相匹配(在你的情况下恰好四舍五入到最接近的4KB)。

您的代码存在的一个更大问题是您发送的数据错误,因为您会覆盖buffer中的数据。例如,如果您发送200个块,则表示您发送了bufferList的最后一个内容的200个副本。

修复相对简单 - 在添加到bufferList.Add(buffer.Take(sum).ToArray()); 之前复制缓冲区:

sum

这也可以解决大小问题,因为最后一个块的大小会更小,如上次调用的bufferList所示。但最重要的是,BotService将包含缓冲区的副本,而不是对缓冲区本身的引用。