2015-10-11 6 views
2

Я пытаюсь использовать ifstream/ofstream для чтения/записи, но по некоторым причинам данные повреждаются по пути. Heres методы на чтение/запись и тест:Запись и чтение файла

void FileWrite(const char* FilePath, std::vector<char> &data) { 
    std::ofstream os (FilePath); 
    int len = data.size(); 
    os.write(reinterpret_cast<char*>(&len), 4); 
    os.write(&(data[0]), len); 
    os.close(); 
} 
std::vector<char> FileRead(const char* FilePath) { 
    std::ifstream is(FilePath); 
    int len; 
    is.read(reinterpret_cast<char*>(&len), 4); 
    std::vector<char> ret(len); 
    is.read(&(ret[0]), len); 
    is.close(); 
    return ret; 
} 

void test() { 
    std::vector<char> sample(1024 * 1024); 
    for (int i = 0; i < 1024 * 1024; i++) { 
     sample[i] = rand() % 256; 
    } 

    FileWrite("C:\\test\\sample", sample); 
    auto sample2 = FileRead("C:\\test\\sample"); 

    int err = 0; 
    for (int i = 0; i < sample.size(); i++) { 
     if (sample[i] != sample2[i]) 
      err++; 
    } 
    std::cout << err << "\n"; 
    int a; 
    std::cin >> a; 

} 

Он записывает длину правильно, считывает его правильно и начинает правильно читает данные, но в некоторой точке (в зависимости от входных данных, как правило, примерно в 1000'th байт) это идет не так, и все, что нужно, ошибочно. Почему это?

+0

написать массив в этом Манер, вы должны преобразовать его в обугливается [] или символ * или с помощью петли и ostream & оператор << и IStream & оператор >> – Mykola

+0

Составитель это с г ++ и она работает хорошо (побежал в 10 раз) , Какой компилятор вы используете? Я не очень уверен в вашей операции записи/чтения, используя ссылку на первый элемент вектора. Вы пытались использовать/while и читать/заполнять векторный элемент за элемент? – jpo38

+1

В '(reinterpret_cast (& len), 4)' не предполагайте, что размер 'len' равен' 4'. Вместо этого используйте 'sizeof (len)'. – NathanOliver

ответ

2

стартера, вы должны открыть файловый поток для бинарного чтения и записи:

std::ofstream os (FilePath,std::ios::binary); 

(редактирование: предполагая символ на самом деле означает «подписанный символ»)
замечают, что регулярное char может вмещать до CHAR_MAX/2 значение, которое равно 127. Если случайное число больше - результат будет обернут вокруг, что приведет к отрицательному значению. поток попытается записать этот символ в виде текстового символа, что является недопустимым значением для записи. бинарный формат должен как минимум исправить эту проблему.

Кроме того, вы не должны закрывать поток самостоятельно здесь, деструктор делает это за вас.

еще две простые точки:
1) &(data[0]) должны быть просто &data[0], то () являются избыточными
2) пытаются сохранить то же самое соглашение. вы пишете верхний верблюд для переменной FilePath, но с нижним верблюжьим футляром для всех других переменных.

+0

'обратите внимание, что обычный символ может содержать значение CHAR_MAX/2, которое составляет 127.' Это не обязательно должно быть правдой. символ «char» может быть подписан или без знака. это реализация определена. – NathanOliver

+0

@NathanOliver хорошо, я каждый день узнаю что-то новое. Я не знал, что char может быть неуправляемым в результате реализации. Я добавил строку –

+0

. О, да, я продолжаю смешивать символ и байт (как определено в .net) ... Не важно в этом случае, хотя – user81993

Смежные вопросы