Java reader.readLine() не возвращает точную строку в файле

#java #file #bufferedreader #readline

#java #файл #bufferedreader #readline

Вопрос:

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

 BufferedReader reader = new BufferedReader(
               new InputStreamReader(
                          new FileInputStream("C:\files\myfile.rtf"), StandardCharsets.ISO_8859_1));
    PrintWriter writer = new PrintWriter(new BufferedOutputStream(new FileOutputStream("C:\files\my2file.rtf")));
    String str;

    while ((str = reader.readLine()) != null) {
        System.out.println(str);

    str = str.replace("CivClient", "myname"); // doesn't work
    str = str.replace("AdresseClient", "myname"); // doesn't work
    str = str.replace("lastname", "myname");
    str = str.replace("firstname", "myname");

    }
    writer.close();
    reader.close();
  

выполняя этот код, я обнаружил, что слово «CivClient» отображается не так, как оно есть, а разделено
это часть журнала, а не весь он. вы заметите, что слово отображается не так, как оно есть.
спасибо за ваши усилия. уважаемые stackoverflowers.

Предварительные НАСТРОЙКИ VOS ~:line <}{rtlchfcs1 af0 ltrch fcs0 insrsid5071958 C}{rtlchfcs1 af0 ltrch fcs0 insrsid10116111 iv}{rtlchfcs1 af0 ltrch fcs0 insrsid5071958 C }{ rtlchfcs1 af0 ltrchfcs0 insrsid10116111 lient > <}{rtlchfcs1 af0 ltrch fcs0 insrsid13635392charrsid13635392 lastname }{rtlchfcs1 af0 ltrch fcs0 insrsid10116111 > <}{ rtlchfcs1 af0 ltrch fcs0 insrsid13635392charrsid13635392 firstname }{rtlchfcs1 af0 ltrchfcs0 insrsid10116111 >line <}{rtlchfcs1 af0 ltrch fcs0 insrsid5071958 A }{rtlchfcs1 af0 ltrch fcs0 insrsid10116111 dresse }{rtlchfcs1 af0 ltrch fcs0 insrsid5071958 C }{rtlchfcs1 af0 ltrchfcs0 insrsid10116111 залог>line <}{rtlchfcs1 af0 ltrch fcs0 insrsid13635392 CPClient }{rtlchfcs1 af0 ltrch fcs0 insrsid10116111 > <}{rtlchfcs1 af0 ltrch fcs0 insrsid13635392 VilleClient}{rtlchfcs1 af0 ltrchfcs0 insrsid10116111 >

Комментарии:

1. Пожалуйста, правильно отформатируйте свой пример. Кроме того, пожалуйста, старайтесь не записывать в тот же файл, из которого вы читаете, особенно при использовании другой кодировки. Это может повлиять на результаты. Вместо этого запишите во временный файл и при успешном выполнении удалите старый и скопируйте / переместите временный файл, чтобы заменить его (или, альтернативно, скопируйте содержимое временного файла в исходный файл).

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

3. Не могли бы вы уточнить, как структурированы данные, которые вы читаете, что именно вы получаете на выходе и чего вы ожидаете?

4. Одновременное чтение и запись одного и того же файла — плохая идея, не делайте этого, если не хотите углубиться в особенности файловой системы.

5. да, документ напечатан так четко с другими заполнителями, проблема здесь в том, что некоторые слова в readline () отображаются не так, как другие, и некоторые заменяются, а другие нет, @BreakBB это просто rtf-файл, который я читаю, заполнителем является <CivClient> , но проблема в том, что все остальные слова заменяются только этим. я не читаю и не записываю одновременно, я изменил имя файла.

Ответ №1:

Очевидно, файл содержит RTF, форматированный текст, вместо обычного текста — как уже предлагалось в конце файла .rtf. Также rtlch , вероятно, означает символы справа налево. Вы могли бы использовать swing StyledDocument , RTFEditorKit, для чтения файла.

 Path path = Paths.get("C:\files\myfile.rtf");
byte[] content = Files.readAllBytes(path);
String rtf = new String(content, StandardCharsets.ISO_8859_1);
StringReader in = new StringReader(rtf);
RTFEditorKit kit = new RTFEditorKit();
Document doc = kit.createDefaultDocument();
kit.read(in, doc, 0);
String text = doc.getText(0, doc.getLength());
  

Код немного пошаговый, его можно сразу прочитать — как вы и делали.


Запись текста обратно в файл:

Проблема заключается в природе RTF. Поскольку вы видели, что «CivClient» разделен посередине разными атрибутами RTF, самое простое решение — создать правильный RTF вручную. Удалите мусор в word.

Тогда ваш код работал бы:

 Path path = Paths.get("C:\files\myfile.rtf");
byte[] content = Files.readAllBytes(path);
String str = new String(content, StandardCharsets.ISO_8859_1);
str = str.replace("CivClient", "myname");
str = str.replace("AdresseClient", "myname");
str = str.replace("lastname", "myname");
str = str.replace("firstname", "myname");
content = str.getBytes(StandardCharsets.ISO_8859_1);
Files.write(path, content);
  

ISO-8859-1, Latin-1, представляет собой ограниченный набор символов. Используя преимущества поддержки UTF-16 в RTF:

 str = str.chars()
    .map(ch -> ch < 128 ? Character.toString(ch) : String.format("\uX", (int)ch))
    .collect(Collectors.joining(""));
  

Которая преобразует специальные символы в формат uXXXX .

Комментарии:

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

2. Строка text будет содержать содержимое файла. Если вы хотите отредактировать / изменить файл, это означает изменение документа и запись его обратно. Я попытаюсь добавить код.

Ответ №2:

Либо это так в вашем исходном файле, либо ваша попытка «перезаписать на месте» путем потоковой передачи входных данных при записи в тот же файл вызывает эту проблему. Как правило, записывайте в новый файл, а когда закончите, переместите новый файл поверх старого (после закрытия всех потоков). В качестве альтернативы можно использовать RandomAccessFile и перезаписать на месте, но обратите внимание, что для перезаписи на месте вы не можете удалить или добавить символы (только заменить их). Это ограничение файловых систем, а не java.

ПРИМЕЧАНИЕ: Вы читаете с принудительной кодировкой: ISO_8859_1. Но при записи вы этого не делаете. Это означает, что в любой системе, где кодировка кодировки по умолчанию платформы не является ISO_8859_1, это задание не просто заменит символы CivClient и ‘less than’, оно также перекодирует всю кодировку, возможно, вы захотите исправить и это.

Комментарии:

1. на самом деле я использую 2 разных файла: 1 для записи и один для чтения, что касается принудительного набора символов, я просто хотел попробовать, возможно, функция readline () изменяет вывод. я пробовал использовать none и другие кодировки, но у меня ничего не получилось. всегда одна и та же проблема