【问题标题】:Writing unsigned chars to a binary file using write()使用 write() 将无符号字符写入二进制文件
【发布时间】:2011-10-23 04:24:20
【问题描述】:

我正在制作一个读取二进制文件的程序。因此,我将各个字节读入无符号字符(实际上将数据读取为字符并将它们转换为每个字符的无符号字符)。现在我必须将无符号字符写回二进制文件。

问题是现在我不得不在将它们转换为字符后写入单个字节(因为二进制文件的 write() 需要 char* 缓冲区)。所以,现在我必须做以下事情:

for(int x=0; x<data_size; x++)
{
    ch=(char)data[x];
    outfile.write(&ch,1);
}

有什么办法可以绕过这个问题,从而减少读写时的 I/O 操作量?

【问题讨论】:

  • 不要一次写入一个字节,而是更大的块(比如 64kiB)。就此而言,阅读也是如此。

标签: c++ file-io binary


【解决方案1】:

outfile 的类型是ofstream,对吧? ofstreamtypedef 的,

typedef std::basic_ofstream<char, std::char_traits<char> > ofstream;

你需要自己的typedef

typedef std::basic_ofstream<unsigned char, std::char_traits<unsigned char> > uofstream;

然后,

uofstream outfile(...);
outfile.write(data, data_size); //no need to cast

【讨论】:

  • 这是未定义的行为。实现没有义务提供std::char_traits&lt;unsigned char&gt; 的实例化,以及那些确实具有不兼容实例化的实例。
  • @c0da 它可能在特定的编译器上。或者它可能不会。我知道有人尝试过使用 VS 和 g++ 来做这件事,但得到了两种完全不同的行为。
  • 很遗憾,这不适用于 gcc v.4.7.2。它创建并打开文件,但不会向其中写入任何数据。
  • 这不适用于 clang++ 5.0.0,尽管该解决方案看起来很优雅。创建了一个文件,但写入失败,最终结果是文件的大小为 0 字节。
【解决方案2】:

您可以对指针进行强制转换...

outfile.write((char *)&data[0], data_size);

读取也可以这样做(即,只需将指针传递给 unsigned char 数组的第一个元素,将其转换为指向 char 的指针)。

【讨论】:

  • 我想要一个明确的reinterpret_cast 更好
  • @Kerrek:问题表明 outfile.write 期待 char*
  • 我想说,也不要使用。如果只是临时数据,那还好,但如果你这样写数据,将来的某个时间,你将无法读取它。
  • @James Kanze:您是否提倡使用 xml 节点保存 RGB 图像的每个像素? :-)
  • @6502 我在哪里说过有关 XML 的内容?我提倡以已知和定义的格式保存数据,以便您以后可以重新阅读。 (大多数图像文件都有您必须遵守的定义格式。)
【解决方案3】:

data 的类型为unsigned char*unsigned char[] 并且您只想将位写入文件时,请执行指针转换:

for(int x=0; x<data_size; x++)
{
outfile.write((char*)data + x, 1);
}

因为铸造消除了一次写作的问题:

outfile.write((char*)data, data_size);

而且您一次完成所有操作。请注意,这超出了类型检查,因此不是最佳解决方案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-19
    • 2014-05-20
    • 1970-01-01
    • 2020-08-28
    • 2016-01-15
    相关资源
    最近更新 更多