Java file not written to stream with new line char

2020-03-24 07:55发布

We're streaming a CSV file from a web service. It appears that we're losing the new line characters when streaming - the client gets the file all on a single line. Any idea what we're doing wrong?

Code:

 public static void writeFile(OutputStream out, File file) throws IOException {
    BufferedReader input = new BufferedReader(new FileReader(file)); //File input stream 
    String line;
    while ((line = input.readLine()) != null) { //Read file
        out.write(line.getBytes());  //Write to output stream 
        out.flush();
    }
    input.close();
} 

6条回答
男人必须洒脱
2楼-- · 2020-03-24 08:29

There are several things wrong with that code. It may also mutilate any NON-ASCII text since it converts via the platform default encoding twice - and for no good reason at all.

Don't use a Reader to read the file, use a FileInputStream and transfer bytes, avoiding the unnecessary and potentially destructive charset conversions. The line break problem will also be gone.

查看更多
孤傲高冷的网名
3楼-- · 2020-03-24 08:32

The readline method uses the newline chars to delimit what gets read, so the newlines themselves are not returned by readLine.

Don't use readline, you can use a BufferedInputStream and read the file one byte at a time if you want, or pass your own buffer into OutputStream.write.

Note that, like BalusC and Michael Borgwardt say, Readers and Writers are for text, if you just want to copy the file you should use InputStream and OutputStream, you are only concerned with bytes.

查看更多
唯我独甜
4楼-- · 2020-03-24 08:33

Any idea what we're doing wrong?

Yes. This line drops the "new line character"

while ((line = input.readLine()) != null) {

And then you write it without it:

 out.write(line.getBytes());

This this related question.

查看更多
狗以群分
5楼-- · 2020-03-24 08:37

BufferedReader.ReadLine() does not preserve the newline. Thus you'll have to add it when writing it out

查看更多
SAY GOODBYE
6楼-- · 2020-03-24 08:49

Don't use BufferedReader. You already have an OutputStream at hands, so just get an InputStream of the file and pipe the bytes from input to output it the usual Java IO way. This way you also don't need to worry about newlines being eaten by BufferedReader:

public static void writeFile(OutputStream output, File file) throws IOException {
    InputStream input = null;
    byte[] buffer = new byte[10240]; // 10KB.
    try {
        input = new FileInputStream(file);
        for (int length = 0; (length = input.read(buffer)) > 0;) {
            output.write(buffer, 0, length);
        }
    } finally {
        if (input != null) try { input.close(); } catch (IOException logOrIgnore) {}
    }
}

Using a Reader/Writer would involve character encoding problems if you don't know/specify the encoding beforehand. You actually also don't need to know about them here. So just leave it aside.

To improve performance a bit more, you can always wrap the InputStream and OutputStream in an BufferedInputStream and BufferedOutputStream respectively.

查看更多
【Aperson】
7楼-- · 2020-03-24 08:52

You can use a PrintWriter which offers a prinln() method. This will also save you from converting the string into an array of chars.

public static void writeFile(OutputStream o, File file) throws IOException {
   PrintWriter out = new PrintWriter(new OutputStreamWriter(o));
   BufferedReader input = new BufferedReader(new FileReader(file)); //File input stream 
   String line;
   while ((line = input.readLine()) != null) { //Read file
       out.println(line);  //Write to output stream 
       out.flush();
   }
   input.close();
}  
查看更多
登录 后发表回答