IO流操作总结
字节流:以InputStream结尾的流都属于字节输入流。以OutputStream结尾的流属于字节输出流。
字节输入流:
InputStream:
FileInputStream 读取 read() 一次读取一个字节 read(byte[] b) 一次读取多个字节放在数组中
BufferedInputStream 字节输入流缓冲区
字节输出流:
OutputStream:
FileOutputStream 写 write(byte[] b) write(int a)
BufferedOutputStream 字节输出流缓冲区
字符流:以Reader结尾的流属于字符输入流。以Writer结尾的流属于字符输出流。
字符输入流:
Reader:
InputStreamReader:InputStream(字节输入流) + 任意编码表 字节数据转字符数据输入流
FileReader:FileInputStream + 默认编码表 read(char[] c) 读取多个字符 read() 一次读取一个字符数据
BufferedReader 字符输入流缓冲区。 readLine() 每次读取一行数据 读到文件末尾返回null
字符输出流:
Writer: 字符输出流 往硬盘上写数据
OutputStreamWriter:OutputStream(字节输出流) + 任意编码表 字符数据转字节数据输出流
FileWrter:便捷类,相当于:FileOutputStream + 默认编码表
BufferedWriter 字符输出流缓冲区 换行 newLine()
所有的流操作:
1、创建流对象,和文件持久设备进行关联;
2、使用流读取或写出数据;
3、关闭流;
问题:
1、在使用IO流之前,判断当前的数据是什么数据?
目的是确定到底使用字节流还是字符流
字节:FileInputStream/FileOutputStream
字符流:FileReader/FileWriter
2、在确定使用的流之后,判断当前到底是读取还是写出?
读取使用输入流,写出就使用输出流。
读:FileInputStream/FileReader
写:FileOutputStream/FileWriter
3、是否需要高效?
是否需要在流的基础上加上缓冲区BufferedXxxxx
补充:字节流一般不需要使用缓冲区,只有字符流需要使用,因为要使用readLine()函数一次读取一行。
4、是否需要转换?
读写数据的时候是否需要字节数据转字符数据,或字符数据转字节数据。在转换的过程中可以指定编码表。
总结:在不确定具体什么数据的时候尽量全部使用字节流。
example:复制单级文件夹
/*
* 数据源:e:\demo
* 目的地:e:\test
* 分析:
* A:封装目录
* B:获取该目录下的所有文本的File数组
* C:遍历该File数组,得到每一个File对象
* D:把该File进行复制
*/
1 public class CopyFolderDemo { 2 public static void main(String[] args) throws IOException { 3 // 封装目录 4 File srcFolder = new File("e:\demo"); 5 // 封装目的地 6 File destFolder = new File("e:\test"); 7 // 如果目的地文件夹不存在,就创建 8 if (!destFolder.exists()) { 9 destFolder.mkdir(); 10 } 11 12 // 获取该目录下的所有文本的File数组 13 File[] fileArray = srcFolder.listFiles(); 14 15 // 遍历该File数组,得到每一个File对象 16 for (File file : fileArray) { 17 // System.out.println(file); 18 // 数据源:e:\demo\e.mp3 19 // 目的地:e:\test\e.mp3 20 String name = file.getName(); // e.mp3 21 File newFile = new File(destFolder, name); // e:\test\e.mp3 22 23 copyFile(file, newFile); 24 } 25 } 26 27 private static void copyFile(File file, File newFile) throws IOException { 28 BufferedInputStream bis = new BufferedInputStream(new FileInputStream( 29 file)); 30 BufferedOutputStream bos = new BufferedOutputStream( 31 new FileOutputStream(newFile)); 32 33 byte[] bys = new byte[1024]; 34 int len = 0; 35 while ((len = bis.read(bys)) != -1) { 36 bos.write(bys, 0, len); 37 } 38 39 bos.close(); 40 bis.close(); 41 } 42 }
字符流
字节流读取字符数据的问题:
汉字等字符,往往由多个字节组成。使用字节流读取由多个字节组成字符数据,发现读取到的每个字符的对应的字节数据,而不是真正的字符内容。而我们更希望看到读取的具体的内容是什么字符数据。
我们需要把读取到的某2个字节合并在一起,拼成一个汉字。这时我们在程序中并不知道应该把哪2个字节合并成一个汉字。由于在程序中,有时一个字节就表示一个字符数据,比如英文字母,有时必须是2个字节表示一个汉字,那么到底应该把一个字节转成字母,还是把2个字节转成汉字,这时我们无法对读取的数据进行控制。
例如:记事本中的数据:abc你好
我们如果使用字节流来读取上述数据,那么字节流不知道什么时候是几个字节组成字母,几个字节组成汉字,这样会出现我们不想要的结果。
但是Java提供的字符流就可以解决上述读取字符数据的问题,在字符流的底层,它自己会根据读取到的字节数据的特点,然后自动的帮助我们把字节转成字符,最后我们就会自然的得到想要的字符数据。
……