【问题标题】:Can Stream.CopyTo() method save the streams incomplete?Stream.CopyTo() 方法可以保存不完整的流吗?
【发布时间】:2015-03-09 13:26:49
【问题描述】:

我有一个 WCF 服务,它允许我分块上传文件。我想知道的是,在任何情况下,这段代码是否会导致上传的流仅部分附加到目标流?

我的日志显示所有发送的流都是 512000 字节(我在客户端设置的),到目前为止,我已经发送了 9 个块中的 6 个块。但在服务器上,文件大小为 2634325。这意味着发送的最后一个块(第 6 个)保存不完整。

是什么导致了这种行为?我应该怎么做才能避免这种情况?

或者这是完全安全的,我应该在其他地方寻找错误?

public void UploadChunk ( RemoteFileChunk file )
{
    /// this file is not touched by anyone else
    var uploadPath = @"C:\some path\some.file";

    using ( var targetStream = new FileStream(uploadPath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None) )
    { 
        if ( targetStream.Length == file.ChunkNumber * Helper.ChunkSize )
        {
            /// ---- streaming operation is here ----
            targetStream.Position = targetStream.Length;
            file.Stream.CopyTo(targetStream);
            file.Stream.Close();
            /// -------------------------------------
        }
        else throw new FaultException<DataIntegrityException>(new DataIntegrityException
        {
            CurrentIndex = targetStream.Length,
            RequestedIndex = file.ChunkNumber * Helper.ChunkSize,
            Message = string.Format("{0}th chunk index requested when there already {1} chunks exist.", file.ChunkNumber, targetStream.Length / Helper.ChunkSize)
        });
    }
}

下面是客户端文件上传代码sn -p:

var buffer = new byte[ChunkIndex != NumberOfChunks - 1 ? Helper.ChunkSize : LastPieceLen];

using ( var file = new FileStream(Info.FullName, FileMode.Open, FileAccess.Read, FileShare.None) )
{
    file.Position = (long)ChunkIndex * Helper.ChunkSize;
    file.Read(buffer, 0, buffer.Length);
}

var chunk = new MemoryStream(buffer);

chunk.Position = 0;
Service.StreamingEnd.UploadChunk(new RemoteFileChunk(FileId, CF.Id, VersionDate, ChunkIndex, chunk.Length, Sessions.Get(), chunk));

【问题讨论】:

  • The underlying implementation of Stream.CopyTo() 非常简单,不会导致您描述的行为。你在其他地方有一个错误。请编辑您的问题,使其包含可靠地重现问题的a good, minimal, complete code example。
  • 分块是如何工作的?是 HTTP 分块吗?这些块不是固定大小的。
  • 我也添加了上传代码sn-p。但是由于这个问题偶尔会发生,而且问题实际上是在询问有关奇怪行为的可能原因的想法,我认为我无法放置可靠地重现问题的代码。
  • 不,我使用自己的分块程序。它们基本上是我从源流中部分读取的流。

标签: c# filestream wcf-streaming


【解决方案1】:

看一下 if 语句——最终块是否保证与块大小完全相同?如果您上传的文件大小不是块大小的倍数会怎样?

【讨论】:

  • 实际上该文件由 17 个块组成。如果您查看上传代码,则有最后一个块的处理程序。所以这个case其实已经涵盖了。
猜你喜欢
  • 1970-01-01
  • 2015-06-01
  • 1970-01-01
  • 2020-04-30
  • 2013-01-28
  • 2018-10-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多