如何在c#中将一个大文件分割成块?
我正在制作一个简单的文件传输发送者和接收者应用程序。到目前为止,我得到的是发送方将文件转换为字节数组,并将该数组的块发送给接收方 这适用于小于或等于256mb的文件,但这一行会引发“系统内存不足”异常,原因如下:如何在c#中将一个大文件分割成块?,c#,file,tcp,filestream,C#,File,Tcp,Filestream,我正在制作一个简单的文件传输发送者和接收者应用程序。到目前为止,我得到的是发送方将文件转换为字节数组,并将该数组的块发送给接收方 这适用于小于或等于256mb的文件,但这一行会引发“系统内存不足”异常,原因如下: byte[] buffer = StreamFile(fileName); //This is where I convert the file 我正在寻找一种方法,将文件分块读取,然后写入该块,而不是将整个文件加载到字节中。如何使用文件流 编辑: 对不起,这是我到目前为止的糟糕代码
byte[] buffer = StreamFile(fileName); //This is where I convert the file
我正在寻找一种方法,将文件分块读取,然后写入该块,而不是将整个文件加载到字节中。如何使用文件流
编辑:
对不起,这是我到目前为止的糟糕代码:
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();
}
我只是想知道我怎样才能把文件分块读,这样我就不需要把它转换成字节了
感谢到目前为止的回复,我想我开始明白了:D只要用一个小的缓冲区反复调用读取
(我倾向于使用类似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;
}
}
byte[]chunk=新字节[MaxChunkSize];
while(true)
{
int指数=0;
//有各种不同的方法来构造这段代码。
//从根本上说,我们一直在努力阅读,直到
//要么我们到达了终点,要么我们已经阅读了所有我们需要的东西。
while(索引
如果我更清醒的话,我可能会找到一种更具可读性的方式来写这篇文章,但现在就行了。一个选项是从中间部分提取另一种方法:
// 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;
}
//尝试将整个区块读入给定数组;返回的大小
//块实际读取。
int ReadChunk(流,字节[]块)
{
int指数=0;
while(索引
var b=new byte[1在StreamFile中找不到这样的方法,您能告诉我应该包括哪个库吗?
// 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);
}