C ++以二进制模式写入和读取文件

时间:2019-12-23 08:04:22

标签: c++ c++11 fstream

我想在/dev/shm/uploaded中创建一个二进制文件,并以二进制模式打开一个文件并将数据写入其中。

    std::string string_path = "/dev/shm/uploaded/";
    std::string filename = "download_file.out";
    std::string tmpStr = "The quick brown fox jumps over the lazy dog";

    createFile(string_path, filename); 

    bool createFile(std::string &string_path, std::string &filename) {
        std::string command_string = "mkdir -p ";
        command_string.append(string_path);
        std::cout << command_string << std::endl;
        int check = system(command_string.c_str());
        if(-1 == check) {
           return false;
        }
        std::ofstream outfile(string_path + filename, std::ios::binary | std::ios::out);
        if(outfile.is_open()) {
          for (int i = 0; i < 100000; i++) {
              outfile << tmpStr;
          }
        }
        outfile.close();
        return true;
    }

我怀疑我使用<<运算符正在以文本模式而不是二进制模式写入数据。 我想以二进制模式写入数据。

我在看binary read and write

它具有以下功能

template<>
std::ostream& binary_write_string(std::ofstream& stream, const std::string& value){
    return stream->write(value.c_str(), value.length());
}

在此函数中,没有typenameclass的模板化函数是什么意思?这是正确的方法吗?

2 个答案:

答案 0 :(得分:0)

正如Botje所建议的,文本模式和二进制模式之间的主要区别在于换行符转换。您可以尝试以下代码并查看输出。

#include <fstream>

using namespace std;

int main()
{
    string tmpStr = "The quick brown fox jumps over the lazy dog\n";

    ofstream outbinfile("output_binary.txt", std::ios::binary | std::ios::out);
    for (int i=0; i<3; i++)
        outbinfile << tmpStr;
    outbinfile.close();

    ofstream outfile("output.txt", std::ios::out);
    for (int i=0; i<3; i++)
        outfile << tmpStr;
    outfile.close();

    return 0;
}

output_binary.txt是132个字节,符合预期。但是output.txt在Windows中是135个字节。因为对于换行符,它实际上写出\r\n[1]

答案 1 :(得分:0)

  1. xfstream( fn, ios::text )xfstream( fn, ios::binary )(其中x是io)之间的区别是行尾如何插入/提取
    • 对于文本流,is << '\n'将插入(取决于操作系统)\n\r。提取后,该序列将翻译回\n
    • 对于二进制流,插入/提取的内容就是写入/读取的内容
  2. 以二进制模式打开流并向其写入二进制数据或从中读取二进制数据是不同的事情。当您使用插入/提取运算符(<<>>)时,您将写入/读取格式化的数据(类似于c中的printf

    #include <iostream>
    #include <iomanip>
    using namespace std;
    //...
    cout << setfill( '~' ) << setw( 2 ) << 2; // outputs "~2"
    
  3. 如果要写入/读取实际字节(例如,32位整数的4个字节,而不是人类可读的形式),则必须使用ostream::write / istream::read。 C ++不会阻止您将这些功能与文本流一起使用。正确组合它们是您的责任。

  4. 在c ++中,模板功能可能是专业化的:对于特定的模板签名,表现出不同的行为。您从引荐链接中错过的是该功能的非专业版本

    template<typename T> void f( T )
    {
      cout << "unspecialized\n";
    }
    
    template<> void f( const char* s )
    {
      cout << "specialized\n";
    }
    //...
    f( 0 ); // prints "unspecialized"
    f( 'c' ); // prints "unspecialized"
    f( "" ); // prints "specialized"