IO流原理及流的分类:Java IO原理
流的分类
一、流的分类: 1 2 3 * 1. 操作数据单位:字节流、字符流 * 2. 数据的流向:输入流、输出流 * 3. 流的角色:节点流、处理流
二、流的体系结构
抽象基类
节点流(或文件流)
缓冲流(处理流的一种)
InputStream
FileInputStream (read(byte[] buffer))
BufferedInputStream (read(byte[] buffer))
OutputStream
FileOutputStream (write(byte[] buffer,0,len)
BufferedOutputStream (write(byte[] buffer,0,len) / flush()
Reader
FileReader (read(char[] cbuf))
BufferedReader (read(char[] cbuf) / readLine())
Writer
FileWriter (write(char[] cbuf,0,len)
BufferedWriter (write(char[] cbuf,0,len) / flush()
节点流-字符流(FileReader)-输入 1 2 3 4 5 6 将day09下的hello.txt文件内容读入程序中,并输出到控制台 说明点: 1. read()的理解:返回读入的一个字符。如果达到文件末尾,返回-1 2. 异常的处理:为了保证流资源一定可以执行关闭操作。需要使用try -catch -finally 处理3. 读入的文件一定要存在,否则就会报FileNotFoundException。
代码示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 @Test public void testFileReader () { FileReader fr = null ; try { File file = new File("hello.txt" ); fr = new FileReader(file); int data; while ((data = fr.read()) != -1 ){ System.out.print((char )data); } } catch (IOException e) { e.printStackTrace(); } finally { if (fr != null ){ try { fr.close(); } catch (IOException e) { e.printStackTrace(); } } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 @Test public void testFileReader1 () { FileReader fr = null ; try { File file = new File("hello.txt" ); fr = new FileReader(file); char [] cbuf = new char [5 ]; int len; while ((len = fr.read(cbuf)) != -1 ){ String str = new String(cbuf,0 ,len); System.out.print(str); } } catch (IOException e) { e.printStackTrace(); } finally { if (fr != null ){ try { fr.close(); } catch (IOException e) { e.printStackTrace(); } } } }
节点流-字符流(FileWriter)-输出 1 2 3 4 5 6 7 8 9 从内存中写出数据到硬盘的文件里。 说明: 1. 输出操作,对应的File可以不存在的。并不会报异常2. File对应的硬盘中的文件如果不存在,在输出的过程中,会自动创建此文件。 File对应的硬盘中的文件如果存在: 如果流使用的构造器是:FileWriter(file,false ) / FileWriter(file):对原有文件的覆盖 如果流使用的构造器是:FileWriter(file,true ):不会对原有文件覆盖,而是在原有文件基础上追加内容
代码示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 @Test public void testFileWriter () { FileWriter fw = null ; try { File file = new File("hello1.txt" ); fw = new FileWriter(file,false ); fw.write("I have a dream!\n" ); fw.write("you need to have a dream!" ); } catch (IOException e) { e.printStackTrace(); } finally { if (fw != null ){ try { fw.close(); } catch (IOException e) { e.printStackTrace(); } } } }
使用FileReader和FileWreter实现文本文件的复制 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 @Test public void testFileReaderFileWriter () { FileReader fr = null ; FileWriter fw = null ; try { File srcFile = new File("hello.txt" ); File destFile = new File("hello2.txt" ); fr = new FileReader(srcFile); fw = new FileWriter(destFile); char [] cbuf = new char [5 ]; int len; while ((len = fr.read(cbuf)) != -1 ){ fw.write(cbuf,0 ,len); } } catch (IOException e) { e.printStackTrace(); } finally { try { if (fw != null ) fw.close(); } catch (IOException e) { e.printStackTrace(); } try { if (fr != null ) fr.close(); } catch (IOException e) { e.printStackTrace(); } } }
节点流-字节流-输入与输出
1.字节流操作文本文件测试(操作台看时可能出现乱码)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 public class FileInputOutputStreamTest { @Test public void testFileInputStream () { FileInputStream fis = null ; try { File file = new File("hello.txt" ); fis = new FileInputStream(file); byte [] buffer = new byte [5 ]; int len; while ((len = fis.read(buffer)) != -1 ){ String str = new String(buffer,0 ,len); System.out.print(str); } } catch (IOException e) { e.printStackTrace(); } finally { if (fis != null ){ try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } } }
2.实现对图片的复制 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 @Test public void testFileInputOutputStream () { FileInputStream fis = null ; FileOutputStream fos = null ; try { File srcFile = new File("爱情与友情.jpg" ); File destFile = new File("爱情与友情2.jpg" ); fis = new FileInputStream(srcFile); fos = new FileOutputStream(destFile); byte [] buffer = new byte [5 ]; int len; while ((len = fis.read(buffer)) != -1 ){ fos.write(buffer,0 ,len); } } catch (IOException e) { e.printStackTrace(); } finally { if (fos != null ){ try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } if (fis != null ){ try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 public void copyFile (String srcPath,String destPath) { FileInputStream fis = null ; FileOutputStream fos = null ; try { File srcFile = new File(srcPath); File destFile = new File(destPath); fis = new FileInputStream(srcFile); fos = new FileOutputStream(destFile); byte [] buffer = new byte [1024 ]; int len; while ((len = fis.read(buffer)) != -1 ){ fos.write(buffer,0 ,len); } } catch (IOException e) { e.printStackTrace(); } finally { if (fos != null ){ try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } if (fis != null ){ try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } } } @Test public void testCopyFile () { long start = System.currentTimeMillis(); String srcPath = "C:\\Users\\Administrator\\Desktop\\01-视频.avi" ; String destPath = "C:\\Users\\Administrator\\Desktop\\02-视频.avi" ; copyFile(srcPath,destPath); long end = System.currentTimeMillis(); System.out.println("复制操作花费的时间为:" + (end - start)); }
总结
可以使用字节对文件(所有,包括文本)进行复制,不会出现乱码。
乱码是在内存层面中读文本文件时才有。
非文本不能用字符流。