c ++ перезаписывает данные файла?

0

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

1 Information 15e+10

2 Information 2e+16

3 Information 6e+2

И так далее.

Эти файлы могут быть очень большими в диапазоне нескольких гигабайт и, насколько мне известно, из-за этого с использованием буфера всего файла и перезаписи всего файла невозможно/необоснованно. Ну, все в порядке, я просто хочу заменить значения (например, 15e+10).

Все это прекрасно работает с простыми ios::in|ios::out и tellp() если я tellp() значение с аналогичным размером (15e+1012e+12) или даже если его размер меньше, чем я могу просто добавьте дополнительное пространство, которое можно игнорировать по строке (например, 15e+104e+10). Но я столкнулся с проблемой, если мне нужно заменить значение значением, длина которого больше, чем уже в файле (например, 6e+216e+10), он будет писать поверх нового символа строки или начать писать поверх информацию в следующей строке.

Я искал на форумах, и все говорят, что вы можете либо перезаписать в файле, либо добавить в конец файла, либо вы можете буферизовать и воссоздать весь файл. В любом случае, я могу достичь своей цели правильно записать значение, не создавая файл?

Если нет, то как я могу открыть 2 файла (1 вход 1 вывод), если несколько файлов, о которых идет речь, слишком велики для памяти?

Примечание. Я также хотел бы избежать использования boost:: поскольку мне нужно иметь возможность запускать это в системе без библиотеки boost.

Теги:
file-io

3 ответа

1

Откройте поток для чтения из входного (IN) файла и второго потока (OUT) для записи в новый файл вывода (tmp).

Чтение из IN и запись в OUT. Когда вы получите значение от IN, которое вы хотите заменить, замените OUT на значение вместо значения, которое вы получили от IN.

Когда синтаксический анализ завершен, замените первый файл вторым (tmp) файлом.

Будет ли это работать для вас?

  • 0
    Мне нравится идея, но в этом случае мне нужно, чтобы оба файла открывались одновременно file1.open (ios :: in) и file2.open (ios :: out), что означает, что они будут храниться в памяти так, Вы можете получить к ним быстрый доступ, правильно? В этом случае мне нужно было бы сделать файлы значительно меньше или мне потребовалось бы использовать суперкомпьютер с >> 8 ГБ ОЗУ.
  • 1
    @JCline - Нет, оба файла не хранятся в памяти. Методы файла C ++ и API операционной системы под ним будут управлять буферизацией для вас. Вы можете спокойно игнорировать размеры файлов, насколько использование памяти идет.
0

Вы можете использовать seekp для перехода к местоположению и переписать его с помощью <<

Пример:

example.txt (|? | = 1 байт данных)

| A | B | C |\п | 1 | 2 | 3 | D | E | F |\п | 4 | 5 | 6 |

//Somewhere in the code

fstream file;

open("example.txt");

//Somehow find the character distance and store it into "distance"

seekp(distance);//If distance = 0, it will go to "A" like rewind() but easier for me

Если расстояние равно 4, следующий символ будет перезаписан: 1

file << "987";

И файл будет

| | B | C |\п | 9 | 8 | 7 | D | E | F |\n | 4 | 5 | 6 |

НО только проблема здесь, когда вам нужно увеличить/уменьшить размер:

Увеличение:

Вы перезапишете другого персонажа, чтобы создать временную строку для хранения остальной части данных или разделить ее на меньший фрагмент, если данные слишком велики, как

| | B | C |\п | 9 | 8 | 7 | D | E | F |\n | 4 | 5 | 6 |

string tempstring;
seekp(distance);
file >> tempstring;
seekp(distance);
file << content << tempstring;  //content is the data

Уменьшение:

Самое простое решение - записать NULL-символ \0 в избыточное пространство, например

| | B | C |\п | 1 | \ 0 | \ 0 | D | E | F |\n | 4 | 5 | 6 |

Единственный побочный эффект - размер файла такой же, как и раньше

0

Используйте lseek()/fseek() для "перехода" в заданную позицию в файле.

  • 0
    Как это решает проблему перезаписи (третий случай в OP)?
  • 0
    Вы должны установить фиксированное пространство для хранения каждого элемента, например, 12 байт, тогда вам не нужно беспокоиться о различной длине элемента. Когда данные короче 12 байт, будет некоторая слабость.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню