将流写入文件不起作用



我正在制作一个程序,通过TCP以块的形式传输文件。现在,每次我传输一个文件,最后一点似乎没有写入,所以如果我试图传输右下角的图片,就会出现故障。现在,我的第一个想法是,当我读取、传输和写入小于缓冲区长度的最后一个块时,我也会写入很多零。因此,我尝试相应地更改最后一个缓冲区的大小。然后,我用一个只有HELLO WORLD的小文本文件尝试了一下,但当我把它写进去,然后打开文件时,它是空的。

这是读取和发送代码,其中范围[0]是第一部分,范围[1]是最后一部分:

byte[] buffer = new byte[DATA_BUFF_SIZE];
using (Stream input = File.OpenRead(file.Path))
{
    Console.WriteLine("SENT PARTS # ");
    for (int i = range[0]; i <= range[1]; i++)
    {
        Console.Write("PART " + i + ", ");
        if (i == range[1])
        {
            buffer = new byte[input.Length - input.Position];
        }
        input.Position = i * DATA_BUFF_SIZE;
        input.Read(buffer, 0, buffer.Length);
        netStream.Write(buffer, 0, buffer.Length);
    }
    Console.WriteLine("LENGTH = " + input.Length);
}

这是接收和写入代码:

int bytesReceived = 0;
int index = partRange.First;
int partNum = 0;
byte[] receiveBuffer = new byte[BUFF_SIZE];
if (index == partRange.Last)
{
    receiveBuffer = new byte[fileToDownload.Length - index * BUFF_SIZE];
}
while ((bytesReceived = netStream.Read(receiveBuffer, 0, receiveBuffer.Length)) > 0)
{
    Console.Write("INDEX:" + index + ", ");
    output.Position = index * BUFF_SIZE;
    output.Write(receiveBuffer, 0, receiveBuffer.Length);
    index++;
    partNum++;
    if (partNum > (partRange.Last - partRange.First))
    {
        break;
    }
    if (index == partRange.Last)
    {
        receiveBuffer = new byte[fileToDownload.Length - index * BUFF_SIZE];
    }
}
Console.WriteLine();

我错过了什么?我甚至打印出了客户端和服务器上的缓冲区,它是相等的。

任何帮助都将不胜感激,谢谢。

尝试netStream.Flush();

我怀疑发生的事情是在写作结束之前流就被关闭了。有时输出流将继续异步写入。在处理文件流时也会发现这一点。使用Flush()强制流在继续执行之前完成它正在进行的任何写入操作。

output.Write(receiveBuffer, 0, receiveBuffer.Length);

需要

output.Write(receiveBuffer, 0, bytesReceived);

并不是每次调用netStream。Read都会填充receiveBuffer。

可能还有其他错误,但那是我突然想到的最大错误

编辑:看起来发送端有同样的错误,但你甚至没有保存输入的结果。读取(

更新:


没有大小限制,缓冲区是唯一的限制。在4.5.1中显示为81920字节。这里和下面提供了Stream.CopyTo的物理实现:

private void InternalCopyTo(Stream destination, int bufferSize)
{
     Contract.Requires(destination != null);
     Contract.Requires(CanRead);
     Contract.Requires(destination.CanWrite);
     Contract.Requires(bufferSize > 0);
     byte[] buffer = new byte[bufferSize];
     int read;
     while ((read = Read(buffer, 0, buffer.Length)) != 0)
          destination.Write(buffer, 0, read);
}

你可以让你的生活更轻松,只需做:

input.CopyTo(output);

这是快速复制数据的快捷方式。复制从当前流中的当前位置开始,并且在复制操作完成后不会重置目标流的位置。

using(MemoryStream destination = new MemoryStream())
     using(FileStream source = File.Open("..."))
     {
          source.CopyTo(destination);
     }

你可以很容易地制作一种方法,使用这种方法:

public static MemoryStream GetStream(this FileStream source)
{
     using(MemoryStream stream = new MemoryStream())
     {
          source.CopyTo(stream);
          return stream;
     }
}

您可能想要错误处理,但正如您所看到的,在流之间复制数据时,这种方法非常灵活。应该能够使这种方法适应您的特定开发需求。您可以在此处找到有关该方法的Microsoft开发人员网络的详细信息。

相关内容

  • 没有找到相关文章

最新更新