输入输出的感念
什么是I/O
IO指的是程序与外部设备或者其他计算机进行交互的操作,几乎所有的程序都有输入输出操作
例如从键盘上读取和写入数据。
Java把这些输入输出操作通过统一的接口来表示。
I:input 即将数据读入内存,进行数据的读操作
O: output 即往内存设备写数据,称为输出,进行数据的write操作
File类
File类概念
File类是java.io中的很重要的一个类;
File类的对象可以表示文件、目录
File对象可以对文件或目录操作,例如文件名,修改日期等等
File对象无法对文件进行读写,无法具体操作文件中的数据
File类常用方法
//创建目录对象
File dir = new File("Test");
System.out.println(dir.getAbsolutePath());
//判断目录是否存在
if (!dir.exists()){
System.out.println("目录不存在,正在创建中");
//创建目录
dir.mkdir();
}else
System.out.println("目录已创建");
//创建文件对象
File file = new File(dir + "/news.txt");
if (!file.exists()){
System.out.println("文件不存在,正在创建");
//文件创建
file.createNewFile();
}else
System.out.println("文件已创建");
//文件删除
file.delete();
//遍历D盘下的所有文件名字
System.out.println("遍历所有名字 list");
File dirs = new File("D://");
String[] fileNames = dirs.list();
for (String name : fileNames) {
System.out.println(name);
}
//遍历D盘文件绝对路径
System.out.println("遍历所有对象");
File[] files = dirs.listFiles();
for (File f:files){
System.out.println(f.getAbsolutePath());
}
输入流与输出流
输入流与输出流的基本概念
首先,解释一下什么是流,你可以把它想象成一个管道,数据在其中传输流动,因此称为流
流的分类根据数据传输方向可以分为输入流和输出流,也可以根据编码格式分为字节流和字符流,根据封装类型还可以分为节点流和处理流
输入流:InputStream/Reader
类名以inputStream结尾的都是InputStream的子类,以Reader结尾的都是Reader类的子类
inputStream是往内存中读的输入流
输出流:OutputStream
类名以inputStream结尾的都是outputStream的子类,以writer结尾的都是writer类的子类
outputStream是从内存中往外写的输出流
字节流:
InputStream和OutputStream的子类都是字节流,字节流通常用来处理二进制文件,即音频图片和歌曲等。
字符流:
Reader和Writer的子类都是字符流,主要用来处理字符或字符串,用字符流来读取二进制文件,可能会导致文件损坏,数据丢失。
因此处理纯文本数据选字符流效率高,除此之外都使用字节流。
节点流:
如果封装流的是某种特定的数据源,例如文件、字符串、字符串数组等称为节点流,直接操作数据源比较底层的流
处理流:
处理流也叫包装流,BufferedReader类继承了Reader,因此只要是Reader的子类都可以传入BufferedReader类中,下图为两个类的源码,Reader为其私有属性,足以说明功能的强大。
对象处理流:
ObjectInputStream和ObjectOutputStream为对象流,用于应对我们将基本数据类型或者对象进行序列化和反序列化的操作,序列化就是在保存数据时,保存数据的值和数据类型,反序列化就是在恢复数据时,恢复数据的值和数据类型,但其进行如此操作时需要让该对象支持序列化机制,即该类必须实现接口Serializable或者Externalizable,Serializable为标记接口,用得较多不需要实现方法,而Externalizable还需要实现其方法。序列化还需要注意,读写顺序需要一致,序列化对象时,默认将里面所有属性都进行序列化,除了static或transient修饰的成员,序列化对象时要求里面属性的类型也实现序列化,序列化具备继承性,若某类已经实现了序列化,则默认其子类也实现了序列化。
流操作的基本规律
首先明确源和目的,是选择输入流还是输出流,其次考虑操作的数据类型,若是纯文本则选择字符流,若是二进制则选择字节流,判断是否有额外功能,是否高效来考虑是否加缓冲区。切记,使用了流就一定要及时关闭,否则造成资源浪费。
简单的文件拷贝示例
//源文件file1
File file1 = new File("testbuf.txt");
//目标文件file2
File file2 = new File("news2.txt");
//创建其对应的输入流,输出流,并使用转换流包裹
BufferedInputStream bfi = new BufferedInputStream(new FileInputStream(file1));
BufferedOutputStream bfo = new BufferedOutputStream(new FileOutputStream(file2));
int read = 0;
byte[] bytes = new byte[2024];
while ((read = bfi.read(bytes)) != -1){
String line = bytes.toString();
bfo.write(bytes,0,read);
System.out.println(line);
}
//关闭流防止资源浪费
bfo.close();
bfi.close();