【问题标题】:Reading and writing binary files in C++用 C++ 读写二进制文件
【发布时间】:2013-06-17 00:56:24
【问题描述】:

我是 C++ 的新手,我只是从昨天开始的几个小时的自学。 所以:

我有一个未压缩的简单 beep.wav 文件,只有大约 3 秒长,里面有一个哔哔声。

我最终想要实现的是,只是读取文件,同时写入二进制数据,全部包括:headerftmdata 或所有十六进制可读数据并将其转储到一个简单的beep.txt 文件中。

在 C++ 中这可能吗?如果是这样,我应该如何开始读取和转储二进制文件?

我可以使用<fstream> 类读取文件~或多或少

#include <iostream>
#include <fstream>

   int main()
   {
       ifstream myfile ("beep.wav", ios::in|ios::binary|ios::ate);
       if (myfile.is_open())
       {
        //reading goes here
        }
       return 0;
    }

【问题讨论】:

  • 你想达到什么目的?为什么要将二进制数据写入文本文件?你认为文本文件会有什么二进制数据没有?
  • 首先,在功能方面,计算机可以做的所有事情都可以在 C++ 中实现(就像大多数其他通用编程语言一样。)世界运行在 C 和 C++ 上,所以它可以完成.但是,您真正想要做什么完全不清楚。您想将一个文件的内容复制到另一个文件中吗?是否要解析 WAV 标头和 PCM 数据并将它们转换为文本?您甚至知道未压缩(又名 PCM)WAV 文件的结构吗?
  • @xxbbcc 好吧,我正在学习 C++ 来创建一个声音操作工具,并且为了了解它从 0 开始的所有工作原理。我需要学习/实验二进制数据的存储工作原理,以及如何操作它。
  • @yzt 就像上面我说的,我一直在学习声音、音频信号和音频驱动程序,这个主题是我了解其工作原理的方式。所以,我只是想玩它。 . 如果你愿意的话。
  • @bluethief 在这种情况下,您首先需要了解二进制文件和文本文件之间的区别。这些存在是有原因的,一个人不能直接将内容从一个写入另一个而没有后果。您可以读取 WAV 文件的内容,但要以有意义的方式将其写入文本文件,您必须翻译数据。如何做到这一点取决于您想要什么样的文本输出。

标签: c++ c wav binaryfiles fstream


【解决方案1】:

正如yzt 所述,您需要提前了解.wav 中的内容以及顺序。据我所知,您将拥有标签、标题和值(样本)以及压缩信息。所以,开始吧:

例如,如果您知道首先要做的是读取压缩率,那么您将通过提取可能是 double 来开始您的阅读过程:

ifstream myfile("beep.wav", ios::in|ios::binary);

double compression_rate;
myfile.read((char*)&compression_rate, sizeof(compression_rate));

// As well as probably the sample rate...
double sample_rate;
myfile.read((char*)&sample_rate, sizeof(sample_rate));

那么,可能是样本数:

int nb_samples;
myfile.read((char*)&nb_samples, sizeof(nb_samples));

然后,这些样本的值...(此处存储为 vectordouble

vector<double> vect;
vect.resize(nb_samples);
myfile.read((char*)&vect[0], nb_samples * sizeof(double));

等等……

但同样,您打开的.wav 是由什么组成的?

一旦你完全掌握了内容,你就可以另辟蹊径,从头开始编写自己的.wav...


Getting started - 和here

Bytes - "Autopsy" of a PCM Wav file.

【讨论】:

  • 好吧,谢谢,但我有点迷失在这里,有了这些新功能。 .wav 文件的类型我也不能多说,因为它是未压缩的简单纯音频 wav 文件。
  • 嗯,这些是从ifstream 读取二值化数据的方法。当你读取一个值(比如double)时,你将它存储在一个变量中。结果compression_rate 得到了值并且文件光标的位置移动了double 的大小。然后,您可以阅读下一条信息(此处为int)。光标再次移动。然后从当前位置读取nb_samples 乘以双精度(同样,每次读取值时,光标都会移动)......直到读取结束(EOF)。对你来说更有意义吗?
  • 谢谢。我现在的照片比以前好。但是链接太棒了。
  • 很高兴为您提供帮助!第二个链接要求您熟悉(如果不是这样的话)size (in bytes) of C typesread 函数只是读取一定数量的字节。这是此函数采用的第二个参数的用途,这也是位于网页中间的表格的size 列的用途。祝你的 sound manipulation tool 项目好运...
  • 谢谢。我边走边学。声音操纵工具只是一个频谱图。只是非常简单的一个。我正在学习这些,只是为了能够创建一个,希望在这周内
【解决方案2】:

此示例将从输入文件中读取数据并将其写入为 2 个字符的十六进制值(文本)。

ofstream outfile("beep.txt");
outfile << hex << setfill('0');

char c;
while( outfile.good() && myfile.get(c) )
{
    outfile << setw(2) << +(unsigned char)c;
}

【讨论】:

  • 感谢 paddy,我尝试将您的代码集成到我的代码中,但是,我遇到了错误.. 更简洁 'ifsteam' was not declared in this scope 这是什么意思?它工作正常,在添加代码之前......很奇怪......
  • 仔细阅读错误信息......它试图告诉你没有ifsteam这样的东西(检查你的拼写)。
  • @bluethief:很明显,您需要一本好书,可以轻松参考和/或熟悉C++ Internet Reference,而不仅仅是一个问答论坛。
【解决方案3】:

WAV file format specification 告诉您 WAV 文件的二进制布局 - 您需要它,因为它告诉您以什么顺序读取哪些字节。 (除了字节之外,您确实需要阅读int-s 和各种其他字段。)一旦您阅读了这些信息,就可以将其翻译以显示并将其写入文本文件。比如,你可以通过读取文件头(具体的布局我不知道)写出WAV文件中声音的长度(持续时间),然后计算转换为多少秒。

从技术角度来说,您的问题的所有其他答案都很好 - 它们为您提供了有关如何在 C++ 中读取/写入二进制和文本数据的指导。

【讨论】:

【解决方案4】:

您可以将整个文件读入缓冲区:

  1. 查找文件末尾
  2. 制作一个足以容纳文件的缓冲区
  3. 回到文件开头
  4. 将整个文件读入缓冲区

myfile.seekg(0, std::ios::end);
std::string buffer(myfile.tellg(), '\0');
myfile.seekg(0);

myfile.read(&buffer.front(), buffer.size());

【讨论】:

  • 谢谢:那我如何在为什么我可以观察到原始数据?
猜你喜欢
  • 2013-07-10
  • 2020-09-09
  • 1970-01-01
  • 1970-01-01
  • 2019-04-20
  • 2019-09-18
  • 1970-01-01
  • 2020-09-03
  • 2021-06-22
相关资源
最近更新 更多