Firemonkey 读取二进制数据

Firemonkey 读取二进制数据,firemonkey,c++builder,c++builder-10.3-rio,Firemonkey,C++builder,C++builder 10.3 Rio,我试图从二进制文件中读取数据。一块数据是76字节长的(这与块中间的2字节的“主数据项”的数目不同)。第一个数据是4字节,第二个是4字节,然后是一堆2字节的主数据项,最后是另外2个2字节的数据段 基于此,我学习了如何使用以下代码读取文件: short AShortInt; // 16 bits int AInteger; // 32 bits try { infile=new TFileStream(myfile,fmOpenRead); // myfile is binary BR = n

我试图从二进制文件中读取数据。一块数据是76字节长的(这与块中间的2字节的“主数据项”的数目不同)。第一个数据是4字节,第二个是4字节,然后是一堆2字节的主数据项,最后是另外2个2字节的数据段

基于此,我学习了如何使用以下代码读取文件:

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字节的缓冲区,然后像下面这样做

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

这将是一款适用于Win32、iOS和Android的FMX应用程序,内置于C++Builder 10.3.2中。

这是我使用Remy建议的
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.");
}
UnicodeString myfile=System::Ioutils::TPath::Combine(System::Ioutils::TPath::GetDocumentsPath(),“binaryCOM.dat”);
TMemoryStream*MS=0;
TBinaryReader*BR=0;
std::向量数组;
短小的;
国际画家;
int NumDatums=32;//2字节主基准的可变数量
尝试
{
MS=新的TMemoryStream();
MS->LoadFromFile(myfile);
BR=新的TBinaryReader(MS,TEncoding::Unicode,false);
对于(int rows=0;rows<5;rows++){//使用前5个数据块进行测试
AInteger=BR->ReadInt32();//读取前两个4字节整数
AInteger=BR->ReadInt32();//此处
对于(inti=0;iReadInt16();
myArray.push_back(AShortInt);//将其推入向量
}
AShortInt=BR->ReadInt16();//读取最后一个2字节整数的旁边
AShortInt=BR->ReadInt16();//读取最后的2字节整数
//这里的代码用于处理从文件中读取的数据块
}
}
删除MS;
删除BR;
}
捕获(…)
{
删除MS;
删除BR;
ShowMessage(“无法打开文件”);
}

这是我使用雷米建议的
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.");
}
UnicodeString myfile=System::Ioutils::TPath::Combine(System::Ioutils::TPath::GetDocumentsPath(),“binaryCOM.dat”);
TMemoryStream*MS=0;
TBinaryReader*BR=0;
std::向量数组;
短小的;
国际画家;
int NumDatums=32;//2字节主基准的可变数量
尝试
{
MS=新的TMemoryStream();
MS->LoadFromFile(myfile);
BR=新的TBinaryReader(MS,TEncoding::Unicode,false);
对于(int rows=0;rows<5;rows++){//使用前5个数据块进行测试
AInteger=BR->ReadInt32();//读取前两个4字节整数
AInteger=BR->ReadInt32();//此处
对于(inti=0;iReadInt16();
myArray.push_back(AShortInt);//将其推入向量
}
AShortInt=BR->ReadInt16();//读取最后一个2字节整数的旁边
AShortInt=BR->ReadInt16();//读取最后的2字节整数
//这里的代码用于处理从文件中读取的数据块
}
}
删除MS;
删除BR;
}
捕获(…)
{
删除MS;
删除BR;
ShowMessage(“无法打开文件”);
}

声明一个记录结构,该结构包含您喜欢命名的整数和短整数。一次性读取此结构的一个实例的所有76个字节,然后在声明单个字段时使用其名称引用这些字段。(我只是不太确定你提到的平台的耐久性)谢谢汤姆。对不起,我忘了提到一个细节,在一个块的开始和结束之间会有一个可变数量的“2字节主数据项”。所以块并不总是76字节。有没有一种方法可以在运行时创建结构,以便它能够满足这种可变性的需要?您必须使用动态分配的数组将整数读入。也就是说,您仍然可以使用
TBinaryReader
读取单个整数,只需将一块数据读入
TMemoryStream
并将其用作读取器的输入数据,而不是
TFileStream
。感谢雷米,我在回答问题时发布了修改后的代码,以保持问题的清晰。这非常有效,因为可变长度的“主数据”总是2字节有符号短整数。请声明一个记录结构,该结构包含这些整数和短整数,并根据需要命名。一次性读取此结构的一个实例的所有76个字节,然后在声明单个字段时使用其名称引用这些字段。(我只是不太确定你提到的平台的耐久性)谢谢汤姆。对不起,我忘了提到一个细节,在一个块的开始和结束之间会有一个可变数量的“2字节主数据项”。所以块并不总是76字节。有没有一种方法可以在运行时创建结构,以便它能够满足这种可变性的需要?您必须使用动态分配的数组将整数读入。也就是说,您仍然可以使用
TBinaryReader
读取单个整数,只需将一块数据读入
TMemoryStream
并将其用作读取器的输入数据,而不是
TFileStream
。感谢雷米,我在回答问题时发布了修改后的代码,以保持问题的清晰。这非常有效,因为可变长度的“主数据”总是2字节有符号短整数。