转自:http://www.zaojiahua.com/1453.html
在使用io操作之前,先看一下java中的文件类File如何使用。File包括文件和目录,对文件和目录的操作是新建目录mkdir,新建文件createNewFile,删除文件和目录delete,以及其他的一些操作。
4 | import java.io.IOException; |
9 | public static void main(String[] args) throws IOException |
12 | File file = new File( "1/2" ); |
21 | File file2 = new File(file, "1.txt" ); |
22 | file2.createNewFile(); |
25 | File file3 = new File( "2.txt" ); |
26 | file3.createNewFile(); |
28 | System.out.println(file3.getAbsolutePath()); |
29 | System.out.println(file2.getParent()); |
33 | File file4 = new File( "1/3" ); |
35 | String str[] = file4.list(); |
38 | System.out.println(s); |
42 | System.out.println( "**********************listAll**********************" ); |
46 | static void listAll(File filename) |
48 | if (filename.isDirectory()) |
50 | File fileDir [] = filename.listFiles(); |
51 | for (File file : fileDir) |
53 | if (file.isDirectory()) |
55 | System.out.println( "目录:" +file); |
59 | System.out.println( "文件:" +file); |
64 | System.out.println( "文件:" +filename); |

接下来是java中IO类的操作,IO分类如下图所示,这里只说几个常用的。

首先是FileInputStream和FileOutputStream,这一对流是对文件进行读写的,读写方法是从父类inputStream和OutputStream继承下来的read和write方法。
1 | package com.zaojiahua.iodemo; |
4 | import java.io.FileInputStream; |
5 | import java.io.FileOutputStream; |
6 | import java.io.IOException; |
10 | public static void main(String[] args) throws IOException { |
12 | File file = new File( "file.txt" ); |
14 | FileInputStream inputStream = new FileInputStream(file); |
15 | FileOutputStream outputStream = new FileOutputStream( "1.txt" ); |
25 | byte [] buf = new byte [ 1024 ]; |
27 | while ((len = inputStream.read(buf)) != - 1 ) |
29 | outputStream.write(buf); |
BufferedInputStream对外提供滑动读取的功能实现,通过预先读入一整段原始输入流数据至缓冲区中,而外界对BufferedInputStream的读取操作实际上是在缓冲区上进行,如果读取的数据超过了缓冲区的范围,那么BufferedInputStream负责重新从原始输入流中载入下一截数据填充缓冲区,然后外界继续通过缓冲区进行数据读取。这样的设计的好处是:避免了大量的磁盘IO,因为原始的InputStream类实现的read是即时读取的,即每一次读取都会是一次磁盘IO操作(哪怕只读取了1个字节的数据),可想而知,如果数据量巨大,这样的磁盘消耗非常可怕。而通过缓冲区的实现,读取可以读取缓冲区中的内容,当读取超过缓冲区的内容后再进行一次磁盘IO,载入一段数据填充缓冲,那么下一次读取一般情况下就直接可以从缓冲区读取,减少了磁盘IO。说白了buffered就是用来缓存的,可以用来提高读取的效率,之所以说FileInputStream是阻塞的方法是因为CUP的速度和磁盘的速度是不匹配的,如果每次要读取的时候都访问磁盘这样就造成了阻塞。通过以上的说明可以看出buffered则并不是阻塞的。所以我们读取文件的时候一般都在文件流上边套上一层buffer流。
1 | package com.zaojiahua.iodemo; |
3 | import java.io.BufferedInputStream; |
4 | import java.io.BufferedOutputStream; |
6 | import java.io.FileInputStream; |
7 | import java.io.FileOutputStream; |
8 | import java.io.IOException; |
12 | public static void main(String[] args) throws IOException { |
14 | File file = new File( "file.txt" ); |
16 | BufferedInputStream input = new BufferedInputStream( new FileInputStream(file)); |
17 | BufferedOutputStream output = new BufferedOutputStream( new FileOutputStream( "1.txt" )); |
20 | byte [] buf = new byte [ 1024 ]; |
22 | while ((len = input.read(buf)) != - 1 ) |
24 | output.write(buf, 0 ,len); |
26 | String str = new String(buf, 0 ,len); |
27 | System.out.println(str); |
数据在硬盘上都是以字节的方式存储的,那么什么时候使用字符流,什么时候使用字节流呢?字符流是对字符操作的,也就是对文本文件或者其他字符文件操作。而对于图片,声音,视频这些文件则用字节流操作。接下来是对字符流的操作,字符流相当于是字节流+编码表。可以向文件中直接写入字符串。读取的时候注意是用字符数组接受,不是字节数组。
1 | package com.zaojiahua.iodemo; |
4 | import java.io.FileReader; |
5 | import java.io.FileWriter; |
6 | import java.io.IOException; |
10 | public static void main(String[] args) throws IOException { |
12 | File file = new File( "file.txt" ); |
15 | FileReader reader = new FileReader(file); |
16 | FileWriter writer = new FileWriter( "2.txt" ); |
19 | char [] buf = new char [ 1024 ]; |
20 | while ((len = reader.read(buf)) != - 1 ) |
22 | System.out.println( new String(buf, 0 ,len)); |
23 | writer.write(buf, 0 ,len); |
26 | writer.write( "\r\n" + "end" ); |
以下是缓冲的字符流。经过缓冲以后可以读取和写入一行的数据。
1 | package com.zaojiahua.iodemo; |
3 | import java.io.BufferedReader; |
4 | import java.io.BufferedWriter; |
6 | import java.io.FileReader; |
7 | import java.io.FileWriter; |
8 | import java.io.IOException; |
12 | public static void main(String[] args) throws IOException { |
14 | File file = new File( "file.txt" ); |
17 | BufferedReader bufferedReader = new BufferedReader( new FileReader(file)); |
18 | BufferedWriter bufferedWriter = new BufferedWriter( new FileWriter( "2.txt" )); |
22 | while ((buf = bufferedReader.readLine()) != null ) |
24 | bufferedWriter.write(buf); |
26 | bufferedWriter.newLine(); |
27 | System.out.println(buf); |
31 | bufferedReader.close(); |
32 | bufferedWriter.close(); |
最后解决的一个问题是字节流和字符流的转化,使用的是InputStreamReader和OutputStreamWriter,它们本身属于的是reader和writer字符流,我们之所以会用到这些转化流是因为系统有时候只给我们提供了字节流,为了方便操作,要用到字符流。比如说System.in标准输入流就是字节流。你想从那里得到用户在键盘上的输入,只能是以转换流将它转换为Reader以方便自己的程序读取输入。再比如说Socket里的getInputStream()很明显只给你提供字节流,你要想读取字符,就得给他套个InputStreamReader()用来读取。
1 | package com.zaojiahua.iodemo; |
3 | import java.io.BufferedReader; |
4 | import java.io.BufferedWriter; |
5 | import java.io.FileInputStream; |
6 | import java.io.FileOutputStream; |
7 | import java.io.IOException; |
8 | import java.io.InputStreamReader; |
9 | import java.io.OutputStreamWriter; |
13 | public static void main(String[] args) throws IOException { |
16 | FileInputStream fileInputStream = new FileInputStream( "input.txt" ); |
18 | BufferedReader reader = new BufferedReader( new InputStreamReader(fileInputStream)); |
21 | OutputStreamWriter outputStreamWriter = new OutputStreamWriter( new FileOutputStream( "output.txt" )); |
22 | BufferedWriter writer = new BufferedWriter(outputStreamWriter); |
26 | while ((buf = reader.readLine()) != null ) |
30 | System.out.println(buf); |