Как записать в середину файла c
В этой статье есть несколько примеров, демонстрирующих различные способы записи текста в файл. В первых двух примерах используются удобные статические методы класса 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 строк).
Заранее всем спасибо. Использовать можно только функции языка Си.
Нежозможно заменить блок в середине файла на блок другого размера, при этом не разрушив последующего содержимого файла. Другими словами - не системном уровне обычно невозможно вставить новое и сместить старое содержимое файла. Если kernel и filesystem поддерживают, то есть очень ограниченная возможность писать в середине файла.
Самое оптимальное решение - открыть оригинал для чтения, читать построчно и добавляя/изменяя писать в новый файл, в конце заменив оригинал новым.
Можно конечно попробовать найти место откуда писать, и начинать оттуда переписывать, т.е. seek() , fread() , seek() и fwrite() , но весь остаток предыдущего содержимого файла должен быть в памяти, и если fwrite() по какой-либо причине не завершится, оригинальный файл будет утерян. Если он дорог как память и надо избежать случая - батарейка села - содержимое памяти надо дублировать в swap с возможностью recovery .
Так что или решение описанное выше, или меняйте формат, или сторонние решения / библиотеки - например Berkeley DB.
Как вы понимаете, если вставляемая строка не равна по длине той, которую она заменяет - счастья (вставить только ее, не трогая остальные) не получится.
Если вам повезло и она точно такая же по длине - становитесь на нужное место в том же файле с помощью функции 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.
Создайте пример текстового файла в Блокнот. Выполните приведенные ниже действия.
- Вклеить текст hello world в Блокнот.
- Сохраните файл как 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 для обработки ошибок и исключений. В частности, может потребоваться освободить ручки для файла в окончательном блоке, чтобы файл не был заблокирован на неопределенный срок. Некоторые возможные ошибки включают файл, который не существует, или файл, который уже используется.
Читайте также: