Como posso ler / transmitir um arquivo sem carregar o arquivo inteiro na memory?

Como posso ler um arquivo arbitrário e processá-lo “peça por peça” (significando byte por byte ou algum outro tamanho de bloco que daria o melhor desempenho de leitura) sem carregar o arquivo inteiro na memory? Um exemplo de processamento seria gerar um hash MD5 do arquivo, embora a resposta possa se aplicar a qualquer operação.

Eu gostaria de ter ou escrever isso, mas se eu conseguir o código existente, seria ótimo também.

(c #)

Aqui está um exemplo de como ler um arquivo em pedaços de 1 KB sem carregar todo o conteúdo na memory:

 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. } } 

System.IO.FileStream não carrega o arquivo na memory.
Esse stream é procurado e o algoritmo de hash MD5 não precisa carregar o stream (arquivo) da memory de input.

Por favor substitua file_path pelo caminho para o seu arquivo.

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

Aqui, seu Hash MD5 será armazenado na variável hash .

  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; } } } 

Copiando Darin’s, este método irá ler 10mb pedaços até o final do arquivo

 const int MAX_BUFFER = 1024; byte[] Buffer = new byte[MAX_BUFFER]; int BytesRead; using (System.IO.FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read)) while ((BytesRead = fileStream.Read(Buffer, 0, MAX_BUFFER)) != 0) { // Process this chunk starting from offset 0 // and continuing for bytesRead bytes! } 
 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)); 

Pelo que entendi as funções usadas aqui (especificamente BinaryReader.ReadBytes ), não há necessidade de controlar quantos bytes você leu. Você só precisa saber o comprimento e a posição atual do loop while – que o stream informa.