2013-05-11 63 views
0

我目前正在编写一个Photoshop PSD文件解析器来提取一些特定的元数据。跳过可能大的无关数据块表明一些随机访问。我需要支持PSB以及PSD - PSB具有相同的基本文件结构,但具有更大的限制,并且一些大小字段为64位。如何处理ifstream使用的随机访问? - 位置/偏移量/大小问题

随着Photoshop file format specs.可公开获得的,这应该是一个很简单的工作,但我从来没有需要之前担心大文件,至少在使用ifstream。我总是忽略streampos等,只是使用size_t作为文件位置和偏移量。我现在没有逃避。我并没有想到这是一件大事,事实并非如此,但它变得尴尬和混乱 - 我认为这意味着我正在与图书馆作斗争,而不是做它所期望的。

第一个问题 - 有三个位置/偏移/大小类型...

  • 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) 

这些警告问题的发生是比较和其他地方了。

基本上,我越来越有刺激性的噪声来解决这些了很多 - 石膏的大量对streamposstreamoff

我有感觉,我是一个白痴和缺少明显的东西,但我谷歌技能让我失望 - 我还没有找到一个能够证明我做错了什么的例子。

所以 - 我做错了什么?有没有一种惯用的风格来进行位置计算的随机访问,以避免所有这些噪音?

+0

边缘线现在睡着了,所以我会把这个留给其他人 - 但要回答你最后的问题 - 不要,至少不是完全的,当你需要去足够低的偏移量,根据定义它会变得混乱。 – TC1 2013-05-11 01:57:23

回答

0

到目前为止,我已经想通了就是...

  • std::streampos不是一个简单的整数,因为它可能需要支持在不具备64位整数平台上的大文件类型为标准。实际上,它几乎可以肯定早于64位整数在PC的编译器中的广泛支持 - Borland C++在1997年的版本5.02(例如IIRC)中获得了它们 - 不久之前就是第一个标准。在C++ 11之前,long long不是标准的。

  • std::streamsizestd::streamoff都是整数类型的定义。但是,streamoff始终是签名类型。这对于相对的寻找很重要,这可能是倒退的。我还没有找到streamsize是否必须签名或未签名的任何要求 - 我猜它至少有可能是未签名的。

  • 当加入或减去streampos时,应始终加上或减去streamoff。需要的地方,例如当增加或减少文字数字。

  • 与往常一样,当有些东西杂乱无章时,将其混淆并隐藏它。