如何在c#中将大文件拆分成块?

我正在通过电线制作一个简单的文件传输发送器和接收器应用程序。 到目前为止,我发送的是发送方将文件转换为字节数组,并将该数组的块发送给接收方。

这适用于高达256mb文件,但上面的任何内容,行:

 byte[] buffer = StreamFile(fileName); //This is where I convert the file Throws a System out of memory exception. 

我正在寻找一种方法来读取块中的文件然后写入该块而不是将整个文件加载到一个byte 。 我怎么能用FileStream做到这一点?

编辑:

对不起,到目前为止,这是我糟糕的代码:

  private void btnSend(object sender, EventArgs e) { Socket clientSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); byte[] fileName = Encoding.UTF8.GetBytes(fName); //file name byte[] fileData = null; try { fileData = StreamFile(textBox1.Text); //file } catch (OutOfMemoryException ex) { MessageBox.Show("Out of memory"); return; } byte[] fileNameLen = BitConverter.GetBytes(fileName.Length); //length of file name clientData = new byte[4 + fileName.Length + fileData.Length]; fileNameLen.CopyTo(clientData, 0); fileName.CopyTo(clientData, 4); fileData.CopyTo(clientData, 4 + fileName.Length); clientSock.Connect("172.16.12.91", 9050); clientSock.Send(clientData, 0, 4 + fileName.Length, SocketFlags.None); for (int i = 4 + fileName.Length; i < clientData.Length; i++) { clientSock.Send(clientData, i, 1 , SocketFlags.None); } clientSock.Close(); } 

这是我收到的方式(代码来自教程)

  public void ReadCallback(IAsyncResult ar) { int fileNameLen = 1; String content = String.Empty; StateObject state = (StateObject)ar.AsyncState; Socket handler = state.workSocket; int bytesRead = handler.EndReceive(ar); if (bytesRead > 0) { if (flag == 0) { Thread.Sleep(1000); fileNameLen = BitConverter.ToInt32(state.buffer, 0); string fileName = Encoding.UTF8.GetString(state.buffer, 4, fileNameLen); receivedPath = fileName; flag++; } if (flag >= 1) { BinaryWriter writer = new BinaryWriter(File.Open(receivedPath, FileMode.Append)); if (flag == 1) { writer.Write(state.buffer, 4 + fileNameLen, bytesRead - (4 + fileNameLen)); flag++; } else writer.Write(state.buffer, 0, bytesRead); writer.Close(); handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state); } } else { Invoke(new MyDelegate(LabelWriter)); } } 

我真的想知道如何以块的forms读取文件,以便我不需要将其转换为字节。

感谢到目前为止的回复,我想我已经开始明白:D

只需用一个小缓冲区重复调用Read (我倾向于使用像16K这样的东西)。 请注意,对Read的调用最终可能会读取比您请求的数量更少的数量。 如果你使用固定的块大小并且需要内存中的整个块,那么你当然可以使用那个大小的数组。

在不知道你如何发送文件的情况下,很难就如何构造代码提出很多建议,但它可能是这样的:

 byte[] chunk = new byte[MaxChunkSize]; while (true) { int index = 0; // There are various different ways of structuring this bit of code. // Fundamentally we're trying to keep reading in to our chunk until // either we reach the end of the stream, or we've read everything we need. while (index < chunk.Length) { int bytesRead = stream.Read(chunk, index, chunk.Length - index); if (bytesRead == 0) { break; } index += bytesRead; } if (index != 0) // Our previous chunk may have been the last one { SendChunk(chunk, index); // index is the number of bytes in the chunk } if (index != chunk.Length) // We didn't read a full chunk: we're done { return; } } 

如果我更清醒的话,我可能会找到一种更易读的写作方式,但现在就可以了。 一种选择是从中间部分提取另一种方法:

 // Attempts to read an entire chunk into the given array; returns the size of // chunk actually read. int ReadChunk(Stream stream, byte[] chunk) { int index = 0; while (index < chunk.Length) { int bytesRead = stream.Read(chunk, index, chunk.Length - index); if (bytesRead == 0) { break; } index += bytesRead; } return index; } 
 var b = new byte[1<<15]; // 32k while((count = inStream.Read(b, 0, b.Length)) > 0) { outStream.Write(b, 0, count); } 

你有没有看过WCF流​​媒体? 以下是MSDN上的一篇很好的文章,它描述了WCF对Stream数据流的function。

大数据和流媒体