Чтение двоичных данных

Я пытаюсь прочитать данные из двоичного файла. Один блок данных имеет длину 76 байтов (это зависит от количества 2-байтовых "основных элементов данных" в середине блока). Первые данные составляют 4 байта, вторые - 4 байта, затем идет группа из 2-х байтовых элементов основных данных, а в конце - еще 2 2-байтовых фрагмента данных.

Основываясь на этом примере Delphi, я научился читать файл с приведенным ниже кодом:

short AShortInt; // 16 bits
int AInteger; // 32 bits
try
{
 infile=new TFileStream(myfile,fmOpenRead); // myfile is binary
 BR = new TBinaryReader(infile, TEncoding::Unicode, false);
 for (int rows = 0; rows < 5; rows++) {  // just read the first 5 blocks of data for testing
  AInteger = BR->ReadInt32(); // read first two 4 byte integers for this block
  AInteger = BR->ReadInt32();
  for (int i = 0; i < 32; i++) { // now read the 32 2-byte integers from this block
   AShortInt = BR->ReadInt16();
  }
  AShortInt = BR->ReadInt16(); // read next to last 2-byte int
  AShortInt = BR->ReadInt16(); // read the last 2-byte int
}
delete infile;
delete BR;
Close();
}
catch(...)
{
 delete infile;  // closes the file, doesn't delete it.
 delete BR;
 ShowMessage("Can't open file!");
 Close();
}

Но я бы хотел использовать буфер шириной 76 байт для чтения всего блока, а затем выбрать различные данные из этого буфера. Я собрал следующий код на основе этого вопроса, и я могу прочитать весь блок данных в буфер.

UnicodeString myfile = System::Ioutils::TPath::Combine(System::Ioutils::TPath::GetDocumentsPath(), "binaryCOM.dat");
TFileStream*infile=0;
try
{
 infile=new TFileStream(myfile,fmOpenRead);
 const int bufsize=76;
 char*buf=new char[bufsize];
 int a = 0;
 while(int bytesread=infile->Read(buf,bufsize)) {
   a++; // just a place to break on Run to Cursor
 }
 delete[]buf;
}
catch(...)
{
  delete infile;  
  ShowMessage("Can't open file!");
  Close();
}

Но я не могу понять, как собрать подмножества из байтов в буфере. Есть ли способ объединить байты? Значит, я мог прочитать блок данных в 76-байтовый буфер, а затем сделать что-то вроде этого ниже?

unsigned int FirstDatum = buf[0]+buf[1]+buf[2]+buf[3];  // concatenate the 4 bytes for the first piece of data

Это будет приложение FMX для Win32, iOS и Android, созданное в C++Builder 10.3.2.

1 ответ

Решение

Вот мой модифицированный код с использованием предложения Реми о TMemoryStream.

UnicodeString myfile = System::Ioutils::TPath::Combine(System::Ioutils::TPath::GetDocumentsPath(), "binaryCOM.dat");

TMemoryStream *MS=0;
TBinaryReader *BR=0;
std::vector<short> myArray;
short AShortInt;
int AInteger;
int NumDatums = 32; // the variable number of 2-byte main datums

try
{
  MS = new TMemoryStream();
  MS->LoadFromFile(myfile);
  BR = new TBinaryReader(MS, TEncoding::Unicode, false);
  for (int rows = 0; rows < 5; rows++) {  // testing with first 5 blocks of data
    AInteger = BR->ReadInt32(); // read first two 4 byte integers
    AInteger = BR->ReadInt32(); // here
    for (int i = 0; i < NumDatums; i++) {  // read the main 2-byte data
      AShortInt = BR->ReadInt16();
      myArray.push_back(AShortInt); // push it into vector
    }
    AShortInt = BR->ReadInt16(); // read next to last 2-byte int
    AShortInt = BR->ReadInt16(); // read the last 2-byte int
    // code here to do something with this block of data just read from file
  }
}
delete MS;
delete BR;
}
catch(...)
{
 delete MS;  
 delete BR;
 ShowMessage("Can't open file.");
}
Другие вопросы по тегам