前天项目组遇到文件上传,对内存加大的问题。特意看了看相关知识,也对这个有一定的了解
try { FileInputStream fis=new FileInputStream(new File("/home/saas/maven/maven.zip")); BufferedInputStream bis=new BufferedInputStream(fis); FileOutputStream fos=new FileOutputStream(new File("/home/saas/bb.sh")); byte[] buffer=new byte[1024*1024*1024];//这是自定义java缓冲区 int len=0; while((len=bis.read(buffer))>0){// fos.write(buffer, 0, len);//貌似直接就调用了io的底层 // fos.flush(); System.out.println("复制了 1024*1024*1024 Byte"); } fis.close(); fos.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }
首先这里个FileInputtream里面的close方法和flash()方法 不调用也会将文件,这个文件也会被复制成功,并且数据对。原理是这样的,因为fos里面直接调用的本地方法,将数据写入文件,所以不关掉叶能成功,但不关掉会造成内存不能回收,有可能造成内存泄漏什么的
其次,BufferedInputream和BufferedOutputStream 都是提供缓存,可以看到里面有个缓存数组buf[] 默认是8092字节。以下是源码
/** * Writes the specified byte to this buffered output stream. * * @param b the byte to be written. * @exception IOException if an I/O error occurs. */ public synchronized void write(int b) throws IOException { if (count >= buf.length) { flushBuffer(); } buf[count++] = (byte)b; }
这里首先判断一下,当前是缓冲区是否已经满了,如果没满,就继续写,如果满了,就会flushBuffer,flushBuffer其实就是将调用本地方法,将字节数组里的数据写入文件里面,以下是源码
/** Flush the internal buffer */ private void flushBuffer() throws IOException { if (count > 0) { out.write(buf, 0, count); count = 0; } }
当你调用BufferOutputStream 的write.如果传入的是FileInputStream的话,BufferOutputSream 里面的out就会指向FileInputStream。这里使用了装饰模式。
另外可以看到源码,FileInputStream里面的flush是继承OutputStream的,而OutputStream里的flush是个空的方法,什么都没干
时间: 2024-10-06 21:57:16