Java 流(Stream)、文件(File)和IO
简介
Java.io 包几乎包含了所有操作输入、输出需要的类。所有这些流类代表了输入源和输出目标。
Java.io 包中的流支持很多种格式,比如:基本类型、对象、本地化字符集等等。
一个流可以理解为一个数据的序列。输入流表示从一个源读取数据,输出流表示向一个目标写数据。
Java 为 I/O 提供了强大的而灵活的支持,使其更广泛地应用到文件传输和网络编程中。
一个流被定义为一个数据序列。输入流用于从源读取数据,输出流用于向目标写数据。
下图是一个描述输入流和输出流的类层次图:
在java.io包中操作文件内容的主要有两大类:字节流、字符流,两类都分为输入和输出操作。
在字节流中输出数据主要是使用OutputStream完成,输入使的是InputStream;在字符流中输出主要是使用Writer类完成,输入流主要使用Reader类完成。这四个都是抽象类。
java中提供了专用于输入输出功能的包java.io, 其中包括:
InputStream, OutputStream, Reader, Writer。
InputStream和OutputStream, 两个是为字节流设计的,主要用来处理字节或二进制对象。
Reader和Writer, 两个是为字符流(1个字符占2个字节)设计的,主要用来处理字符或字符串。
常见的System.in其实就是InputStream对象。
字节流转换为字符流
控制台输入System.in 创建BufferedReader创建字符轮流
//从控制台读取
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
//从文件读取
BufferedReader br=new BufferedReader(new InputStreamReader(new FileInputStream("D:/text.txt")));
针对上面示例的三个类进行简单说明:
InputStream:是所有字节输入流的超类,一般使用它的子类:FileInputStream等,它能输出字节流;
InputStreamReader:是字节流与字符流之间的桥梁,能将字节流输出为字符流,并且能为字节流指定字符集,可输出一个个的字符;
BufferedReader:提供通用的缓冲方式文本读取,readLine()读取一个文本行,从字符输入流中读取文本,缓冲各个字符,从而提供字符、数组和行的高效读取。
FileInputStream
该流用于从文件读取数据,它的对象可以用关键字 new 来创建。
有多种构造方法可用来创建对象。
可以使用字符串类型的文件名来创建一个输入流对象来读取文件:
InputStreamf= newFileInputStream("C:/java/hello");
也可以使用一个文件对象来创建一个输入流对象来读取文件。我们首先得使用 File() 方法来创建一个文件对象:
Filef= newFile("C:/java/hello"); InputStreamout= newFileInputStream(f);
创建了InputStream对象,就可以使用下面的方法来读取流或者进行其他的流操作。
序号方法及描述
1
public void close() throws IOException{}
关闭此文件输入流并释放与此流有关的所有系统资源。抛出IOException异常。
2
protected void finalize()throws IOException {}
这个方法清除与该文件的连接。确保在不再引用文件输入流时调用其 close 方法。抛出IOException异常。
3
public int read(int r)throws IOException{}
这个方法从 InputStream 对象读取指定字节的数据。返回为整数值。返回下一字节数据,如果已经到结尾则返回-1。
4
public int read(byte[] r) throws IOException{}
这个方法从输入流读取r.length长度的字节。返回读取的字节数。如果是文件结尾则返回-1。
5
public int available() throws IOException{}
返回下一次对此输入流调用的方法可以不受阻塞地从此输入流读取的字节数。返回一个整数值。
除了 InputStream 外,还有一些其他的输入流,更多的细节参考下面链接:
FileOutputStream
该类用来创建一个文件并向文件中写数据。
如果该流在打开文件进行输出前,目标文件不存在,那么该流会创建该文件。
有两个构造方法可以用来创建 FileOutputStream 对象。
使用字符串类型的文件名来创建一个输出流对象:
OutputStreamf= newFileOutputStream("C:/java/hello")
也可以使用一个文件对象来创建一个输出流来写文件。我们首先得使用File()方法来创建一个文件对象:
Filef= newFile("C:/java/hello"); OutputStreamf= newFileOutputStream(f);
创建OutputStream 对象完成后,就可以使用下面的方法来写入流或者进行其他的流操作。
序号方法及描述
1
public void close() throws IOException{}
关闭此文件输入流并释放与此流有关的所有系统资源。抛出IOException异常。
2
protected void finalize()throws IOException {}
这个方法清除与该文件的连接。确保在不再引用文件输入流时调用其 close 方法。抛出IOException异常。
3
public void write(int w)throws IOException{}
这个方法把指定的字节写到输出流中。
4
public void write(byte[] w)
把指定数组中w.length长度的字节写到OutputStream中。
除了OutputStream外,还有一些其他的输出流,更多的细节参考下面链接:
Java中的目录
创建目录:
File类中有两个方法可以用来创建文件夹:
mkdir( )方法创建一个文件夹,成功则返回true,失败则返回false。失败表明File对象指定的路径已经存在,或者由于整个路径还不存在,该文件夹不能被创建。
mkdirs()方法创建一个文件夹和它的所有父文件夹。
下面的例子创建 "/tmp/user/java/bin"文件夹:
CreateDir.java 文件代码:
import java.io.File;
public class CreateDir {
public static void main(String args[]) {
String dirname = "/tmp/user/java/bin";
File d = new File(dirname);
// 现在创建目录
d.mkdirs();
}
}
编译并执行上面代码来创建目录 "/tmp/user/java/bin"。
注意: Java 在 UNIX 和 Windows 自动按约定分辨文件路径分隔符。如果你在 Windows 版本的 Java 中使用分隔符 (/) ,路径依然能够被正确解析。
读取目录
一个目录其实就是一个 File 对象,它包含其他文件和文件夹。
如果创建一个 File 对象并且它是一个目录,那么调用 isDirectory() 方法会返回 true。
可以通过调用该对象上的 list() 方法,来提取它包含的文件和文件夹的列表。
下面展示的例子说明如何使用 list() 方法来检查一个文件夹中包含的内容:
DirList.java 文件代码:
import java.io.File;
public class DirList {
public static void main(String args[]) {
String dirname = "/tmp";
File f1 = new File(dirname);
if (f1.isDirectory()) {
System.out.println( "目录 " + dirname);
String s[] = f1.list();
for (int i=0; i < s.length; i++) {
File f = new File(dirname + "/" + s[i]);
if (f.isDirectory()) {
System.out.println(s[i] + " 是一个目录");
} else {
System.out.println(s[i] + " 是一个文件");
}
}
} else {
System.out.println(dirname + " 不是一个目录");
}
}
}
以上实例编译运行结果如下:
目录/tmp
bin 是一个目录lib 是一个目录demo 是一个目录test.txt 是一个文件README 是一个文件index.html 是一个文件include 是一个目录
删除目录或文件
删除文件可以使用 java.io.File.delete() 方法。
以下代码会删除目录/tmp/java/,即便目录不为空。
测试目录结构:
/tmp/java/|--1.log|--test
DeleteFileDemo.java 文件代码:
import java.io.File;
public class DeleteFileDemo {
public static void main(String args[]) {
// 这里修改为自己的测试目录
File folder = new File("/tmp/java/");
deleteFolder(folder);
}
//删除文件及目录
public static void deleteFolder(File folder) {
File[] files = folder.listFiles();
if(files!=null) {
for(File f: files) {
if(f.isDirectory()) {
deleteFolder(f);
} else {
f.delete();
}
}
}
folder.delete();
}