Как записать в середину файла c

Обновлено: 07.07.2024

В этой статье есть несколько примеров, демонстрирующих различные способы записи текста в файл. В первых двух примерах используются удобные статические методы класса System.IO.File для записи каждого элемента любого объекта IEnumerable<string> и string в текстовый файл. В третьем примере показано, как добавить текст в файл, если необходимо обрабатывать отдельно каждую строку по мере ее записи в файл. В первых трех примерах происходит перезапись всего существующего содержимого файла. В последнем примере показано, как добавить текст в существующий файл.

Запись коллекции строк в файл

Предыдущий пример исходного кода:

Создает экземпляр массива строк с тремя значениями.

  • Асинхронно создает имя файла WriteLines.txt. Если целевой файл уже существует, он будет перезаписан.
  • Записывает заданные строки в файл.
  • Закрывает файл, выполняет автоматическую очистку и удаление по мере необходимости.

Запись одной строки в файл

Предыдущий пример исходного кода:

Создает экземпляр строки с заданным назначенным строковым литералом.

  • Асинхронно создает имя файла WriteText.txt. Если целевой файл уже существует, он будет перезаписан.
  • Записывает заданный текст в файл.
  • Закрывает файл, выполняет автоматическую очистку и удаление по мере необходимости.

Запись выбранных строк из массива в файл

Предыдущий пример исходного кода:

  • Создает экземпляр массива строк с тремя значениями.
  • Создает экземпляр StreamWriter с путем к файлу WriteLines2.txt как с помощью объявления.
  • Выполняет итерацию по всем строкам.
  • Условно ожидает вызов StreamWriter.WriteLineAsync(String), который записывает строку в файл, если строка не содержит "Second" .

Добавление текста в существующий файл

Предыдущий пример исходного кода:

  • Создает экземпляр массива строк с тремя значениями.
  • Создает экземпляр StreamWriter с путем к файлу WriteLines2.txt как с помощью объявления, передавая true для добавления.
  • Ожидает вызов StreamWriter.WriteLineAsync(String), который записывает строку в файл как добавленную строку.

Исключения

При следующих условиях возможно возникновение исключения:

    : Файл существует и является файлом только для чтения. : Имя пути имеет слишком большую длину. : Диск может быть переполнен.

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

Здравствуйте. Интересует вопрос, как можно записать в файл строку, не трогая остальные строки по нужному индексу.

Например, у меня 3 строки в файле:

Мне нужно заменить строку 2 на ййййй :

То что получается у меня, это постоянная перезапись всего файла с помощью fprintf() . Но так не пойдет, у меня там 100 000 записей. Также нужно вставлять строки небольшими блоками (примерно по 60 строк).

Заранее всем спасибо. Использовать можно только функции языка Си.


183k 13 13 золотых знаков 103 103 серебряных знака 208 208 бронзовых знаков А файл открыт на добавление? (В fopen какой режим выбран) Это чтобы он не перезаписывал файл. А по файлу можно ходить через функцию fseek. Возможно я не до конца вас понял. Обновление Fseek умеет переводить курсор внутри файла, там атрибут fsetpos есть он за это отвечает. Будете когда 100000 строк достиг ставить курсор в начало файла SEEK_SET. Почитайте. Понятно. В двух словах я уже ответил и расширенные ответы уже даны. Ишите компромис - или все 100000 строк в память поместяться, или ещё один вспомогательный файл. Другого не дано.

Нежозможно заменить блок в середине файла на блок другого размера, при этом не разрушив последующего содержимого файла. Другими словами - не системном уровне обычно невозможно вставить новое и сместить старое содержимое файла. Если kernel и filesystem поддерживают, то есть очень ограниченная возможность писать в середине файла.

Самое оптимальное решение - открыть оригинал для чтения, читать построчно и добавляя/изменяя писать в новый файл, в конце заменив оригинал новым.

Можно конечно попробовать найти место откуда писать, и начинать оттуда переписывать, т.е. seek() , fread() , seek() и fwrite() , но весь остаток предыдущего содержимого файла должен быть в памяти, и если fwrite() по какой-либо причине не завершится, оригинальный файл будет утерян. Если он дорог как память и надо избежать случая - батарейка села - содержимое памяти надо дублировать в swap с возможностью recovery .

Так что или решение описанное выше, или меняйте формат, или сторонние решения / библиотеки - например Berkeley DB.


50.4k 153 153 золотых знака 54 54 серебряных знака 211 211 бронзовых знаков так делаю но писать 100000 строк сильно дорого когда раз в 5 минут меняются только 60 @Aldmi: А других вариантов нет. Выбранный вами текстовый формат не позволяет модифицировать данные в середине. Меняйте формат. ОСь/filesystem может предоставить (очень ограниченную) возможность работать в середине файла даже если это может изменить его размер без переписывания всего файла. Пример: можно использовать fallocate() , чтобы удалить данные из начала файла @jfs согласен, моё утверждение "совсем невозможно" не совсем верно, скорее надо было что-то нейтральное - ось обычно не поддерживает .

Как вы понимаете, если вставляемая строка не равна по длине той, которую она заменяет - счастья (вставить только ее, не трогая остальные) не получится.

Если вам повезло и она точно такая же по длине - становитесь на нужное место в том же файле с помощью функции fseek и записываете строку с помощью fwrite или той же fprintf .

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

Перезаписывать в другой файл большими блоками просто - выделяете буфер, открываете файлы (исходный и вновь созданный) в бинарном режиме (иначе считать будет трудно), и читаете-пишете блоками с помощью fread и fwrite . Аккуратно отслеживая, сколько именно надо прочитать до искомой строки, затем новую строку, затем переход с помощью fseek за строку, и снова читаете-пишете до конца файла.

Естественно, сначала вам нужно найти, с какой позиции в файле располагается искомая строка.

Если файл небольшой и легко размещается в памяти - проще считать его весь в буфер достаточного размера, с помощью memmove расчистить место под запись строки, обнулить старый файл и записать заново.

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

Как вставить текст в .txt документ, но при этом в определённую строчку? В первом случае надо например на 2-ую строку, не заменяя старое. Во втором под строчку с определённым текстом, так же не заменяя старый текст. Вот актуальный код на запись.

Например, есть текстовый документ и в нём текст:

Нужно, чтобы текст вставился между строками в 1 случае:

А во 2-ом перед определённой строчкой, содержащей bbb

Вот неработающий второй код:

Определенную чем? Порядковым номером, содержимым срок, еще каким-то условием? Строчку надо вставить или перезаписать? Новую поверх старой? Дополните пожалуйста вопрос. нет, работает неправильно стирает старый текст и в целом непонятно работает.

Начнём с критики.

Вы, когда пишете код, обращайте внимание на подсказки Студии (если, конечно, вы не пишете в Блокноте). И читайте документацию.

Первым параметром в конструкторе StreamWriter идёт путь (имя файла). Так дайте ему осмысленное название. Например, общепринятые path или filename .

Второй параметр - append: false означает переписать файл. То есть всё предыдущее содержимое будет потеряно. Просто читайте документацию к используемым классам!

Третье. Никогда не используйте кодировку Default ! На каждом компьютере она своя. В итоге файл, записанный вашей программой на одном компьютере, может не открыться (выдать кракозябры) вашей же программой на другом компьютере.

Укажите какую-либо конкретную кодировку. Если файл предназначен для использования только в вашей программе, то Encoding.Unicode , если будет передаваться куда-либо (по сети) для использования в других программах, то Encoding.UTF8 .

Приведу самые простые способы решения ваших задач.

Используем методы класса File . Читаем и записываем файл с их помощью.

Считанный массив преобразуем в List - этот класс имеет удобный метод Insert , выполняющий нужную нам работу.

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

Если текст, который ищем, расположен не на отдельной строке, а содержится в ней, то меняем сравнение:

Оригинальная версия продукта: Visual Studio
Исходный номер КБ: 816149

Аннотация

В разделе Чтение текстовых файлов этой статьи описывается, как использовать класс для чтения StreamReader текстового файла. Разделы Write a text file (пример 1) и разделы Write a text file (пример 2) описывают, как использовать класс для записи StreamWriter текста в файл.

Чтение текстового файла

Следующий код использует класс для открытия, чтения и закрытия StreamReader текстового файла. Вы можете передать путь текстового файла конструктору, чтобы StreamReader открыть его автоматически. Метод читает каждую строку текста и приращение указателя файла к следующей строке по ReadLine мере чтения. Когда метод достигает конца файла, он возвращает ReadLine ссылку null. Дополнительные сведения см. в группе StreamReader Class.

Создайте пример текстового файла в Блокнот. Выполните приведенные ниже действия.

  1. Вклеить текст hello world в Блокнот.
  2. Сохраните файл как Sample.txt.

Начните Microsoft Visual Studio.

В меню File указать на New, а затем выбрать Project.

Добавьте следующий код в начале файла Class1.cs:

Добавьте в метод следующий Main код:

В меню Отлаговка выберите Пуск для компиляции и запуска приложения. Нажмите КНОПКУ ВВОД, чтобы закрыть окно консоли. В окне Консоли отображается содержимое файла Sample.txt:

Написать текстовый файл (пример 1)

Следующий код использует класс для открытия, записи и закрытия StreamWriter текстового файла. Аналогично классу, вы можете передать путь текстового файла конструктору, чтобы открыть StreamReader StreamWriter его автоматически. Метод WriteLine записывает полную строку текста в текстовый файл.

Запустите Visual Studio.

В меню File указать на New, а затем выбрать Project.

Добавьте следующий код в начале файла Class1.cs:

Добавьте в метод следующий Main код:

В меню Отлаговка выберите Пуск для компиляции и запуска приложения. Этот код создает файл, которыйTest.txt на диске C. Open Test.txt в текстовом редакторе, например Блокнот. Test.txt содержит две строки текста:

Написать текстовый файл (пример 2)

Следующий код использует класс для открытия, записи и закрытия StreamWriter текстового файла. В отличие от предыдущего примера, этот код передает конструктору два дополнительных параметра. Первый параметр — путь к файлу и имя файла. Второй параметр true указывает, что файл открыт в режиме приложения. Если вы указываете для второго параметра, содержимое файла перезаписывается при каждом запуске false кода. Третий параметр Unicode указывает, чтобы StreamWriter кодировать файл в формате Unicode. Можно также указать следующие методы коди-кодинга для третьего параметра:

Метод похож на метод, за исключением того, что метод не автоматически встраит комбинацию символов возврата или строки Write WriteLine Write (CR/LF). Это полезно, когда нужно одновременно писать по одному символу.

Запустите Visual Studio.

В меню Файл выберите пункт Создать и затем пункт Проект.

Добавьте следующий код в начале файла Class1.cs:

Добавьте в метод следующий Main код:

В меню Отлаговка выберите Пуск для компиляции и запуска приложения. Этот код создает файл, которыйTest1.txt на диске C. Open Test1.txt в текстовом редакторе, например Блокнот. Test1.txt содержит одну строку текста: 0123456789.

Полное перечисление кода для чтения текстового файла

Полное перечисление кода для записи текстового файла (версия 1)

Полное перечисление кода для записи текстового файла (версия 2)

Устранение неполадок

Для всех манипуляций с файлами, это хорошая практика программирования, чтобы обернуть код в блок try-catch-finally для обработки ошибок и исключений. В частности, может потребоваться освободить ручки для файла в окончательном блоке, чтобы файл не был заблокирован на неопределенный срок. Некоторые возможные ошибки включают файл, который не существует, или файл, который уже используется.

Читайте также: