C# 如何在不将整个文件加载到内存的情况下读取/传输文件?

C# 如何在不将整个文件加载到内存的情况下读取/传输文件?,c#,file,hash,md5,md5-file,C#,File,Hash,Md5,Md5 File,如何在不将整个文件加载到内存中的情况下,读取任意文件并“逐块”处理它(意味着逐字节或提供最佳读取性能的其他块大小)?处理的一个例子是生成文件的MD5哈希,尽管答案可以应用于任何操作 我希望有或写这个,但如果我可以得到现有的代码,这将是伟大的太 (c#)System.IO.FileStream不会将文件加载到内存中。 此流是可查找的,MD5哈希算法也不必加载流(文件)的介绍内存 请用文件路径替换文件路径 byte[] hash = null; using (var stream = new Fi

如何在不将整个文件加载到内存中的情况下,读取任意文件并“逐块”处理它(意味着逐字节或提供最佳读取性能的其他块大小)?处理的一个例子是生成文件的MD5哈希,尽管答案可以应用于任何操作

我希望有或写这个,但如果我可以得到现有的代码,这将是伟大的太


(c#)

System.IO.FileStream不会将文件加载到内存中。
此流是可查找的,MD5哈希算法也不必加载流(文件)的介绍内存

请用文件路径替换
文件路径

byte[] hash = null;

using (var stream = new FileStream(file_path, FileMode.Open))
{
    using (var md5 = new System.Security.Cryptography.MD5CryptoServiceProvider())
    {
        hash = md5.ComputeHash(stream);
    }
}

这里,您的MD5哈希将存储在
Hash
变量中。

下面是一个示例,说明如何在不将整个内容加载到内存的情况下读取1KB的文件:

const int chunkSize = 1024; // read the file by chunks of 1KB
using (var file = File.OpenRead("foo.dat"))
{
    int bytesRead;
    var buffer = new byte[chunkSize];
    while ((bytesRead = file.Read(buffer, 0, buffer.Length)) > 0)
    {
        // TODO: Process bytesRead number of bytes from the buffer
        // not the entire buffer as the size of the buffer is 1KB
        // whereas the actual number of bytes that are read are 
        // stored in the bytesRead integer.
    }
}
int-fullfilesize=0;//文件的完整大小
int DefaultReadValue=10485760//每次读取10MB
int toRead=10485760;
int位置=0;
//int
//byte[]ByteReadFirst=新字节[10485760];
私有无效按钮\u单击(对象发送者,路由目标e)
{
使用(var fs=new FileStream(@“filepath”、FileMode.Open、FileAccess.Read))
{
使用(MemoryStream requestStream=new MemoryStream())
{
fs.位置=位置;
如果(fs.Position>=fullfilesize)
{
MessageBox.Show(“全部完成”);
返回;
}
System.Diagnostics.Debug.WriteLine(“文件位置”+fs.position);
如果(完整文件大小位置<读取)
{
toRead=fullfilesize-position;
MessageBox.Show(“上次”);
}
系统.Diagnostics.Debug.WriteLine(“toread”+toread);
int字节读取;
字节[]缓冲区=新字节[toRead];
整数偏移=0;
位置+=探路者;
而(toRead>0&(bytesRead=fs.Read(缓冲区、偏移量、toRead))>0)
{
探路者-=字节阅读;
偏移量+=字节读取;
}
toRead=DefaultReadValue;
}
}
}
复制Darin的,此方法将读取10mb的块,直到文件结束

const long numberOfBytesToReadPerChunk = 1000;//1KB
using (BinaryReader fileData = new BinaryReader(File.OpenRead(aFullFilePath))
    while (fileData.BaseStream.Position - fileData.BaseStream.Length > 0)
        DoSomethingWithAChunkOfBytes(fileData.ReadBytes(numberOfBytesToReadPerChunk));

据我所知,这里使用的函数(特别是
BinaryReader.ReadBytes
)不需要跟踪您读取了多少字节。您只需要知道while循环的长度和当前位置——流会告诉您

请澄清为什么此代码不能将文件完全读入内存。另外,请解释您的待办事项部分。这会将1KB(或chunkSize字节)加载到内存中。编辑:他的意思是不是整个
缓冲区都写了!只有从索引0到索引
bytesRead-1
@Darin的字节-忽略我在第一条评论中的问题。我看到这是文件的结果。读取时只读取字节块。@Darin我尝试了这段代码,但它没有正确读取最后一个字节块。如果最后一个块小于
chunkSize
@Mujeeb,它会在缓冲区中保留垃圾值。您需要读取
bytesRead
长度,而不是
buffer
的整个长度,例如
fsFileStream.Write(buffer,0,bytesRead)
看,真正的答案是“
System.IO.FileStream
不会将文件加载到内存中。”尽管示例中的MemoryStream不是必需的,但您是唯一发布示例并设置文件流位置的人。这解决了我的问题,我需要分割和传输10兆块大文件。向上投票!对于未来的堆栈器,您只需要一个using语句——如果我没记错的话,它们可以聚在一起。
   int fullfilesize = 0;// full size of file
    int DefaultReadValue = 10485760; //read 10 mb at a time
    int toRead = 10485760;
    int position =0;

  //  int 
 //   byte[] ByteReadFirst = new byte[10485760];

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        using (var fs = new FileStream(@"filepath", FileMode.Open, FileAccess.Read))
        {
            using (MemoryStream requestStream = new MemoryStream())
            {


                fs.Position = position;

                if (fs.Position >= fullfilesize)
                {
                    MessageBox.Show(" all done");
                    return;
                }
                System.Diagnostics.Debug.WriteLine("file position" + fs.Position);

                if (fullfilesize-position < toRead)
                {
                    toRead = fullfilesize - position;
                    MessageBox.Show("last time");
                }
                System.Diagnostics.Debug.WriteLine("toread" + toRead);
                int    bytesRead;
                byte[] buffer = new byte[toRead];
                int offset = 0;
                position += toRead;
                while (toRead > 0 && (bytesRead = fs.Read(buffer, offset, toRead)) > 0)
                {
                    toRead -= bytesRead;
                    offset += bytesRead;
                }

                toRead = DefaultReadValue;


            }
        }
    }
const long numberOfBytesToReadPerChunk = 1000;//1KB
using (BinaryReader fileData = new BinaryReader(File.OpenRead(aFullFilePath))
    while (fileData.BaseStream.Position - fileData.BaseStream.Length > 0)
        DoSomethingWithAChunkOfBytes(fileData.ReadBytes(numberOfBytesToReadPerChunk));