IO流是Java中很重要的一块知识,但凡项目中十有八九会用到这块,比如上传、下载,或者导入导出也是基于流操作资源。
Java中流 一共分为两个大类,一字符流Reader,二 字节流OutputStream。
字符流:顾名思义就是操作存文本数据。
字节流:可操作音频、视频、图片以及其他多媒体资源。能有字符流操作的数据,都可以使用字节流,反过来就不行,因为会乱码。
字符流又分为字符输入流FileReader、字符输出流FileWriter
字符流有read()重载方法,可以读取一个字符,也可以读取一个字符数组,当读到最后没有数据时,返回-1。
有读的方法,就有写的方法,同样提供writer()重载方法,可以一次写入一个字符,也可以一次字符数组。
直接上代码
@Test public void testReader() { Reader reader = null; Writer writer = null; try { //加载源文件 reader = new FileReader("E:\\temp\\xx.txt"); //初始化输出流对象 writer = new FileWriter("E:\\temp\\dd.txt"); //初始化字符数组一次读取1024 char[] chars = new char[1024]; int len = 0; //开始时间 long start = System.currentTimeMillis(); int temp = 0; while ((len = reader.read(chars)) != -1) { //一次写入一个数组,从0开始 writer.write(chars, 0, len); writer.flush(); temp++; System.out.println("当前正在执行第 {" + temp + "} 次"); } //结束时间 long end = System.currentTimeMillis(); System.out.println("时间:" + (end - start)); } catch (Exception e) { e.printStackTrace(); } finally { try { if (reader != null) { reader.close(); } if (writer != null) { writer.close(); } } catch (Exception e) { e.printStackTrace(); } } }
说完了字符流,说下字节流,其实大部分操作都是相同的。
字节流分为字节输入流FileIntputStream以及字节输出流FileOutputStream
字节输入流也有重载的read()方法,可一次读取一个字节,亦可以 一次读取一个字节数组,大小自己定义(结合实际需求,不可过大或者过小)
同样字节输出流有重载的writer()方法,可一次写入一个字节,也可以一次写入一个字节数组。
例如
@Test public void testCopyFile() { String name = "E:\\temp\\xx.txt"; InputStream is = null; OutputStream os = null; try { is = new FileInputStream(name); os = new FileOutputStream("E:\\temp\\QW.txt"); int len = 0; byte[] ch = new byte[1024]; long staer = System.currentTimeMillis(); int temp = 0; while ((len = is.read(ch)) != -1) { os.write(ch, 0, len); os.flush(); temp++; System.out.println("正在执行 {" + temp + "} 次"); } long end = System.currentTimeMillis(); System.out.println("时间:" + (end - staer)); } catch (Exception e) { e.printStackTrace(); } finally { try { if (os != null) { os.close(); } if (is != null) { is.close(); } } catch (Exception e) { e.printStackTrace(); } } }
IO流中还有一块重要的知识,就是高效流。无论是字符流还是字节流都有自己的高效流。因为我们正常从一个磁盘复制到另外一个磁盘时候,如果文件比较大,频繁的读写数据,对系统内存消耗很大,所以Java提供了这个高效流。说直白一点 就是读取的文件 暂时存放到缓冲区,然后从缓冲区中拿出数据,写到另外一个磁盘中,这样就大大节省了频繁读取的时间。直接上代码
@Test public void testBufferCopyFile() { //初始化输入流 InputStream is = null; //初始化输出流 OutputStream os = null; //初始化高效输入流 BufferedInputStream bis = null; //初始化高效输出流 BufferedOutputStream bos = null; try { is = new FileInputStream("E:\\temp\\xx.txt"); os = new FileOutputStream("E:\\temp\\buffer.txt"); bis = new BufferedInputStream(is); bos = new BufferedOutputStream(os); int len = 0; byte[] bytes = new byte[1024*10]; long start = System.currentTimeMillis(); while ((len = bis.read(bytes)) != -1) { bos.write(bytes, 0, len); bos.flush(); } long end = System.currentTimeMillis(); System.out.println("时间:"+(end-start)); } catch (Exception e) { e.printStackTrace(); } finally { if (bos != null) { try { bos.close(); } catch (Exception e) { e.printStackTrace(); } } if (bis != null) { try { bis.close(); } catch (Exception e) { e.printStackTrace(); } } } }
另外高效流这块也是使用了装饰者模式,在不改变原有方式的情况下 对现有的输入流、输出流的读写行为进行增强,这个还需研究。。。。。