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

My confuse is that:
what does the inner buffer in BufferedInput/OutputStream actually do? is it just play a same role as the byte array in snippet 1?
If they play a same role, then why BufferedInput/OutputStream is more efficient?