C ++ пишет и читает файл в двоичном режиме - PullRequest
0 голосов
/ 23 декабря 2019

Я хочу создать двоичный файл в /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;
    }

Я подозреваю, что с помощью оператора << я записываю данные втекстовый режим, а не в двоичном режиме. Я хочу записать данные в двоичном режиме.

Я смотрел на двоичное чтение и запись

Он имеет следующую функцию

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

В этой функции что означает шаблонная функция без typename или class? Это правильный подход.

Ответы [ 2 ]

0 голосов
/ 23 декабря 2019
  1. Разница между xfstream( fn, ios::text ) и xfstream( fn, ios::binary ) (где x - i или o) - как вставка / извлечение конца строки .
    • Для текстового потока is << '\n' вставит (в зависимости от ОС) \n\r. При извлечении последовательность будет переведена обратно на \n.
    • Для двоичного потока то, что вы вставляете / извлекаете, - это то, что вы пишете / читаете .
  2. Открытие потока в двоичном режиме и запись / чтение двоичных данных в / из него - разные вещи. Когда вы используете операторы вставки / извлечения (<< & >>), вы записываете / читаете отформатированные данные (аналогично printf в c) :

    #include <iostream>
    #include <iomanip>
    using namespace std;
    //...
    cout << setfill( '~' ) << setw( 2 ) << 2; // outputs "~2"
    
  3. Если вы хотите записать / прочитать фактические байты (например, 4 байта 32-битного целого числа, а не его читабельной формы), вы должны использовать ostream::write / istream::read. C ++ не остановит вас от использования этих функций с текстовым потоком. Вы несете ответственность за их правильное объединение.

  4. В шаблонах с ++ функции могут быть специализированными : демонстрировать различное поведение для конкретных сигнатур шаблона. То, что вы пропустили по указанной ссылке, является неспециализированная версия функции .

    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"
    
0 голосов
/ 23 декабря 2019

Как предполагает Ботье, основным отличием между текстовым и двоичным режимом является преобразование новой строки. Вы можете попробовать следующий код и посмотреть результат:

#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 составляет 135 байт в Windows. Потому что для новой строки он выписывает \r\n на самом деле. [1]

...