如何在 C++ 中将数百个二进制文件合并为一个输出文件?

How do I combine hundreds of binary files to a single output file in c++?

我有一个包含数百个 .aac 文件的文件夹,我正在尝试以最有效的方式将它们“打包”到一个文件中。

我已经尝试了以下方法,但最终得到的文件只有几个字节长,或者音频听起来非常失真。

// Now we want to get all of the files in the folder and then repack them into an aac file as fast as possible
void Repacker(string FileName)
{
    string data;
    boost::filesystem::path p = "./tmp/";
    boost::filesystem::ofstream aacwriter;
    aacwriter.open("./" + FileName + ".aac", ios::app);

    boost::filesystem::ifstream aacReader;
    boost::filesystem::directory_iterator it{ p };
    cout << "Repacking File!" << endl;
    while (it != boost::filesystem::directory_iterator{}) {
        aacReader.open(*it, std::ios::in | ios::binary);
        cout << "Writing " << *it << endl;
        aacReader >> data;
        ++it;
        aacwriter << data;
        aacReader.close();
    }
    aacwriter.close();
}

我查看了以下问题以尝试帮助解决此问题

Merging two files together

How do I read an entire file into a std::string in C++?

Read whole ASCII file into C++ std::string

Merging Two Files Into One

然而不幸的是,其中 none 个回答了我的问题。

它们要么与文本文件有关,要么与不能同时处理数百个文件的函数有关。

我正在尝试写入 二进制 数据,而不是文本。音频要么全部失真,要么文件只有几个字节长。

如果有有效的内存方法可以做到这一点,请告诉我。我正在使用 C++ 20 和 boost。 谢谢。

这些文件具有内部结构:header、blocks/frames 等,并且在串联文件中简单地存在多个 header 会打乱预期的结果。

看看AAC file format structure,你会发现事情并没有那么简单。

您最好的尝试应该是使用 FFMPEG,因为它具有连接媒体文件的功能 ,而不会 被迫重新编码数据。它有点复杂,因为 FFMPEG 的命令行非常复杂并且并不总是非常直观,但只要所有 AAC 文件使用相同的编码和特征,它就应该可以工作。否则,您将需要 re-encode 它们 - 但它也可以自动完成。 检查此 web research 以获取一些基本信息。

否则,您可以使用 FFMPEG 使用的基础库,例如 libavcodec (available at ffmpeg.org), Fraunhofer FDK AAC 等。但是您还有更多的工作要做,最后,您将完全按照 FFMPEG 的方式进行操作已经这样做了,因为它依赖于这些库。其他 AAC 库不会真的更容易使用。

显然,您也可以在您的应用程序中“嵌入”FFMPEG,调用 ffprobe 等工具来分析文件并自动调用 ffmpeg 可执行文件,作为一个 child 进程。

注意:如果您打算分发您的程序,请非常注意许可。 FFMPEG licensing 真的不简单,大部分时候都是作为源码分发,避免恶性案件。