Символ новой строки пропущен при чтении из буфера

Я написал следующий код:

public class WriteToCharBuffer {

 public static void main(String[] args) {
  String text = "This is the data to write in buffer!\nThis is the second line\nThis is the third line";
  OutputStream buffer = writeToCharBuffer(text);
  readFromCharBuffer(buffer);
 }

 public static OutputStream writeToCharBuffer(String dataToWrite){
  ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
  BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(byteArrayOutputStream));
  try {
   bufferedWriter.write(dataToWrite);
   bufferedWriter.flush();
  } catch (IOException e) {
   e.printStackTrace();
  }
  return byteArrayOutputStream;
 }

 public static void readFromCharBuffer(OutputStream buffer){
  ByteArrayOutputStream byteArrayOutputStream = (ByteArrayOutputStream) buffer;
  BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(byteArrayOutputStream.toByteArray())));
  String line = null;
  StringBuffer sb = new StringBuffer();
  try {
   while ((line = bufferedReader.readLine()) != null) {
    //System.out.println(line);
    sb.append(line);
   }
   System.out.println(sb);
  } catch (IOException e) {
   e.printStackTrace();
  }

 }
}

Когда я выполняю приведенный выше код, следующий вывод:

This is the data to write in buffer!This is the second lineThis is the third line

Почему символы новой строки (\n) пропускаются? Если я раскомментирую System.out.println() следующим образом:

while ((line = bufferedReader.readLine()) != null) {
        System.out.println(line);
        sb.append(line);
       }

Я получаю правильный вывод как:

This is the data to write in buffer!
This is the second line
This is the third line
This is the data to write in buffer!This is the second lineThis is the third line

В чем причина?

7 ответов

Решение

JavaDoc говорит

public String readLine()
                throws IOException

Читает строку текста. Строка считается завершенной любым из перевода строки ('\n'), возврата каретки ('\r') или возврата каретки, за которым сразу следует перевод строки.
Возвращает:
Строка, содержащая содержимое строки, не включая символы окончания строки, или ноль, если достигнут конец потока
Броски:

Из Javadoc

Прочитайте строку текста. Строка считается завершенной любым из перевода строки ('\ n'), возврата каретки ('\r') или возврата каретки, за которым сразу следует перевод строки.

Вы можете сделать что-то подобное

buffer.append(line);
buffer.append(System.getProperty("line.separator"));

На всякий случай, если кто-то захочет прочитать текст '\n' включен.

попробуйте этот простой подход

Так,

Скажем, у вас есть три строки данных (скажем, в .txt файл), вот так

This is the data to write in buffer!
This is the second line
This is the third line

И во время чтения вы делаете что-то вроде этого

    String content=null;
    String str=null;
    while((str=bufferedReader.readLine())!=null){ //assuming you have 
    content.append(str);                     //your bufferedReader declared.
    }
    bufferedReader.close();
    System.out.println(content);

и ожидая, что результат будет

This is the data to write in buffer!
This is the second line
This is the third line

но почесывая голову, увидев вывод в виде одной строки

This is the data to write in buffer!This is the second lineThis is the third line

Вот что вы можете сделать

добавив этот кусок кода внутри цикла while

if(str.trim().length()==0){
   content.append("\n");
}

Так что теперь, что ваш while петля должна выглядеть так

while((str=bufferedReader.readLine())!=null){
    if(str.trim().length()==0){
       content.append("\n");
    }
    content.append(str);
}

Теперь вы получите необходимый вывод (как три строки текста)

This is the data to write in buffer!
This is the second line
This is the third line

Это то, что javadocs говорит для метода readLine() класса BufferedReader

 /**
 * Reads a line of text.  A line is considered to be terminated by any one
 * of a line feed ('\n'), a carriage return ('\r'), or a carriage return
 * followed immediately by a linefeed.
 *
 * @return     A String containing the contents of the line, not including
 *             any line-termination characters, or null if the end of the
 *             stream has been reached
 *
 * @exception  IOException  If an I/O error occurs
 */

Это из-за readLine(). Из документов Java:

Прочитайте строку текста. Строка считается завершенной любым из перевода строки ('\n'), возврата каретки ('\r') или возврата каретки, за которым сразу следует перевод строки.

Итак, что происходит, так это то, что ваш "\n" рассматривается как перевод строки, поэтому читатель считает, что это строка.

readline() не возвращает окончание строки платформы. JavaDoc.

Я столкнулся с аналогичной проблемой из ByteArrayInputStream, где содержимое файла загружается в виде массива байтов из базы данных и читается через IOUtils.readlines().

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

"Заголовок\\nСтрока1\\nСтрока2"

Мне пришлось написать отдельный код для замены символов от '\\n' до '\n' путем преобразования массива байтов в строку для замены строк и снова преобразовать обратно в массив байтов из вновь сформированной строки, и это сработало для меня .

Другие вопросы по тегам