首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >合并大文件

合并大文件
EN

Stack Overflow用户
提问于 2009-08-14 00:27:28
回答 3查看 1.8K关注 0票数 0

我正在尝试连接C++中的两个大文件(比如UNIX cat命令: cat file1 file2 > final)。

我不知道怎么做,因为我尝试的每个方法都非常慢(例如,逐行将第二个文件复制到第一个文件中)

?做到这一点的最好方法是什么?

对不起,我太简短了,我的英语不太好

EN

回答 3

Stack Overflow用户

发布于 2009-08-14 00:31:55

在标准流中使用二进制模式来完成这项工作,而不是将其作为格式化数据进行处理。

这是一个演示,如果您想要以块为单位传输数据:

代码语言:javascript
运行
复制
#include <fstream>
#include <vector>

std::size_t fileSize(std::ifstream& file)
{
    std::size_t size;

    file.seekg(0, std::ios::end);
    size = file.tellg();
    file.seekg(0, std::ios::beg);

    return size;
}

int main()
{
    // 1MB! choose a conveinent buffer size.
    const std::size_t blockSize = 1024 * 1024;

    std::vector<char> data(blockSize);
    std::ifstream first("first.txt", std::ios::binary),
                second("second.txt", std::ios::binary);
    std::ofstream result("result.txt", std::ios::binary);
    std::size_t firstSize  = fileSize(first);
    std::size_t secondSize = fileSize(second);

    for(std::size_t block = 0; block < firstSize/blockSize; block++)
    {
        first.read(&data[0], blockSize);
        result.write(&data[0], blockSize);
    }

    std::size_t firstFilerestOfData = firstSize%blockSize;

    if(firstFilerestOfData != 0)
    {
        first.read(&data[0], firstFilerestOfData);
        result.write(&data[0], firstFilerestOfData);
    }

    for(std::size_t block = 0; block < secondSize/blockSize; block++)
    {
        second.read(&data[0], blockSize);
        result.write(&data[0], blockSize);
    }

    std::size_t secondFilerestOfData = secondSize%blockSize;

    if(secondFilerestOfData != 0)
    {
        second.read(&data[0], secondFilerestOfData);
        result.write(&data[0], secondFilerestOfData);
    }

    first.close();
    second.close();
    result.close();

    return 0;
}
票数 6
EN

Stack Overflow用户

发布于 2009-08-14 01:06:45

如果你正在使用std::fstream,那就不要使用它,它主要用于格式化的输入/输出,字符级的操作是slower than you'd expect。相反,可以直接使用std::filebuf。这是对其他答案中的建议的补充,特别是使用更大的缓冲区大小。

票数 6
EN

Stack Overflow用户

发布于 2009-08-14 00:50:35

使用普通的老式C++:

代码语言:javascript
运行
复制
#include <fstream>

std::ifstream file1("x", ios_base::in | ios_base::binary);
std::ofstream file2("y", ios_base::app | ios_base::binary);
file2 << file1.rdbuf();

Boost标头声称copy()在某些情况下是优化的,尽管我不确定这是否算数:

代码语言:javascript
运行
复制
#include <boost/iostreams/copy.hpp>
// The following four overloads of copy_impl() optimize 
// copying in the case that one or both of the two devices
// models Direct (see 
// http://www.boost.org/libs/iostreams/doc/index.html?path=4.1.1.4)

boost::iostreams::copy(file1, file2);

更新:

Boost复制功能兼容多种类型,因此可以与Pavel Minaev建议的使用std::filebuf相结合,如下所示:

代码语言:javascript
运行
复制
std::filebuf file1, file2;

file1.open("x", ios_base::in | ios_base::binary);
file2.open("y", ios_base::app | ios_base::binary);

file1.setbuf(NULL, 64 * 1024);
file2.setbuf(NULL, 64 * 1024);

boost::iostreams::copy(file1, file2);

当然,实际的最佳缓冲区大小取决于许多变量,64k只是一个胡乱猜测。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1275415

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档