0

我正在尝试直接写入 fstream 输出缓冲区以避免memcpy.

为什么下面的代码不起作用?

它在 Linux 上编译、运行并生成正确长度的输出文件。但输出文件不包含正确的文本。另请注意,由于某种原因,当我注释掉涉及 的两行时str2,会生成一个长度为零的输出文件。

注意:这个例子没有避免memcpy,但如果它有效,它将帮助我memcpy在我的应用程序中避免 a 。

#include <fstream>

int main(int argc, char *argv[]) {
  std::fstream out;
  char buffer[512];
  out.rdbuf()->pubsetbuf(buffer, 512);
  out.open("file.txt", std::fstream::out);
  char *str1 = "test text.";
  strcpy(buffer, str1);
  out.rdbuf()->pubseekpos(strlen(str1), std::ios_base::out);
  char *str2 = "why?";
  out << str2;
  out.flush();
  out.close();
}
4

5 回答 5

2

您为流提供一个缓冲区供内部使用。然后你不给它写任何东西。

您在不告诉流的情况下将某些内容复制到缓冲区这一事实不会给您文件中的任何内容。

您可能已经注意到,seekpos 用于在文件中定位,而不是在缓冲区中移动。缓冲区仅供流内部使用!

于 2011-04-27T06:29:16.487 回答
1

当 you 时out.rdbuf()->pubseekpos(strlen(str1), std::ios_base::out);,这会要求流向前跳过新创建的文件。您能期望它从您指定的缓冲区中获取内容吗?一条线索:您是否看到任何涉及指定缓冲区的示例,这些示例表明您需要以某种方式对其进行初始化或指定其中包含的非垃圾字符的初始数量?不...因为流本身会跟踪缓冲区的哪些部分正在使用中。因此 - 当您使用假定的空缓冲区并向前跳过时,它会生成中间的 NUL。将它们设置在缓冲区中是没有意义的(所以简单地在memcpy后面做 apubseekpos也行不通)——如果你向前跳跃超过一个缓冲区大小怎么办?

希望这至少可以说明问题,尽管在这个阶段我没有考虑过如何强制流改变它对有意义的缓冲区内容的“跟踪”......

于 2011-04-27T06:08:01.370 回答
0

我看到了三种可能性

  1. 实现你自己的流缓冲类
  2. 使用本机文件 API
  3. 禁用缓冲pubsetbuf(0, 0)

实现一个流缓冲区真的没有那么困难,并且可以让您有机会将 C++ 风格的流插入与直接内存访问相结合,而不会牺牲性能。

于 2011-04-27T21:10:55.857 回答
0

时间还早,但你不是基本在做吗

#include <fstream>

int main(int argc, char *argv[]) 
{

  std::fstream out;
  out.open("file.txt", std::fstream::out);

  out << "test text";
  out << "why?";

  out.flush();
  out.close();
}

?

于 2011-04-27T04:39:32.883 回答
0

我对 C++ iostream 库不够熟悉,无法说出您的程序出了什么问题,我只想提一下,如果您想做自己的缓冲,使用 read() 和 write() 接口可能会更直接直接(man 2 write)。如果你自己做缓冲,iostream 库可能不会给你带来太多好处,只会掩盖实际发生的事情。

于 2011-04-27T06:04:55.537 回答