0

I am learning Java I/O and I've a question for the differences between the two following snippets which both copy a file:

Snippet 1, using FileInput/OutputStream and a byte array:

public static void main(String[] args) throws IOException {
    //function: copy a jpg file
    //1.get a jpg as source file
    File f1 = new File("d:\\LOL.jpg");

    //2.get a target file
    File f2 = new File("d:\\LOL2.jpg");

    //3.using FileInputStream for source file
    FileInputStream fis = new FileInputStream(f1);

    //4.using FileOutputStream for target file
    FileOutputStream fos = new FileOutputStream(f2);

    //5.copy the file by byte array
    byte[] b = new byte[1024*8];
    int len = fis.read(b);
    while(len!=-1){
        fos.write(b,0,len); 
        len = fis.read(b); 
    }

    //6.close stream
    fos.close();
    fis.close();
}

Snippet 2, using BufferedInput/OutputStream

public static void main(String[] args) throws IOException {
    //1.get a jpg as source file
    File f1 = new File("d:\\LOL.jpg");

    //2.get a target file
    File f2 = new File("d:\\LOL2.jpg");

    //3.using FileInputStream for source file
    FileInputStream fis = new FileInputStream(f1);

    //4.using FileOutputStream for target file
    FileOutputStream fos = new FileOutputStream(f2);

    //5.use BufferedInputStream:
    BufferedInputStream bis = new BufferedInputStream(fis);

    //6.use BufferedOutputStream:
    BufferedOutputStream bos = new BufferedOutputStream(fos);

    //7.copy
    byte[] b = new byte[1024*8];
    int len = bis.read(b);
    while(len!=-1){
        bos.write(b,0,len);
        len = bis.read(b);
    }

    //8.close
    bos.close();
    bis.close();

I looked into the source code of BufferedInput/OutputStream and found out that its default buffer size is 1024*8 byte enter image description here

My confuse is that:

  1. what does the inner buffer in BufferedInput/OutputStream actually do? is it just play a same role as the byte array in snippet 1?

  2. If they play a same role, then why BufferedInput/OutputStream is more efficient?

2
  • @user16320675 I measured the time for both of the two methods. Commented Aug 20, 2021 at 15:27
  • @user16320675 I tested my code, and if I set both of the byte array to 1024, then Buffered I/O is much faster, but if I set both of the byte array to 8192 then they are almost the same, the File I/O stream can even be 1 ms faster. Is that because the buffered I/O actually uses the inner buffer as well as the byte array, but the File I/O only uses the byte array? Commented Aug 21, 2021 at 6:26

2 Answers 2

1

is it just play a same role as the byte array in snippet 1?

yes, read/write multiple bytes at once

If they play a same role, then why BufferedInput/OutputStream is more efficient?

it is not more efficient... it will be only if you use the same buffer size and the same operations read/write...

Use a buffer could be even less efficient! if you force to read 1M buffer but you only need the first byte.

The buffer size can drastically influence the efficiency of the same algorithm or make different algorithms go from being the least to the most efficient.

There are also other considerations that drastically influence the operation of distributed systems, since until an output buffer is full, no information reaches the recipient.

A very common effect when some users say that nothing is painted... no, it is not that nothing is painted, it is that the buffer has not been filled and it is necessary to force a dump with some flush operation.

An interesting read in this regard may be: Deadlock-free buffer configuration for stream computing

Stream computing is a popular paradigm for parallel and distributed computing, where compute nodes are connected by first-in first-out data channels. Each channel can be considered as a concatenation of several data buffers, including an output buffer for the sender and an input buffer for the receiver. The configuration of buffer sizes impacts the performance as well as the correctness of the application.

Sign up to request clarification or add additional context in comments.

2 Comments

I tested my code, and if I set both of the byte array to 1024, then Buffered I/O is much faster, but if I set both of the byte array to 8192 then they are almost the same, the File I/O stream can even be 1 ms faster. Is that because the buffered I/O actually uses the inner buffer as well as the byte array, but the File I/O only uses the byte array?
@Lake_Lagunita be careful benchmarking Java code (a lot of aside things could happend), anyway as I said, you'll get this kind of results when change buffer configuration and strategies.
1

The difference is that while an unbuffered is making a write call to the underlying system everytime you give it a byte to write, the buffered output stream is storing the data to be written in a buffer, making the system call to write the data only after calling the flush command. This is to improve performance by reducing I/O Operations called.

https://docs.oracle.com/javase/8/docs/api/java/io/BufferedOutputStream.html https://docs.oracle.com/javase/8/docs/api/java/io/OutputStream.html

1 Comment

Reducing the number of calls does not always imply an improvement in efficiency (e.g. you can have your outputstream consumer bored in the waiting room for something to get to work with).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.