gpt4 book ai didi

c++ - 有效地将一个标准流复制到另一个标准流

转载 作者:可可西里 更新时间:2023-11-01 17:59:51 26 4
gpt4 key购买 nike

好的,这里有一些代码概述了我正在尝试做的事情。

#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;
}
}
}
}

它首先将大块数据读入数据缓冲区。我知道有更好的 C++ 方法来完成这部分,但在我的实际应用程序中,我得到了一个 char[] 缓冲区和一个长度。

然后我将缓冲区写入 std::stringstream 对象,这样我就可以一次从中删除一行。

我想我会在 stringstream 上使用 get( streambuf & ) 方法将一行写入另一个 stringstream,然后我可以在其中输出它。

忽略这样一个事实,即这可能不是一次从我读入的缓冲区中提取一行的最佳方法(尽管我希望任何人都能提供比我在此处发布的方法更好的替代方法),一旦第一个 ss.get( *s2.rdbuf() ) 被调用,ss 就处于失败状态,我不知道为什么。输入文件中有大量数据,因此 ss 肯定包含不止一行输入。

有什么想法吗?

最佳答案

在我看来,获得良好效率的第一步(可能也是最大的一步)是尽量减少数据复制。由于您在 char[] 中获得了具有长度的数据,因此我的第一个倾向是首先使用该缓冲区创建一个 strstream。然后,我不会一次将一个字符串复制到另一个 strstream(或 stringstream),而是一次将一个字符串复制到您将用于将它们写入输出的流。

如果您被允许修改缓冲区的内容,另一种可能性是通过简单地将每个'\n'替换为'\0'来将缓冲区解析为行。如果你打算这样做,你通常会想要创建一个指向每行开头的指针的 vector (双端队列等)(即找到第一个'\r'或'\n',并且将其替换为“\0”。然后,除“\r”或“\n”之外的下一个内容是下一行的开头,因此它在 vector 中的地址)。

我也会仔细考虑是否可以避免一次一行输出。读取大缓冲区以查找换行符相对较慢。如果您最终要一行接一行地写,您可以通过将整个缓冲区写入输出流并完成它来避免所有这些。

关于c++ - 有效地将一个标准流复制到另一个标准流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2084713/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com