目录
IO的核心组成是五个类(File, OutputStream, InputStream, Reader, Writer)和一个接口(Serializable)
一. File文件操作类
在java.io包中,File类是唯一一个与文件本身操作(创建、删除、取得信息)有关,与文件内容无关的程序类。
1. File类的基本使用
java.io.File类是一个普通的类,直接产生实例化对象即可。如果要实例化对象,需要用到两个构造方法:
该方式只需要传入绝对路径即可。
该方式需要设置父路径和子路径。
创建新文件:
判断文件是否存在:
删除文件:
2. 目录操作
2.1 取得父路径与父File对象
2.2 创建目录
注:无论有多少级父目录,都会一起创建。
例:
import java.io.File;
import java.io.IOException;
public class Test {
public static void main(String[] args) throws IOException {
//取得FiLe对象
File file = new File("C:"+File.separator+"Users"+File.separator+
"Administrator"+File.separator+"Desktop"+File.separator+"www"+
File.separator+"java"+File.separator+"JavaIO.java");
//取得父文件对象
File parentFile = file.getParentFile();
if (!parentFile.exists()){
//若父目录不存在,则创建
parentFile.mkdirs();
}
if (file.exists()){
//判断文件是否存在
file.delete();
}else {
file.createNewFile();
}
}
}
3. 取得文件信息
判断File对象是否是文件:
判断File对象是否是路径:
取得文件大小:
注意:取得是文件的字节数
取得最后修改日期:
列举一个目录的全部组成:
例:遍历桌面上的所有文件
import java.io.File;
public class Test {
public static void main(String[] args) {
new Thread(()->{
File file = new File("C:"+File.separator+"Users"+File.separator
+"Administrator"+File.separator+"Desktop");
System.out.println("遍历文件开始。。。");
long start = System.currentTimeMillis();
listAllFiles(file);
long end = System.currentTimeMillis();
System.out.println("遍历文件结束。。。");
System.out.println("总共花了"+(end-start)+"毫秒");
}).start();
}
public static void listAllFiles(File file){
if (file.exists() && file.isFile()){
System.out.println(file);
}else {
//此时file对象不是文件
File[] files = file.listFiles();
if (files != null){
for (File file1 : files)
listAllFiles(file1);
}
}
}
}
注:IO相关处理属于阻塞式耗时操作,一般放在子线程中进行。
二. 字节与字符流
流的分类:
- 字节流(byte):InputStream、OutputStream
- 字符流(char):Reader、Writer
字节流与字符流的区别:
字节流是原生操作,字符流是处理后的操作。
(就像家里排污水和使用水,字节流就是直接使用和排放,而字符流是通过净水厂个排污工厂,在使用和排放)
一般使用字节流(无论是网络传输还是磁盘的数据保存,均以字节为单位),只有处理中文的文本时,才会用到字符流。
1. 流的操作过程
无论是字符流还是字节流,操作流程几乎一样,以文件操作为例:
- 取得File对象
- 取得file对象的输入流和输出流
- 进行数据的读取或写入
- 关闭流(close)
注意:IO操作属于资源处理,所有资源处理(如IO、数据库、网络)使用后都必须关闭。
2. 字节输出流(OutputStream)
我们可以看到,OutputStream继承Closeable,Flushable。
Closeable接口中只有一个方法:
Flushable中也只有一个方法:
输出方法(write):
①将指定的字节数组全部输出:
②将部分字节数组输出:
③输出单个字节:
要进行文件内容的输出,就是要OutputStream子类:
文件内容覆盖:
文件内容追加:
例:在桌面添加文件并输出内容
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class Test {
public static void main(String[] args) throws IOException {
//1.取得File对象
File file = new File("C:"+File.separator+"Users"+File.separator
+"Administrator"+File.separator+"Desktop"+File.separator+
"Test.txt");
if (!file.exists()){
file.createNewFile();
}
//2.取得终端对象的输出流
OutputStream outputStream = new FileOutputStream(file,true);
//3.进行数据的输出
String msg = "你好\r\n";
outputStream.write(msg.getBytes());
//4.关闭流
outputStream.close();
}
}
注意:当使用FileOutputStream进行文件输出时,只要文件的父路径存在,FileOutputStream会自动创建文件。如上述代码,只要Test.txt的父路径存在,判断文件是否存在那步是可以省略的。
3. 字节输入流(InputStream)
InputStream实现Closeable接口。
输入方法(read):
①读取数据到字节数组b中
返回值有三种情况:
- 返回 b 长度:当读取的数据大小>字节数组大小,返回字节数组的大小
- 返回大于0但是小于b的长度:读取数据大小<字节数组大小,返回真正的读取个数
- 返回-1:数据读取完毕
②读取单个字节:
例:读取文件内容
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
public class Test {
public static void main(String[] args) throws IOException {
//1.取得File对象
File file = new File("C:"+File.separator+"Users"+File.separator
+"Administrator"+File.separator+"Desktop"+File.separator+
"Test.txt");
//2.取得输入流
InputStream inputStream = new FileInputStream(file);
//3.读取文件内容
byte[] data = new byte[1024];
int res = inputStream.read(data);
System.out.println(new String(data,0,res));
//4.关闭流
inputStream.close();
}
}
4. 字符流
字符输出流(Writer):
①传入字符数组:
②传入String对象:
字符输入流(Reader):
Reader类中没有方法可以直接读取字符串,只能通过字符数组来读取。
5. 字节流与字符流
- 从实际开发角度来讲,字节流优先考虑,只有处理中文时才会考虑使用字符流。
- 字节流直接把输出内容输出到终端,而字符流是先将数据保存在缓存中,只有关闭流之后,数据才会输出到终端。