【发布时间】:2013-02-14 18:48:23
【问题描述】:
我正在向一些遗留代码添加一些新功能。现有代码从文本文件中读取一些数据。在新版本中,我将读取更多数据并希望使用二进制文件,除此之外,该程序可以在 Linux 或 Windows 上使用相同的(外部)数据文件,所以我想强制执行读取二进制数据时的大端意义。
为此,我创建了一个新的输入文件流类型 - 从 ifstream 继承 - 使用重载的“>>”运算符从文件中读取二进制数据,并将其解释为大端。到目前为止一切顺利。
现在,当我从文件中读取数据时,我需要选择要创建哪种类型的输入文件流对象:处理旧文本文件时的常规 ifstream 或处理新文本文件时的新“iBinFile”类型二进制文件。我能想到的唯一解决方案是使用两段不同的代码,一段用于旧类型,另一段用于新类型,除了输入文件流类型之外,它们是相同的:
if (szFileName.compare(szFileName.size()-3,3,"bin")==0) {
iBinFile inFile(szFileName.c_str());
if (!inFile) {
cout << szFileName <<" file could not be opened" << endl;
exit (-1);
}
while(!inFile.eof())
inFile >> data;
}
else {
ifstream inFile(szFileName.c_str());
if (!inFile) {
cout << szFileName <<" file could not be opened" << endl;
exit (-1);
}
while(!inFile.eof())
inFile >> data;
}
但我觉得因为 iBinFile 是从 ifstream 派生的,所以应该有一种方法可以做到这一点,其中 if 语句仅确定文件类型,其他一切都是共同的。如果我从我自己的类派生 iBinFile,那么我可以将“>>”运算符设为虚拟,但由于不是,我不知道解决方案是什么,如果有的话。
【问题讨论】:
-
只有一件事,
while(!inFile.eof())是不可以的!请改用while(inFile >> data) { /* do stuff with data */}。 -
二进制文件不可移植。再次重申:二进制文件不可移植。如果你这样做,你会感到很头疼;字节序只是您必须处理的问题之一。您还必须为相同类型和值的不同二进制表示形式分类不同的大小。更不用说完全不习惯使用
>>,在正常使用中会进行格式化输入(即来自文本文件)。 -
@PeteBecker 二进制文件可以像文本文件一样便携。在这两种情况下,您都需要指定一种格式(或使用现有的格式,如 XDR 或 BER),然后写入和读取该格式。毕竟,许多可移植格式(例如 JPEG、MP3 等)是二进制的,我也在 IBM 大型机和 PC 之间以二进制进行通信(使用一种定义浮点的格式以 BCD 表示)。
-
@JamesKanze - 我坚持我所说的:除了字节顺序之外,您还必须处理相同类型的不同大小和值的不同二进制表示。将协议名称放在上面并不会改变根本问题。
-
@PeteBecker 您必须以 yoru 二进制格式定义类型的表示,是的。而且您必须确保您的写入和读取函数符合您定义的格式。但是,这可以便携式完成; BER 和 XDR 都很普遍,BER 经常用于在架构完全不同的处理器之间进行通信。
标签: c++ inheritance file-io operator-overloading