C#FileStream.Read不读取最后一个块

时间:2018-04-25 03:01:45

标签: c# filestream

我将二进制文件逐个块地读取。

当我使用FileStream.Read和File.ReadAllBytes

时,这是不同的
  1. FileSteram.Read

    int limit = 0;
    if (openFileDlg.FileName.Length > 0)
    {
        fileName = openFileDlg.FileName;
        FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
        fsLen = (int)fs.Length;
        int count = 0;
        limit = 100;
        byte[] read_buff = new byte[limit];
        StringBuilder sb = new StringBuilder();
        while ( (count = fs.Read(read_buff, 0, limit)) > 0)
        {
             foreach (byte b in read_buff)
             {
                sb.Append(Convert.ToString(b, 16).PadLeft(2, '0'));
             }
    
        }
        rtxb_bin.AppendText(sb.ToString() + "\n");
    }
    
  2. File.ReadAllBytes

    if (openFileDlg.FileName.Length > 0)
    {
            fileName = openFileDlg.FileName;
            byte[] fileBytes = File.ReadAllBytes(fileName);
            StringBuilder sb2 = new StringBuilder();
    
            foreach (byte b2 in fileBytes)
            {
                sb2.Append(Convert.ToString(b2, 16).PadLeft(2, '0'));
            }
            rtxb_allbin.AppendText(sb2.ToString());
     }
    
  3. 案例1,reasult是......

        ........04c0020f00452a00421346108129844f2138448500208020250405250043188510812e0
    

    和案例2是

          .......04c0020f00452a00421346108129844f2138448500208020250405250043188510812e044f212cc48120c24125404f2069c2c0008bff35f8f401efbd17047
    

    FileStream.Read在'12e0'之后不读 '44f212cc48120c24125404f2069c2c0008bff35f8f401efbd17047'缺失

    如何使用FileStream.Read读取所有字节?

    为什么FileStream.Read不读取最后一个块?

3 个答案:

答案 0 :(得分:3)

很可能出现给你,它不会读取最后一个块。假设你有长度为102的文件。你循环的第一次迭代读取前100个字节,一切都很好。但是第二个(最后一个)会发生什么?您将两个字节读入read_buff,其长度为100.现在该缓冲区包含最后一个块的2个字节和前一个(第一个)块的98个字节,因为Read不清除缓冲区。然后继续:

 foreach (byte b in read_buff)
 {
    sb.Append(Convert.ToString(b, 16).PadLeft(2, '0'));
 }

结果,sb有100个字节的第一个块,2个字节的最后一个块,然后是98个字节的第一个块。如果你看起来不太近,可能看起来它只是跳过最后一个块,而实际上它是前一个块的重复部分。

要修复,请使用count(表示实际读入缓冲区的字节数)仅适用于read_buff的有效部分:

for (int i = 0; i < count; i++) {
    sb.Append(Convert.ToString(read_buff[i], 16).PadLeft(2, '0'));
}

答案 1 :(得分:0)

您需要更新偏移和计数。

  

Sintaxis

public override int Read(
    byte[] array,
    int offset,
    int count
)
  

实施例

public static byte[] ReadFile(string filePath)
{
  byte[] buffer;
  FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
  try
  {
    int length = (int)fileStream.Length;  // get file length
    buffer = new byte[length];            // create buffer
    int count;                            // actual number of bytes read
    int sum = 0;                          // total number of bytes read

    // read until Read method returns 0 (end of the stream has been reached)
    while ((count = fileStream.Read(buffer, sum, length - sum)) > 0)
      sum += count;  // sum is a buffer offset for next reading
  }
  finally
  {
    fileStream.Close();
  }
  return buffer;
}

Reference

答案 2 :(得分:0)

   public static void ReadAndProcessLargeFile(string theFilename, long whereToStartReading = 0)
    {
        FileInfo info = new FileInfo(theFilename);
        long fileLength = info.Length;
        long timesToRead = (fileLength / megabyte);
        long ctr = 0;
        long timesRead = 0;

        FileStream fileStram = new FileStream(theFilename, FileMode.Open, FileAccess.Read);
        using (fileStram)
        {
            byte[] buffer = new byte[megabyte];

            fileStram.Seek(whereToStartReading, SeekOrigin.Begin);

            int bytesRead = 0;
            
            //bytesRead = fileStram.Read(buffer, 0, megabyte);
            //ctr = ctr + 1;

            while ((bytesRead = fileStram.Read(buffer, 0, megabyte)) > 0)
            {
                ProcessChunk(buffer, bytesRead);
                buffer = new byte[megabyte]; // This solves last read prob
            }

        }
    }

    private static void ProcessChunk(byte[] buffer, int bytesRead)
    {
        // Do the processing here
        string utfString = Encoding.UTF8.GetString(buffer, 0, buffer.Length);
        Console.Write(utfString);
    }