我正在创建一个通过TCP传输文件的程序。现在,每次我最后转移一个文件时,似乎都没有写入,所以如果我尝试传输图片at the bottom right there are glitches。 现在,我的第一个想法是,当我读取,传输和写入比缓冲区长度更小的最终块时,我也写了很多零。所以我试着相应地改变最后的缓冲区大小。然后我尝试使用一个只写有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();
我错过了什么?我甚至在客户端和服务器上打印出缓冲区,它是平等的。
任何帮助都将不胜感激,谢谢。
答案 0 :(得分:1)
尝试netStream.Flush();
我怀疑在写完成之前,流正在关闭。有时输出流将继续异步写入。在处理文件流时,您也会发现这一点。在继续执行之前,使用Flush()
强制流完成它正在执行的任何写操作。
答案 1 :(得分:0)
output.Write(receiveBuffer, 0, receiveBuffer.Length);
需要
output.Write(receiveBuffer, 0, bytesReceived);
并非每次调用netStream.Read都会填充receiveBuffer。
可能还有其他错误,但那是一个突然出现在我身上的错误。
编辑:看起来发送方有相同的错误,但你甚至没有保存input.Read(
的结果答案 2 :(得分:0)
<强>更新强>
没有大小限制,缓冲区是唯一的限制。其中4.5.1似乎是81920字节。 Stream.CopyTo
的实际实施是here及以下:
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;
}
}
您需要进行错误处理,但正如您所看到的,在Streams之间复制数据时,此方法非常灵活。应该能够根据您的具体开发需求改变这种方法。您可以在Microsoft Developer Network上找到有关方法here的更多信息。