好的,这里有一些代码概述了我正在尝试做的事情.
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/fcntl.h>
#include <iostream>
#include <sstream>
int main( int c, char *v[] )
{
int fd = open( "data.out", O_RDONLY | O_NONBLOCK );
std::cout << "fd = " << fd << std::endl;
char buffer[ 1024000 ];
ssize_t nread;
std::stringstream ss;
while( true )
{
if ( (nread = read( fd, buffer, sizeof( buffer ) - 1 )) < 0 )
break;
ss.write( buffer, nread );
while( true )
{
std::stringstream s2;
std::cout << "pre-get : " <<
(((ss.rdstate() & std::ios::badbit) == std::ios::badbit) ? "bad" : "") << " " <<
(((ss.rdstate() & std::ios::eofbit) == std::ios::eofbit) ? "eof" : "") << " " <<
(((ss.rdstate() & std::ios::failbit) == std::ios::failbit) ? "fail" : "" ) << " " <<
std::endl;
ss.get( *s2.rdbuf() );
std::cout << "post-get : " <<
(((ss.rdstate() & std::ios::badbit) == std::ios::badbit) ? "bad" : "") << " " <<
(((ss.rdstate() & std::ios::eofbit) == std::ios::eofbit) ? "eof" : "") << " " <<
(((ss.rdstate() & std::ios::failbit) == std::ios::failbit) ? "fail" : "" ) << " " <<
std::endl;
unsigned int linelen = ss.gcount() - 1;
if ( ss.eof() )
{
ss.str( s2.str() );
break;
}
else if ( ss.fail() )
{
ss.str( "" );
break;
}
else
{
std::cout << s2.str() << std::endl;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
它首先将大块数据读入数据缓冲区.我知道有更好的C++方法来做这个部分,但在我的实际应用程序中,我交给了一个char []缓冲区和一个长度.
然后我将缓冲区写入std :: stringstream对象,这样我就可以一次删除一行.
我想我会使用get(流缓冲和)方法对stringstream的一条线写另一个字符串流在那里我可以再输出.
忽略这一事实,这可能不是从我读过的缓冲区一次提取一行的最佳方式(虽然我希望任何人提供一个更好的替代我在这里发布的那个),一旦第一个ss.get( *s2.rdbuf() )被称为ss处于失败状态,我无法解决原因.输入文件中有大量数据,因此ss应该包含多行输入.
有任何想法吗?
我已经在 Windows 上对此进行了测试,因此您可能需要验证这一点;
如果 data.out 以换行符开头,我会遇到与您相同的问题,否则 ss.get( *s2.rdbuf() ) 在第一次调用时工作正常。
第二次调用时,流的当前位置尚未超过 EOL。因此,当第二次调用 get 时,立即尝试读取 EOL,并且由于没有复制其他字符,因此它设置失败位。
快速但可能是肮脏的修复:
ss.get( *s2.rdbuf() );
// Get rid of EOL (may need an extra if file contains both \r and \n)
ss.get();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3482 次 |
| 最近记录: |