C # FileStream.Read не читает последний блок - PullRequest
0 голосов
/ 25 апреля 2018

Я читаю двоичный файл в шестнадцатеричный формат по блокам.

Это разные, когда я использую 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());
     }
    

вариант 1, результат ... ... 1017 *

    ........04c0020f00452a00421346108129844f2138448500208020250405250043188510812e0

и вариант 2:

      .......04c0020f00452a00421346108129844f2138448500208020250405250043188510812e044f212cc48120c24125404f2069c2c0008bff35f8f401efbd17047

FileStream.Read не читает после '12e0' 44f212cc48120c24125404f2069c2c0008bff35f8f401efbd17047 'отсутствует

Как я могу прочитать все байты с помощью FileStream.Read?*1025St * 1026.Читать не читает последний блок?

Ответы [ 2 ]

0 голосов
/ 25 апреля 2018

Скорее всего вам покажется , что он не читает последний блок.Предположим, у вас есть файл длиной 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'));
}
0 голосов
/ 25 апреля 2018

Вам необходимо обновить смещение и счет.

Синтаксис

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

Ссылка

...