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

前端之家收集整理的这篇文章主要介绍了如何在c#中将大文件分割成块?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我通过电线制作一个简单的文件传输发送方和接收方应用程序.我到目前为止,发送方将文件转换为字节数组,并将该数组的块发送到接收器.

这个文件最多可以达到256mb,但上面的任何一行都是这样的:

byte[] buffer = StreamFile(fileName); //This is where I convert the file

Throws a System out of memory exception.

我正在寻找一种方式来读取文件中的块,然后写入该块,而不是将整个文件加载到一个字节.我如何使用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,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,bytesRead);
                        writer.Close();
                        handler.BeginReceive(state.buffer,StateObject.BufferSize,new AsyncCallback(ReadCallback),state);
                }
        }
        else
        {
            Invoke(new MyDelegate(LabelWriter));
        }

    }

我只是想知道如何以块的形式读取文件,以便我不需要将其转换为一个字节.

感谢您的答复,我想我开始得到它:D

解决方法

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

不知道如何发送文件,很难给出关于如何构建代码的很多建议,但它可能是这样的:

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,chunk.Length - index);
        if (bytesRead == 0)
        {
            break;
        }
        index += bytesRead;
    }
    return index;
}

猜你在找的C#相关文章