【发布时间】:2013-07-04 05:45:18
【问题描述】:
执行此操作的规范方法是什么?
我必须在这里阅读wstring,但我确信答案也应该适用于string。
这是我现在正在尝试的:
wifstream file(filename, ios::in | ios::binary);
// this next line is cleverer but works the same way (i.e. null byte stops it)
// return wstring(istreambuf_iterator<wchar_t>(file), istreambuf_iterator<wchar_t>());
wstring out;
wchar_t buf[8192];
while (true) {
file.read(buf, 8192);
streamsize len = file.gcount();
cerr << len << "chars read.";
out.append(buf, len);
if (len != 8192) break;
}
return out;
如何在文件中遇到空字节时让它继续读取?
如果 POSIX 有一项法令禁止任何文件中存在空字节,我实际上不会感到惊讶。但显然 Vim 正在使用一些魔法将所有这些空值写入撤消文件格式。此外,如果您碰巧将内容编码或加密为随机字节流(或多种模拟采样),则必须产生空值。我的意思是,我可以继续:OS X 上的管道 (FIFO) 可以很好地处理通过它们的空字节:我可以 cat 撤消文件,将其通过管道传输到 xxd,它可以读取它。
这显然是我遇到的一些简单的事情。它是什么?当然有一种 C++ 方法可以做到这一点。或者也许你知道<stdio.h> 的方法。我想知道。
例如,这是我正在测试的文件:
% cat .dmp.cpp.un\~| xxd | head
0000000: 5669 6d9f 556e 446f e500 0218 96c6 25f6 Vim.UnDo......%.
0000010: 64bb 2301 6ed8 3578 5c50 61e0 eae5 a819 d.#.n.5x\Pa.....
0000020: b17d 53b5 f932 dc9d 40aa 1b00 0000 8500 .}S..2..@.......
0000030: 0000 5720 2020 2020 2020 2020 2020 2063 ..W c
0000040: 6572 7220 3c3c 2022 466f 756e 6420 616e err << "Found an
0000050: 2075 6e70 7269 6e74 6162 6c65 2063 6861 unprintable cha
字节 2b 是第一个空字节。程序读取了 44 个字节 (2c),因此它写入了第一个空字节,并停在那里。
% la .dmp.cpp.un\~
-rw-r--r-- 1 lust staff 326836 Jul 4 01:41 .dmp.cpp.un~
P.S.,我在 here 的评论中得到了简洁的单行字。可悲的是,它也受到这个问题的影响。
【问题讨论】:
-
您如何验证它不是?打印字符串将在第一个
\0处停止,但数据可能仍在字符串中。检查std::string::size()可能吗? -
好吧,对于初学者来说,当我在我的 vim undofile 上运行它时,它有很多 KB,它只读取 44 个字节(我是
cerring gcount 给我的东西......)。我xxd文件,果然第44个字节是\0。 -
我有同样的字符串没有任何问题:while (file.read(buf, sizeof(buf)).gcount() > 0) rep.append(buf, file.gcount()) ;
-
这段代码对我有用。我怀疑可能是您在返回字符串后如何使用它。
-
我不需要对字符串做任何事情!! gcount 比实际实际大小要小得多!如果你们能用相同的程序让它读取任何空字节,请给我看截图或其他东西。
标签: c++ file-io filestream binaryfiles ifstream