原帖地址:http://www.cnblogs.com/idayln/archive/2013/05/29/3106487.html
在上篇中,已经写下了IO流概念以及对File类操作,如果想查阅上篇的内容,请点击这里: http://www.cnblogs.com/idayln/archive/2013/05/27/3102810.html . 此文是它的姊妹篇!本文以Demo为主,不会涉及太多概念!!!
- 输入流: InputStream/Reader 拥有一系列read方法
- InputStream 是字节输入流的超类
- Reader是字符输入流的超类
- 输出流: OutputStream/Writer 拥有一系列write方法
- OutputStream 字节输出类的超类
- Writer 字符输出流的超类
输出流代码:
1 static void demo0() throws Exception {
2 try (OutputStream outputStream = new FileOutputStream("demo1.txt")) {
3 outputStream.write("First 'demo' for how to use 'OutputStream' !"
4 .getBytes());
5 }
6 System.out.println("Over");
7 }
看到这段代码,是不是感觉有点奇怪?别紧张.
- 上段代码是Java 7中异常新特性:try-with-resources: 它可以自行进行资源管理,例如上例就不需要手动close;需要注意的是:try(/* 此处可以是代码块 */),这种语法节省的好多代码。
- OutputStream是个抽象类,它必须通过子类来进行实例化。
- OutputStream主要分为二种功能
- 字入数据的write系列方法
- 参数为byte: 单一字节
- 参数为byte数组
- 参数为byte数组和数组中的起始位置与长度
- 流的控制
- 关闭:close
- 刷新保存:flush: 其实不必手动flush。第一:当内部缓冲期满过,它会自动自动执行flush;第二:当invoke close方法时,会自动执行flush。
输入流代码:
1 static void demo1() throws IOException{
2 InputStream inputStream =null;
3 try {
4 inputStream = new FileInputStream("demo0.txt");
5 byte[] bb = new byte[1024]; //缓冲区
6 int temp;
7 while((temp=inputStream.read(bb))!=-1){
8 System.out.println(new String(bb, 0, temp));
9 }
10 } catch (FileNotFoundException e) {
11 // TODO Auto-generated catch block
12 e.printStackTrace();
13 }finally{
14 if(inputStream!=null){
15 inputStream.close();
16 }
17 }
18 }
InputStream:
- 上段采用Java 6的语法,是不是明显感觉到代码量增多:从7行增加到18行。
- 与OutputStream一样是个抽象类。因为它们都是比较早设计的类,因此并没有采用流行的面向接口编程思想。
- 与OutputStream一样也主要有二个功能:read系列方法,但是它的流的控制没有flush而是添加了skip,mark这二个方法,平时用得少,感兴趣的同学可以自行去查API。
Reader,Writer与InputStream,OutputStream基本功能相,这里就不在解释。深入理解了InputStream与OutputStream之后,学其它就很快;对于不同的处理流,查API就行!!
附上IO流体系结构表:
分类 | 字节输入流 | 字节输出流 | 字符输入流 | 字符输出流 |
抽象基类 | InputStream | OutputSteam | Reader | Writer |
文件 | FileInputStream | FileOutputSteam | FileReader | FileWriter |
数组 | ByteArrayInputStream | ByteArrayOutputStream | CharArrayReader | CharArrayWriter |
缓冲 | BufferedInputStream | BufferedOutputStream | BufferdReader | BufferWriter |
对象 | ObjectInputStream | ObjectOutputStream | ||
转换 | InputStreamReader | OutputStreamWriter | ||
打印 | PrintStream | PrintWriter | ||
字符串 | StringReader | StringWriter | ||
管道 | PipedInputStream | PipedOutputStream | PipedReader | PipedWriter |
这多类,该如何记忆,理解呢? 我是这么理解的。
首先把它们大致划分为:节点流与处理流。节点流就是直接与物理节点,进行交互;而处理流通常直接处理的对象是节点流,是再上一层的包装。
比如:如果想对read操作进行同步缓冲,可以使用BufferedInputStream:
1 static void demo2() throws Exception{
2 InputStream inputStream =null;
3 BufferedInputStream bufferedInputStream =null;
4 try {
5 inputStream = new FileInputStream("demo0.txt");
6 bufferedInputStream = new BufferedInputStream(inputStream);
7 byte[] bb = new byte[1024];
8 int temp=-1;
9 while((temp=bufferedInputStream.read(bb))!=-1){
10 System.out.println(new String(bb,0,temp));
11 }
12 } catch (FileNotFoundException e) {
13 // TODO Auto-generated catch block
14 e.printStackTrace();
15 }finally{
16 if(inputStream!=null){
17 inputStream.close();
18 }
19 }
20 }
RandomAccessFile: 任意访问内容类:既可以读取文件内容,也可以向文件输出数据,可以自由访问文件的任意位置,它可以自由定位文件记录指针。
二个重要方法:
- long getFilePointer(): 获取文件记录的当前指针位置
- void seek(long position): 将文件的记录指针特定position的位置。
使用RandomAccessFile 必须要设置模式:
- r: 只读
- rw: 读写,如果不存在,则自动创建。
- rws: 读写,读文件内容与元数据改动都会同步更新到Target Device上;
- rwd:与rws类似,差别在于,当元数据改动后,不会同步更新到Target Device
1 static void demo3() throws Exception{
2 RandomAccessFile file = new RandomAccessFile("demo0.txt", "rw");
3 System.out.println("Before invoke write:"+file.getFilePointer());
4 file.seek(file.length());
5 file.write("\nUsing RandomAccessFile Class".getBytes());
6
7 System.out.println("After invoke write:"+file.getFilePointer());
8 file.seek(0);
9 byte[] bb = new byte[1024];
10 int temp=-1;
11 while ((temp=file.read(bb))>0) {
12 System.out.println(new String(bb,0,temp));
13 }
14
15 file.close();
16 }
如果要在指定的位置进行插入内容,那必须得把指定位置的内容进行缓存,不然会被替代。
1 static void demo4(String fileName,long position,String content) throws Exception{
2 RandomAccessFile file = new RandomAccessFile(fileName, "rws");
3 File tempFile = File.createTempFile("temp", null);
4
5 long currentLength = file.length();
6 if(position>currentLength){
7 return;
8 //Maybe you can setup position=currentLenght; Also you can setup anything what you want !!!
9 }
10 FileOutputStream fileOutputStream = new FileOutputStream(tempFile); // write data to "temp" file
11 FileInputStream fileInputStream = new FileInputStream(tempFile); // read data
12 byte[] bb = new byte[512];
13 int tempNum=-1;
14
15 file.seek(position);
16
17 while((tempNum=file.read(bb))>0){
18 fileOutputStream.write(bb, 0, tempNum);
19 }
20
21 file.seek(position); // Go back to position
22 file.write(content.getBytes());
23
24 while((tempNum=fileInputStream.read(bb))>0){
25 file.write(bb, 0, tempNum);
26 }
27
28 tempFile.deleteOnExit();
29 if(fileInputStream!=null){
30 fileInputStream.close();
31 }
32 if(fileOutputStream!=null){
33 fileOutputStream.close();
34 }
35
36 file.close();
37 }
