Java中文件和I/O
以下内容引用自http://wiki.jikexueyuan.com/project/java/files-and-io.html:
在Java中java.io包含的每一个类几乎都要进行输入和输出操作。所有的这些流代表一个输入源和输出目的地。在java.io包中支持许多数据,如原语,对象,本地化字符等等。
一、流
流可以被定义为一个序列的数据。
- InPutStream:输入流用来从一个源中读数据。
- OutPutStream:输出流用来向一个目的地写数据。
Java提供了强大且灵活的有关文件和网络的I/O功能。
二、字节流
Java字节流是用来处理8比特字节(8-bit bytes)的输入和输出。尽管有许多的有关字节流的类,但是最常用的是FileInputStream类和FileOutputStream类。下面是一个例子,作用是用这两个类来完成把一个输入文件的内容复制到输出文件:
import java.io.*; public class CopyFile { public static void main(String args[]) throws IOException { FileInputStream in = null; FileOutputStream out = null; try { in = new FileInputStream("input.txt"); out = new FileOutputStream("output.txt"); int c; while ((c = in.read()) != -1) { out.write(c); } }finally { if (in != null) { in.close(); } if (out != null) { out.close(); } } } }
接下来需要有一个文件input.txt,内容如下:
This is test for copy file.
下一步,编译上面的程序并执行它,结果会创建一个文件叫做output.txt,它的内容和上面的input.txt内容是一样的。所以将上面的代码放入CopyFile.java文件,然后进行如下操作:
$javac CopyFile.java
$java CopyFile
二、字符流
Java字节流是用来处理8比特字节的输入和输出,Java字符流用于处理16位unicode的输入和输出。尽管这里有许多关于字符流的类,但最常用的类是,FileReader和FileWriter。虽然在内部FileReader还是使用FileInputStream和FileWriter使用FileOutputStream,但是主要的区别是FileReader和FileWriter一次读写两个字节。
重写上面的例子来完成把一个输入文件(包含unicode字符)的内容复制到输出文件:
import java.io.*; public class CopyFile { public static void main(String args[]) throws IOException { FileReader in = null; FileWriter out = null; try { in = new FileReader("input.txt"); out = new FileWriter("output.txt"); int c; while ((c = in.read()) != -1) { out.write(c); } }finally { if (in != null) { in.close(); } if (out != null) { out.close(); } } } }
接下来需要有一个文件input.txt ,内容如下:
This is test for copy file.
下一步,编译上面的程序并执行它,结果会创建一个文件叫做output.txt,它的内容和上面的input.txt内容是一样的。所以将上面的代码放入CopyFile.java文件,然后进行如下操作:
$javac CopyFile.java
$java CopyFile
三、标准流
所有的编程语言都提供了对标准I/O流的支持,即用户可以从自己的键盘上进行输入,并且从屏幕上输出。C或C++编程语言中三种标准输入输出STDIN,STDOUT和STDERR。同样的Java也提供了以下的三种标准流:
- Standard Input:这是用来将数据反馈给用户的程序,通常键盘作为标准输入流并且表示为System.in。
- Standard Output:这是用于输出用户程序产生的数据,通常电脑屏幕作为标准输出流,并且表示为System.out。
- Standard Error:这是用来输出用户产生的错误数据,通常电脑屏幕作为标准错误流,并且表示为System.err。
下面是一个示例程序用来创建一个InputStreamReader来读标准输入流直到用户输入字符"q":
import java.io.*; public class ReadConsole { public static void main(String args[]) throws IOException { InputStreamReader cin = null; try { cin = new InputStreamReader(System.in); System.out.println("Enter characters, 'q' to quit."); char c; do { c = (char) cin.read(); System.out.print(c); } while(c != 'q'); }finally { if (cin != null) { cin.close(); } } } }
把上面的代码放到ReadConsole.java中并且用如下方法编译执行它。这个程序将不断地读写相同的字符直到按下"q"。
$javac ReadConsole.java $java ReadConsole Enter characters, 'q' to quit. 1 1 e e q q
四、读写文件
一个流可以定义为一个序列的数据。输入流用来从一个源中读数据,输出流用来向一个目的地写数据。
这里是相关类的层次来表示输入和输出流:
两个重要的流是FileInputStream和FileOutputStream。
五、文件输入流
这个流是用来从文件中读数据的。对象能够通过用关键字new来创建,并且这里有很多可用的不同类型的构造函数。
下面的构造函数以文件名的字符串为参数来创建一个输入流对象去读文件。
InputStream f = new FileInputStream("C:/java/hello");
下面的构造函数需要以一个文件对象作为参数来去创建一个输入流对象去读文件,首先用File()方法来去创建一个文件对象:
File f = new File("C:/java/hello"); InputStream f = new FileInputStream(f);
一旦有了一个输入流对象,这里将有很多的提供帮助的方法来进行读操作或是其他在流中的操作。
方法 | 描述 |
---|---|
public void close() throws IOException{} | 这个方法关闭文件输出流。释放有关文件的所有系统资源。抛出IO异常。 |
protected void finalize() throws IOException {} | 这个方法会切断和文件的连接。确保这个文件输出流的关闭方法在这个流没有引用的时候才会被调用。抛出IO异常。 |
public int read(int r) throws IOException{} | 这个方法从InputStream中读到特定字节数的数据。返回一个int类型。返回下一个字节的数据或是在文件末尾时返回-1。 |
public int read(byte[] r) throws IOException{} | 这个方法是从输入流中读r个长度字节到数组中。返回所有读到的字节数,或是在文件末尾时返回-1。 |
public int available() throws IOException{} | 给出能从输入流中读到的字节数,返回一个int类型数据。 |
六、文件输出流
FileOutputStream是用来创建一个文件,并向其中写入数据。如果之前没有该文件,该流会在打开流之前创建一个文件。
这里是两个能够产生FileOutputStream对象的构造函数。
下面的构造函数以文件名的字符串作为参数来创建一个输出流对象去写文件:
OutputStream f = new FileOutputStream("C:/java/hello")
下面的构造函数需要以一个文件对象作为参数来去创建一个输出流对象去写文件,首先用File()方法来去创建一个文件对象:
File f = new File("C:/java/hello"); OutputStream f = new FileOutputStream(f)
一旦有了一个输出流对象,这里将有很多的提供帮助的方法来进行写操作或是其他在流中的操作。
方法 | 描述 |
---|---|
public void close() throws IOException{} | 这个方法关闭文件输出流。释放有关文件的所有系统资源。抛出IO异常。 |
protected void finalize() throws IOException {} | 这个方法会切断和文件的连接。确保这个文件输出流的关闭方法在这个流没有引用的时候才会被调用。抛出IO异常。 |
public void write(int w) throws IOException{} | 这个方法用来写特定的字节到输出流。 |
public void write(byte[] w) | 从字节数组中写 w 长度字节到输出流。 |
示例:
下面是一个例子来演示InputStream和OutputStream:
public class FileStreamTest { public static void main(String args[]) { try { byte bWrite[] = { 11, 21, 3, 40, 5 }; OutputStream os = new FileOutputStream("test.txt"); for (int x = 0; x < bWrite.length; x++) { os.write(bWrite[x]); // writes the bytes } os.close(); InputStream is = new FileInputStream("test.txt"); int size = is.available(); for (int i = 0; i < size; i++) { System.out.print((char) is.read() + " "); } is.close(); } catch (IOException e) { System.out.print("Exception"); } } }
上面的代码将产生test.txt文件并且以二进制格式写入给出的数字。
七、文件导航和I/O
这里需要查看很多类来去了解文件导航和I/O。
- File Class
- FileReader Class
- FileWriter Class
提示:获得完整详细的类说明,请参考Java官方文档。
八、Java目录
目录是一个文件可以包含其他文件和目录的列表。想要在目录中列出可用文件列表,可以通过使用File对象创建目录,获得完整详细的能在File对象中调用的以及有关目录的方法列表。
1、创建目录
这里有两个有用的文件方法,能够创建目录:
- mkdir()方法创建了一个目录,成功返回true,创建失败返回false。失败情况是指文件对象的路径已经存在了,或者无法创建目录,因为整个路径不存在。
- mkdirs()方法创建一个目录和它的上级目录。
以下示例创建“/tmp/user/java/bin”目录:
import java.io.File; public class CreateDir { public static void main(String args[]) { String dirname = "/tmp/user/java/bin"; File d = new File(dirname); // Create directory now. d.mkdirs(); } } //编译并执行以上代码创建 “/tmp/user/java/bin”
提示:Java自动按UNIX和Windows约定来处理路径分隔符。如果在Windows版本的Java中使用正斜杠(/),仍然可以得到正确的路径。
2、目录列表
如下,能够用File对象提供的list()方法来列出目录中所有可用的文件和目录
import java.io.File; public class ReadDir { public static void main(String[] args) { File file = null; String[] paths; try{ // create new file object file = new File("/tmp"); // array of files and directory paths = file.list(); // for each name in the path array for(String path:paths) { // prints filename and directory name System.out.println(path); } }catch(Exception e){ // if any error occurs e.printStackTrace(); } } } //基于/tmp目录下可用的目录和文件,将产生以下结果: test1.txt test2.txt ReadDir.java ReadDir.class
提示:这种方法只能获取当前目录下的文件和目录,不能递归获取。
测试工程:https://github.com/easonjim/5_java_example/tree/master/javabasicstest/test14