【问题标题】:FStream reading a binary file written with Delphi's binary writerFStream 读取使用 Delphi 的二进制编写器编写的二进制文件
【发布时间】:2012-10-18 14:27:52
【问题描述】:

我在 MS Visual Studio 2010 Express 中创建了一个 dll,它使用 C++ 中的 fstream 库加载二进制数据文件(*.mgr 扩展名 -> 专门用于我公司的应用程序)。该文件是使用我公司中使用 Delphi 的其他人开发的应用程序创建的。他说前 15 个字节应该是一些字符,表明文件的创建日期和其他一些东西,比如应用程序的版本:

“XXXX 2012”。

用fstream(二进制模式)加载,用fstream(字符串模式)写入另一个文件后的结果如下:

"[] X X X X 2 0 1 2"

第一个字符是未知字符(矩形),然后每个字符之间有空格。最后它是 31 字节宽。实际字符为 15 + 空格为 15 + 矩形字符为 1 = 31。

其他一些信息: 我正在使用 C++,应用程序开发人员正在使用 Delphi。 我正在使用 fstream。他正在使用 BW.Write() 函数。 (BW == 二进制写入器?) 他使用的是 Windows 7,而我使用的是 Windows XP Professional。

你能对问题做出诊断吗?

提前致谢

第一次编辑:我正在添加加载这些第一个字节的 c++ 代码。

首先他使用的是来自 embarcadero Rad Studio XE2 的 Delphi XE2。

据我所知,PChar 是一个以空字符结尾的字符串,由宽字符(自 delphi 2009 起)组成,宽字符为 2 个字节,而不是普通字符(一个字节)。所以基本上他是在保存单词而不是字节。

这是加载经理的代码:

wchar_t header[15];
DXFLIBRARY_API void loadMGR(const char* szFileName, const char* szOutput)
{
fstream file;
file.open( szFileName, ios::binary | ios::in );
if(file.is_open()) 
{
    file.read(reinterpret_cast<char*>(header),sizeof(header));
}
file.close();

//zapis

fstream saveFile;
saveFile.open( szOutput, ios::out );
if(saveFile.is_open())
{
    saveFile.write(reinterpret_cast<const char*>(header),sizeof(header));
}
saveFile.close(); 
}

Header 包含 15 个 wchar_t,所以我们得到 30 个字节。在调查之后我仍然不知道如何转换。

【问题讨论】:

  • 欢迎来到 Stack Overflow。一句友好的忠告。像这样的问题得益于包含代码。您读取文件并写入文本流的代码会有所帮助。更重要的是,Delphi 版本很重要。有两个 Delphi 分裂,pre-Unicode 和 post-Unicode。您的同事使用的是哪个版本?

标签: c++ delphi delphi-xe2


【解决方案1】:

似乎很清楚,在某个地方,数据在 8 位文本编码和 16 位编码之间被破坏了。虚假的第一个字符几乎可以肯定是 UTF-16 BOM。

一种可能的解释是 Delphi 开发人员正在将 UTF-16 编码文本写入文件。并且大概您期望 8 位编码。

另一种解释是,Delphi 代码正确地写出 8 位文本,但您的代码正在破坏它。也许您的读/写代码正在这样做。

在 Delphi 程序的文件输出上使用十六进制编辑器来缩小发生损坏的确切位置。

在问题中没有任何代码的情况下,很难比这更具体。

【讨论】:

  • 开发人员可能已从早期版本升级到 D2009+,因此他的字符串 Ansi 现在是 Unicode。他最有可能应该专门使用 AnsiString 或 ShortString。 (并且在字符串中保存应该是字节的内容也有点狡猾,但这是另一回事......)
  • @DavidM 它实际上看起来像文本而不是字节。这可能都是 AnsiString 会很好。
  • 很遗憾他不在这里,但我偷偷进入他的电脑并提取了这行:BW.Write(PChar('MG-XXX-XXX-2012'));什么是Pchar?我的第一个猜测是它是一个 c 字符串等价物(指向 char 表的指针?)
  • PCharchar*wchar_t* 取决于 Delphi 版本。 2009 及更高版本使用宽 UTF-16 作为本机编码。
  • 好吧,如果 Delphi dev 使用 XE2,那么 PChar('MG-XXX-XXX-2012') 是 UTF-16 编码的。当然,您的 C++ 代码读取和写入 30 个字节而不是 15 个字节。因此,似乎没有任何代码仅适用于 15 个 8 位编码字符!
猜你喜欢
  • 2019-03-27
  • 1970-01-01
  • 2010-12-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-07
相关资源
最近更新 更多