Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/277.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将文件分块_C#_Tcp - Fatal编程技术网

C# 将文件分块

C# 将文件分块,c#,tcp,C#,Tcp,我有一个学校作业,我必须制作一个程序,将不同的文件切成块(txt文件、图像…),然后通过tcp客户端发送,最后将它们连接回文件并保存。 我在互联网上找到了一个解决方案,但它并没有发送所有的文件,但最后还是少了一点。 我找不到问题。有人能帮忙吗 剪切文件的代码: const int chunkSize = 1024; //1KB chunks int counter = 0; using (var file = File.OpenRead(filePath))

我有一个学校作业,我必须制作一个程序,将不同的文件切成块(txt文件、图像…),然后通过tcp客户端发送,最后将它们连接回文件并保存。 我在互联网上找到了一个解决方案,但它并没有发送所有的文件,但最后还是少了一点。 我找不到问题。有人能帮忙吗

剪切文件的代码:

      const int chunkSize = 1024; //1KB chunks
      int counter = 0;

      using (var file = File.OpenRead(filePath)) {
          int bytesRead;
          var buffer = new byte[chunkSize];
          while ((bytesRead = file.Read(buffer, 0, buffer.Length)) > 0) {
               Send(ns, buffer);
          }
      }
long chunkSize=1024;
长sentBytes=0;
byte[]fileBytes=File.ReadAllBytes();
byte[]fileChunk=新字节[1024];
long fileLen=fileBytes.Length;
While(sentBytesfileLen)
chunkSize=fileLen-sentBytes;
复制(fileBytes,sentBytes,fileChunk,sentBytes,chunkSize);
sentBytes+=块大小;
//在这里发送文件块
}

免责声明:未测试

代码中存在错误

为了举例说明,假设您要发送一个块长度为10的文件,其内容如下:

 abcdefghijklmnopqrstuvwxyz
(为了便于说明,假设每个字符为1字节。)

第一次调用
file.Read(buffer,0,buffer.Length)
可以填充缓冲区。调用将返回复制到缓冲区的字节数。由于可用字符数超过了缓冲区长度,
file.Read
会将接下来的10个字节写入
buffer
并返回10:

buffer (before call): 0000000000 (where 0 represents \0)
buffer (after call):  abcdefghij
return value of File.read: 10
类似地,对
file.Read的第二次调用可以用接下来的10个字节填充缓冲区:

buffer (before call):  abcdefghij
buffer (after call) : klmnopqrst
return value of File.read: 10
对于第三次调用,文件中只剩下6个字节。调用
file.Read
会将剩余的6个字节写入缓冲区,并返回6以指示只写入了6个字节。缓冲区的其余4个字节未写入并保留其以前的值:

buffer (before call) = klmnopqrst
buffer (after call)  = uvwxyzqrst
return value of File.read: 6
由于
Send
发送整个缓冲区,因此
buffer
的以下值作为参数提供给
Send

abcdefghij
klmnopqrst
uvwxyzqrst
您可能想要的是:

abcdefghik
klmnopqrst
uvwxyz
那么你如何解决这个问题呢

传统的方法是将
bytesRead
作为参数传递给
Send
方法。您的
Send
方法需要忽略(即不传输)
buffer
过去出现的
bytesRead
内容

  using (var file = File.OpenRead(filePath)) {
      int bytesRead;
      var buffer = new byte[chunkSize];
      while ((bytesRead = file.Read(buffer, 0, buffer.Length)) > 0) {
           Send(ns, buffer, bytesRead);
      }
或者,在缓冲区未填满的情况下,您可以将较小的缓冲区作为参数发送到
send

  using (var file = File.OpenRead(filePath)) {
      int bytesRead;
      var buffer = new byte[chunkSize];
      while ((bytesRead = file.Read(buffer, 0, buffer.Length)) > 0) {
           if (bytesRead < buffer.Length)
           {
               var smallBuffer = new byte[bytesRead];
               Array.Copy(buffer, 0, smallBuffer, 0, bytesRead);
               Send(ns, smallBuffer);
           }
           else
           {
               Send(ns, buffer);
           }
      }
使用(var file=file.OpenRead(filePath)){
int字节读取;
var buffer=新字节[chunkSize];
而((bytesRead=file.Read(buffer,0,buffer.Length))>0){
if(字节读取<缓冲区长度)
{
var smallBuffer=新字节[bytesRead];
复制(buffer,0,smallBuffer,0,bytesRead);
发送(ns,smallBuffer);
}
其他的
{
发送(ns,缓冲区);
}
}

看起来这段代码发送的字节比源文件包含的字节要多,因为您总是发送完整的
缓冲区
,即使最后读取的块实际上小于
chunksize
字节。这是编程中最有用的技能之一。
  using (var file = File.OpenRead(filePath)) {
      int bytesRead;
      var buffer = new byte[chunkSize];
      while ((bytesRead = file.Read(buffer, 0, buffer.Length)) > 0) {
           if (bytesRead < buffer.Length)
           {
               var smallBuffer = new byte[bytesRead];
               Array.Copy(buffer, 0, smallBuffer, 0, bytesRead);
               Send(ns, smallBuffer);
           }
           else
           {
               Send(ns, buffer);
           }
      }