Как удалить строку из файла java
Перейти к содержимому

Как удалить строку из файла java

  • автор:

Как удалить строку из файла java

Чтобы удалить строку из файла в Java , вы можете использовать следующий подход:

  1. Создайте новый временный файл.
  2. Прочтите исходный файл построчно, пропуская строки, которые вы хотите удалить.
  3. Записывайте прочитанные строки во временный файл.
  4. Удалите исходный файл.
  5. Переименуйте временный файл в исходное имя файла.
import java.io.*; public class RemoveLineFromFile  public static void main(String[] args)  // имя файла String fileName = "example.txt"; // строка, которую нужно удалить String lineToRemove = "delete me"; try  // создаем временный файл File tempFile = new File("temp.txt"); BufferedWriter writer = new BufferedWriter(new FileWriter(tempFile)); // читаем исходный файл BufferedReader reader = new BufferedReader(new FileReader(fileName)); String currentLine; while ((currentLine = reader.readLine()) != null)  // если текущая строка не равна удаляемой // записываем ее во временный файл if (!currentLine.equals(lineToRemove))  writer.write(currentLine + System.getProperty("line.separator")); > > // закрываем ридер и писатель reader.close(); writer.close(); // удаляем исходный файл File oldFile = new File(fileName); oldFile.delete(); // переименовываем временный файл в исходное имя файла tempFile.renameTo(oldFile); System.out.println("Строка " + lineToRemove + " удалена из файла " + fileName); > catch (IOException ex)  System.out.println("Ошибка при удалении строки из файла " + fileName); ex.printStackTrace(); > > > 

Этот код удалит все строки с текстом «delete me» из файла «example.txt»

15.32.3. Java – Метод delete()

Метод delete() – удаляет символы в подстроке данной строки буфера (StringBuffer). Подстрока начинается с указанного начального индекса и распространяется до символа конечного индекса, или до конца StringBuffer, если такого символа не существует. Другими словами метод позволяет удалить символы из строки, начиная и заканчивая указанными индексами.

Если start (начальный индекс) равен end (конечный индекс), то изменения не производятся.

Синтаксис

public StringBuffer delete(int start, int end) 

Параметры

Подробная информация о параметрах:

  • start – начальный индекс, включительно;
  • end – конечный индекс, не включая.

Возвращаемое значение

  • В Java delete() возвращает объект строки буфера (StringBuffer).

Пример

public class Test < public static void main(String args[]) < StringBuffer sb = new StringBuffer("абвгдеёжз"); sb.delete(3,7); System.out.println(sb); >> 

Получим следующий результат:

абвжз 

Оглавление

  • 1. Java – Самоучитель для начинающих
  • 2. Java – Обзор языка
  • 3. Java – Установка и настройка
  • 4. Java – Синтаксис
  • 5. Java – Классы и объекты
  • 6. Java – Конструкторы
  • 7. Java – Типы данных и литералы
  • 8. Java – Типы переменных
  • 9. Java – Модификаторы
  • 10. Java – Операторы
  • 11. Java – Циклы и операторы цикла
  • 11.1. Java – Цикл while
  • 11.2. Java – Цикл for
  • 11.3. Java – Улучшенный цикл for
  • 11.4. Java – Цикл do..while
  • 11.5. Java – Оператор break
  • 11.6. Java – Оператор continue
  • 12. Java – Операторы принятия решений
  • 12.1. Java – Оператор if
  • 12.2. Java – Оператор if..else
  • 12.3. Java – Вложенный оператор if
  • 12.4. Java – Оператор switch..case
  • 12.5. Java – Условный оператор (? 🙂
  • 13. Java – Числа
  • 13.1. Java – Методы byteValue(), shortValue(), intValue(), longValue(), floatValue(), doubleValue()
  • 13.2. Java – Метод compareTo()
  • 13.3. Java – Метод equals()
  • 13.4. Java – Метод valueOf()
  • 13.5. Java – Метод toString()
  • 13.6. Java – Метод parseInt()
  • 13.7. Java – Метод Math.abs()
  • 13.8. Java – Метод Math.ceil()
  • 13.9. Java – Метод Math.floor()
  • 13.10. Java – Метод Math.rint()
  • 13.11. Java – Метод Math.round()
  • 13.12. Java – Метод Math.min()
  • 13.13. Java – Метод Math.max()
  • 13.14. Java – Метод Math.exp()
  • 13.15. Java – Метод Math.log()
  • 13.16. Java – Метод Math.pow()
  • 13.17. Java – Метод Math.sqrt()
  • 13.18. Java – Метод Math.sin()
  • 13.19. Java – Метод Math.cos()
  • 13.20. Java – Метод Math.tan()
  • 13.21. Java – Метод Math.asin()
  • 13.22. Java – Метод Math.acos()
  • 13.23. Java – Метод Math.atan()
  • 13.24. Java – Метод Math.atan2()
  • 13.25. Java – Метод Math.toDegrees()
  • 13.26. Java – Метод Math.toRadians()
  • 13.27. Java – Метод Math.random()
  • 14. Java – Символы
  • 14.1. Java – Метод Character.isLetter()
  • 14.2. Java – Метод Character.isDigit()
  • 14.3. Java – Метод Character.isWhitespace()
  • 14.4. Java – Метод Character.isUpperCase()
  • 14.5. Java – Метод Character.isLowerCase()
  • 14.6. Java – Метод Character.toUpperCase()
  • 14.7. Java – Метод Character.toLowerCase()
  • 14.8. Java – Метод Character.toString()
  • 15. Java – Строки
  • 15.1. Java – Метод charAt()
  • 15.2. Java – Метод compareTo()
  • 15.3. Java – Метод compareToIgnoreCase()
  • 15.4. Java – Метод concat()
  • 15.5. Java – Метод contentEquals()
  • 15.6. Java – Метод copyValueOf()
  • 15.7. Java – Метод endsWith()
  • 15.8. Java – Метод equals()
  • 15.9. Java – Метод equalsIgnoreCase()
  • 15.10. Java – Метод getBytes()
  • 15.11. Java – Метод getChars()
  • 15.12. Java – Метод hashCode()
  • 15.13. Java – Метод indexOf()
  • 15.14. Java – Метод intern()
  • 15.15. Java – Метод lastIndexOf()
  • 15.16. Java – Метод length()
  • 15.17. Java – Метод matches()
  • 15.18. Java – Метод regionMatches()
  • 15.19. Java – Метод replace()
  • 15.20. Java – Метод replaceAll()
  • 15.21. Java – Метод replaceFirst()
  • 15.22. Java – Метод split()
  • 15.23. Java – Метод startsWith()
  • 15.24. Java – Метод subSequence()
  • 15.25. Java – Метод substring()
  • 15.26. Java – Метод toCharArray()
  • 15.27. Java – Метод toLowerCase()
  • 15.28. Java – Метод toString()
  • 15.29. Java – Метод toUpperCase()
  • 15.30. Java – Метод trim()
  • 15.31. Java – Метод valueOf()
  • 15.32. Java – Классы StringBuilder и StringBuffer
  • 15.32.1. Java – Метод append()
  • 15.32.2. Java – Метод reverse()
  • 15.32.3. Java – Метод delete()
  • 15.32.4. Java – Метод insert()
  • 15.32.5. Java – Метод replace()
  • 16. Java – Массивы
  • 17. Java – Дата и время
  • 18. Java – Регулярные выражения
  • 19. Java – Методы
  • 20. Java – Потоки ввода/вывода, файлы и каталоги
  • 20.1. Java – Класс ByteArrayInputStream
  • 20.2. Java – Класс DataInputStream
  • 20.3. Java – Класс ByteArrayOutputStream
  • 20.4. Java – Класс DataOutputStream
  • 20.5. Java – Класс File
  • 20.6. Java – Класс FileReader
  • 20.7. Java – Класс FileWriter
  • 21. Java – Исключения
  • 21.1. Java – Встроенные исключения
  • 22. Java – Вложенные и внутренние классы
  • 23. Java – Наследование
  • 24. Java – Переопределение
  • 25. Java – Полиморфизм
  • 26. Java – Абстракция
  • 27. Java – Инкапсуляция
  • 28. Java – Интерфейсы
  • 29. Java – Пакеты
  • 30. Java – Структуры данных
  • 30.1. Java – Интерфейс Enumeration
  • 30.2. Java – Класс BitSet
  • 30.3. Java – Класс Vector
  • 30.4. Java – Класс Stack
  • 30.5. Java – Класс Dictionary
  • 30.6. Java – Класс Hashtable
  • 30.7. Java – Класс Properties
  • 31. Java – Коллекции
  • 31.1. Java – Интерфейс Collection
  • 31.2. Java – Интерфейс List
  • 31.3. Java – Интерфейс Set
  • 31.4. Java – Интерфейс SortedSet
  • 31.5. Java – Интерфейс Map
  • 31.6. Java – Интерфейс Map.Entry
  • 31.7. Java – Интерфейс SortedMap
  • 31.8. Java – Класс LinkedList
  • 31.9. Java – Класс ArrayList
  • 31.10. Java – Класс HashSet
  • 31.11. Java – Класс LinkedHashSet
  • 31.12. Java – Класс TreeSet
  • 31.13. Java – Класс HashMap
  • 31.14. Java – Класс TreeMap
  • 31.15. Java – Класс WeakHashMap
  • 31.16. Java – Класс LinkedHashMap
  • 31.17. Java – Класс IdentityHashMap
  • 31.18. Java – Алгоритмы Collection
  • 31.19. Java – Iterator и ListIterator
  • 31.20. Java – Comparator
  • 32. Java – Дженерики
  • 33. Java – Сериализация
  • 34. Java – Сеть
  • 34.1. Java – Обработка URL
  • 35. Java – Отправка Email
  • 36. Java – Многопоточность
  • 36.1. Java – Синхронизация потоков
  • 36.2. Java – Межпоточная связь
  • 36.3. Java – Взаимная блокировка потоков
  • 36.4. Java – Управление потоками
  • 37. Java – Основы работы с апплетами
  • 38. Java – Javadoc

Удаление строки из текстового файла в программе на java swing

Есть у меня программа типа словаря, в которой есть кнопка удалить. Задача такая, мне нужно найти строку в текстовом файле, и удалить её. Находить, я нахожу, но вот удалять строку я не научился. Пробовал такой вот метод

private void DeleteActionPerformed(java.awt.event.ActionEvent evt) < String filePath = "Dictio.txt"; String outputLine = jTextField3.getText(); String line=null; jTextField3.setText(" "); try < BufferedReader reader = new BufferedReader(new FileReader(new File("Dictio.txt"))); BufferedWriter out1 = new BufferedWriter(new FileWriter(new File("Dictio.txt"))); while((line = reader.readLine()) != null)< if(line.contains(outputLine))< out1.newLine(); out1.write(""); out1.close(); >> // закрываем > catch (Exception e) < System.err.println("Error in file cleaning: " + e.getMessage()); >> 

Но получается пока удалять все содержимое из файла, а надо только заранее найденную строку.
Отслеживать
56k 10 10 золотых знаков 83 83 серебряных знака 136 136 бронзовых знаков
задан 20 мая 2016 в 16:32
45 1 1 серебряный знак 5 5 бронзовых знаков

3 ответа 3

Сортировка: Сброс на вариант по умолчанию

В приведённом Вами коде присутствует сразу несколько грубейших ошибок:

  • Вы записываете данные сразу в тот же файл из которого их только что прочитали;
  • Вы записываете в файл пустую строку;
  • После записи первой строки Вы сразу же закрываете файл.

В итоге получается описанный Вами результат.

Чтобы этого не было:

  1. Создаём две файловые переменные. File sourceFile = new File(«Dictio.txt»); File outputFile = new File(«Dictio2.txt»);
  2. Записываем в новый файл все данные, кроме удаляемой строки. BufferedReader reader = new BufferedReader(new FileReader(sourceFile)); BufferedWriter writer = new BufferedWriter(new FileWriter(outputFile)); while ((line = reader.readLine()) != null) < if (!line.equals(outputLine)) < writer.write(line); writer.newLine(); >>
  3. Затем удаляем исходный файл, а получившийся файл переименовываем. reader.close(); writer.close(); sourceFile.delete(); outputFile.renameTo(sourceFile);

P.S.

В данной ситуации, ИМХО, более рациональным решением было бы прочитать файл в строковый массив, а затем удалить в нём нужную строку и перезаписать исходный файл с новыми данными.

Отслеживать
ответ дан 20 мая 2016 в 17:35
11.7k 9 9 золотых знаков 28 28 серебряных знаков 40 40 бронзовых знаков
Тут есть какая то ошибка. Срабатывает IOException.
20 мая 2016 в 18:46

Ошибок нет. Алгоритм рабочий. Судя по всему, что-то сделали не так. Просто, нужно хотя бы немного разобраться, а не копировать в свой проект «в лоб». Без обид. Выкладывайте код, как пытались применить решение из ответа, и stack trace исключения. Комментарии из категории «у меня не получается и всё» здесь не прокатывают.

20 мая 2016 в 21:00

Как вставлять код в комментарии я не знаю (F.A.Q. показанный внизу я не понял). Но делал примерно так, сначала задал outputLine так, как задал его в своем первоначальном варианте. Затем объявил переменную таким образом- String line; . Потом объявил два файла как указанно у вас в примере. Основную часть с записью в файл кроме удаляемой строки я окружил try/catch. И в этом же блоке перед самым catch задал удаление исходного и переименовывание нового файла. И исключение выглядит так java.io.IOException: Stream closed

Затирание файлов в Java

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

И кажется, в этом проблемы нет. В стандартной библиотеке Java есть метод delete() в классе java.io.File для удаления файла.

File file = new File("path/to/file"); if (file.delete()) < System.out.println(file.getName() + " deleted"); >else

Метод delete() в классе java.io.File вызывает под капотом нативную функцию для удаления файла в зависимости от ОС. А современные ОС при удалении файла сразу не удаляют файл, а только удаляют имя файла. Содержимое файла остается, и память занимаемая под уже удаленный файл может быть в будущем переиспользована. Но все таки некоторое время кажется уже удаленный файл является доступный.

И если посмотреть на просторы интернета, то имеется немало программ для восстановления удаленных файлов, например Recuva.

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

Поскольку приложения разрабатовалось в Ubuntu, то эта ОС предоставляет немало готовых решений в виде утилит командной строки. Например, утилита secure-delete, которая позволяет удалять файлы без востановления используя разные подходы.

$ srm -vz private/* 

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

Что очень не удобно и хочется уйти от этих проблем. Если посмотреть исходный код утилиты secure-delete, то она позволяет работать под разные операционные системы. Написана на С99 и использует разную препроцессорную магию и платформо-зависимый API. Отлаживать такой нативный код в случае ошибки очень сложно и еще та задача.

Если разобраться как работает утилита secure-delete, то можно выделить следующие этапы.

  • сначала проверяется существует ли файл и корректность прав.
  • в зависимости от указаного алгоритма перезаписывает содержимое файла.
  • сокращает размер файла к нуль байтам.
  • переименовует файл рандомной последовательностю символов.
  • удаляет файл.
  • Simple алгоритм — перезаписывает 1 проходом 0x00 байтами.
  • DOE алгоритм — перезаписывает 3 проходами random, random, «DoE».
  • RCMP алгоритм — перезаписывает 3 проходами 0x00 ,0xFF, «RCMP».
  • OPENBSD алгоритм — перезаписывает 3 проходами 0xFF, 0x00, 0xFF байтами.
  • DOD алгоритм — перезаписывает 7 проходами.
  • Gutmann алгоритм — перезаписывает 35 проходами.

Для того чтобы проверить существует ли файл и имеет ли он корректные права можно использовать std::filesystem, которая была добавлена в C++17.

Для предыдущих версий стандарта можно использовать boost::filesystem.

namespace fs = std::filesystem; if (!fs::exists(file)) < env->ThrowNew(exception_class, "File doesn't exist"); > if (!fs::is_regular_file(file)) < env->ThrowNew(exception_class, "Path doesn't regular file or symlink"); > if (!eraser.check_permision(file, fs::status(file).permissions())) < env->ThrowNew(exception_class, "File hasn't enough permision (maybe not user)"); > bool kl::erase_content::check_permision(const fs::path& entry, fs::perms permision) < try < fs::permissions(entry, fs::perms::owner_read | fs::perms::owner_write, fs::perm_options::add); return true; >catch (fs::filesystem_error& e) < return false; >> 

Для перезаписывания содержимого файла в зависимости от выбраного алгортма можно оставить реализацию, как в secure-delete.

bool kl::erase_content::overwrite() < switch (entry.get_mode()) < case kl::overwrite_mode::SIMPLE_MODE: if (!overwrite_byte(1, 0x00)) < return false; >break; case kl::overwrite_mode::DOE_MODE: if (!overwrite_random(1)) < return false; >if (!overwrite_random(2)) < return false; >if (!overwrite_bytes(3, "DoE")) < return false; >break; case kl::overwrite_mode::OPENBSD_MODE: /* override OPENBSD_MODE method */ break; case kl::overwrite_mode::RCMP_MODE: /* override RCMP_MODE method */ break; case kl::overwrite_mode::DOD_MODE: /* override DOD_MODE method */ break; case kl::overwrite_mode::GUTMAN_MODE: /* override GUTMAN_MODE method */ break; default: std::cerr return true; > 

Заполняется буфер определеного размера, определеным набором данных, в зависимости от алгоритма и записывает это буфер в файл, пока не достигнет конца.

bool kl::erase_content::overwrite_byte(const int pass, const uint8_t byte) < const auto& [file_name, file_size, buffer_size, mode] = entry; this->buffer = std::make_unique(buffer_size); std::memset(buffer.get(), byte, buffer_size); this->file = kl::fs_util::make_open_file(file_name, "r+b"); if (!overwrite_data(pass)) < return false; >return true; > bool kl::erase_content::overwrite_data(const int pass) < const auto& [file_name, file_size, buffer_size, mode] = entry; const size_t count = file_size / buffer_size; const size_t tail = file_size % buffer_size; size_t writted = 0; if (fseek(file.get(), 0, SEEK_SET) != 0) < std::cerr writted = write_buffer(count, tail); if (writted != file_size) < std::cerr fflush(file.get()); if (fseek(file.get(), 0, SEEK_SET) != 0) < std::cerr file.reset(); return true; > 

Потом сократим размер файла к нуль байтам, используя для этого функцию std::filesystem::resize_file().

try < fs::resize_file(file, 0); >catch (fs::filesystem_error& e) < env->ThrowNew(exception_class, "truncate file fail"); > 

Следующим этапом переименовуем файл рандомной последовательностю символов, используя для этого std::random() и std::filesystem::file::replace_filename().

std::string parent_path = file.parent_path(); std::string file_name = file.filename(); fs::path copy_file = file; file_name = random_text(file_name.size()); copy_file.replace_filename(fs::path(file_name)); try < fs::rename(file, copy_file); >catch (fs::filesystem_error& e) < env->ThrowNew(exception_class, "can't rename file"); > return true; 

И на завершающем этапе нужно просто удалить файл, используя для этого std::filesystem::remove().

try < fs::remove(copy_file); >catch (fs::filesystem_error& e) < env->ThrowNew(exception_class, "can't remove file"); > 

Ну и для использования на Java нужно объявить нативные методы.

public class EraseFS < static < System.loadLibrary("jefl"); >public static native boolean eraseFile(String path) throws EraseException; public static native boolean eraseFile(String path, OverwrideMode mode) throws EraseException; public static native boolean eraseFiles(String. paths) throws EraseException; public static native boolean eraseFiles(OverwrideMode mode, String. paths) throws EraseException; public static native boolean eraseDirectory(String path, boolean recursived) throws EraseException; public static native boolean eraseDirectory(String path, OverwrideMode mode, boolean recursived) throws EraseException; > 

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

Стандарт С++17 уже поддерживают все популярные компиляторы: MVSC, Clang, GCC.
Полный исходной код можно посмотреть на github: code.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *