我正在编写一个Photoshop PSD文件解析器来提取一些特定的元数据。跳过可能的大块无关数据表明一些随机访问。我需要支持PSB以及PSD - PSB具有相同的基本文件结构,但具有更大的限制,并且有一些大小字段为64位。
公开提供Photoshop file format specs.,这应该是一项微不足道的工作,但我以前从不需要担心大文件,至少在使用ifstream
时。我总是忽略streampos
等而只是使用size_t
来获取文件位置和偏移量。我现在还没有逃避。
我并不认为这是一个大问题,但事实并非如此,但结果却变得尴尬和混乱 - 我认为这意味着我正在与图书馆作斗争而不是按照预期行事。< / p>
第一期 - 有三种位置/偏移/尺寸类型......
streampos
streamoff
streamsize
这对我来说似乎没用。文件中的位置是从开始的偏移量。文件的大小也是从开始到结束的偏移量。这就是我们在vector
中使用相同类型size_t
指定位置,偏移和尺寸的原因。
事实上,我发现确定文件大小的最简单方法是streampos
- 寻找文件的末尾并查询位置......
myfile.seekg (0, ios::end);
streampos myfilesize = myfile.tellg ();
streampos
类型也是模板类fpos
的一个实例(使用GCC 4.7.0似乎是16个字节 - 我没有检查我是否正在构建32位或64位代码,但无论哪种方式看起来超大)。为什么不使用整数类型?
有些烦恼......
streampos p;
p++; // Error - streampos doesn't have operator++
p = p + 1; // Warning - ambiguous (using 1ul or 1ull doesn't seem to fix it)
这些警告问题也会在比较和其他地方发生。
基本上,我会遇到很多令人恼火的噪音来解决这些问题 - 很多演员阵容都来自streampos
或streamoff
等。
我觉得自己是个白痴,错过了一些显而易见的东西,但是我的Google技能让我失望了 - 我没有找到一个例子来说明我做错了什么。
所以 - 我做错了什么?使用位置计算进行随机访问是否有惯用的风格可以避免所有这些噪音?
答案 0 :(得分:0)
到目前为止,我已经想到的是......
std::streampos
不是一个简单的整数,因为它可能需要在标准上没有64位整数类型的平台上支持大文件。事实上,它几乎肯定早于PC编译器中64位整数的广泛支持 - Borland C++在版本5.02中获得了它们,例如,1997年的IIRC,在第一个标准之前不久。 {CES 11之前long long
不是标准的。
std::streamsize
和std::streamoff
都是整数类型的typedef。但是,streamoff
始终是签名类型。这对于相对寻求很重要,这可能是倒退。我没有找到关于streamsize
是否必须签名或未签名的任何要求 - 我猜这至少可能是无签名的。
在streampos
中添加或减去时,您应始终添加或减去streamoff
。需要的Typecast,例如添加或减去文字编号时。
与往常一样,当事情变得混乱时,请把它弄得乱七八糟地隐藏起来。