文章目录
一 概述
1.什么是IO流
数据源和程序之间交互的管道叫做IO流,主要用来处理设备之间的数据传输
2.IO流的分类
- 按流向分类
- 输入流: 数据源到程序
- 输出流: 程序到目的地
- 按功能分类
- 节点流:从特定的地方读写的流类,如磁盘或者一块内存区域。以byte或者file开头的是节点流,其余都是处理流
- 过滤流(处理流):不直接连接数据源,而是对其它流进行封装,以简化操作和提高性能
- 按传输单位分类
- 字节流(stream结尾):以字节(8位二进制)为单位进行处理。主要用于读写诸如图像或声音的二进制数据
- 字符流(reader和writer结尾):以字符(16位二进制)为单位进行处理,处理纯文本优先考虑
二 File类
1.什么是File类
用来抽象的表示文件或文件夹,这个File不一定存在。代表着java和资源的一个关联
2.路径
- 拼接路径的方式
- 直接用/来分割
- 用File.separator
- 绝对路径和相对路径
- 完整的文件路径
- 相对于项目的路径
3.File类的构建方式
- 通过将给定路径名字符串转换成抽象路径名来创建一个新 File 实例
- 根据 parent 路径名字符串和 child 路径名字符串创建一个新 File 实例
- 通过给定的父抽象路径名和子路径名字符串创建一个新的File实例
- 通过将给定的 file: URI 转换成一个抽象路径名来创建一个新的 File 实例
/***
* @author bincai
* @email 1355869831@qq.com
*/
public class No2_BuildFile {
public static void main(String[] args) {
// 通过将给定路径名字符串转换成抽象路径名来创建一个新 File 实例.
File file = new File("/Users/caibin/IOstudy/timg.jpeg");
System.out.println(file.length());
// 根据 parent 路径名字符串和 child 路径名字符串创建一个新 File 实例.
File file2 = new File("/Users/caibin/IOstudy", "timg.jpeg");
System.out.println(file2.length());
// 通过给定的父抽象路径名和子路径名字符串创建一个新的File实例.
File file3 = new File(new File("/Users/caibin/IOstudy"), "timg.jpeg");
System.out.println(file3.length());
try {
// 通过将给定的 file: URI 转换成一个抽象路径名来创建一个新的 File 实例.
URI url = new URI("file", null, "/Users/caibin/IOstudy/timg.jpeg", null, null);
File file4 = new File(url);
System.out.println(file4.length());
} catch (Exception e) {
System.out.println(e);
}
}
}
4.File类的常用API
- 名称/路径
- getName() 获取文件名
- getPath() 获取路径(构建是是什么路径就是绝对路径)
- getAbsoultePath() 获取绝对路径
- getParent() 获取父路径,把getPath文件的名称分隔符前面的拿出来,没有返回为null
- 文件状态
- exists() 是否存在
- isFile() 是否是文件,目录不是文件夹,在存在的情况下只有文件和目录两种状态!
- isDirectory() 是否是目录
- 文件长度
- length() 文件长度,如果是目录或不存在返回0, 返回的是long类型
- 创建删除
- createNewFile() 创建文件,如果创建不成功(比如已经存在,则返回false),不能创建文件夹
- delete() 删除文件,如果是删除文件夹要使用递归!!!
- 文件夹相关
- mkdir()/mkdirs() 创建目录,mkdir必须保证上一级存在,mkdirs如果父目录不存在则一同创建,尽量用mkdirs()
- list() 返回下级名称(包括文件和文件夹)数组,只是下一级
- listFiles() 返回下级File对象(包括文件和文件夹)数组,只是下一级
三 字节流和字符流
1.字节流
- InputStream
- void close() 释放系统资源
- read() 从输入流读取数据的下一字节,这是一个一个来,读到文件末尾读不到了返回-1
- read(byte[] b) 从输入流读取一些字节数存到缓冲器阵列b,这是一块一块来,读到文件末尾读不到了返回-1
- OutputStream
- void close() 释放系统资源
- void flush()
- void write(int)
2.字符流
- Reader
- void close() 释放系统资源
- int read() 读到文件末尾读不到了返回-1
- Writer
- void close() 释放系统资源
- void flush()
*void write(String)
四 节点流和处理流
1.节点流
- FileInputStream/FileOutputStream
- FileInputStream 通过字节方式读取文件,FileInputStream的src必须存在
- FileOutputStream 通过字节方式写出或追加数据到文件,FileOutputStream的src可以不存在,不存在的话创建一个
- FileReader/FileWriter(仅适合字符文件)
- FileReader 读取文本文件
- FileWriter 写出或追加字符到文件
- 字节数组流(ByteArrayInputStream/ByteArrayOutputStream) 字节数组流是基于内存的,所以不需要关闭,任何东西都可以转换成字节数组!
- ByteArrayInputStream
- ByteArrayOutputStream
2.处理流
⑴什么是处理流
处理流使用的是装饰器设计模式,对节点流进行增强。
处理流的重要特征:
- 性能提升
- 底层都是节点流
- 释放处理流时会自动释放内部的节点流,如果手动释放,从里到外依次释放
⑵常用的处理流
- 缓冲流,提高效率,缓冲流嵌套一次就行,多次嵌套没用
- IO转换流,如字节流转字符流,前提是这个字节流是操作纯文本的
等等。。。
五 乱码实现的原因
- ⑴ 字节数不够
- ⑵ 字符集不统一
public class No6_EnDecode {
public static void main(String[] args) throws IOException {
String input = "io流";
//编码 默认的字符集是根据项目配置来的
byte[] byte1 = input.getBytes();
System.out.println(byte1.length);
//使用指定字符集编码
byte[] byte2 = input.getBytes("gbk");
System.out.println(byte2.length);
//解码
String output = new String(byte1);
System.out.println(output);
//乱码1 字节数不够,导致乱码
String output2 = new String(byte1,0,byte1.length-1);
System.out.println(output2);
//乱码2 字符集不一致
String output3 = new String(byte1,"gbk");
System.out.println(output3);
}
}
六 commonsIO
1.引入依赖
<dependencies>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.3</version>
</dependency>
</dependencies>
2.常用方法
⑴统计文件以及目录大小
public class No100_Commonsio {
public static void main(String[] args) {
// 统计文件的大小
long fileSize = FileUtils.sizeOf(new File("timg.jpeg"));
System.out.println(fileSize);
// 统计目录的大小
long directroySize = FileUtils.sizeOf(new File("directory"));
System.out.println(directroySize);
}
}
⑵列出子孙集
// 递归子集
Collection<File> son = FileUtils.listFiles(new File("directory"), EmptyFileFilter.NOT_EMPTY, null);
for(File file : son){
System.out.println(file.getAbsolutePath());
}
// 递归子孙集
Collection<File> all = FileUtils.listFiles(new File("directory"), EmptyFileFilter.NOT_EMPTY, DirectoryFileFilter.INSTANCE);
for(File file : all){
System.out.println(file.getAbsolutePath());
}
⑶读取写出文件
String msg = FileUtils.readFileToString(new File("out.txt"),"UTF-8");
System.out.println(msg);
byte[] msgByte = FileUtils.readFileToByteArray(new File("out.txt"));
System.out.println(msgByte.length);
//逐行读取
List<String> msgs = FileUtils.readLines(new File("out.txt"),"UTF-8");
for(String line : msgs){
System.out.println(line);
}
//写出文件
FileUtils.write(new File("write.txt"),"蔡","UTF-8");
//最后一个参数是追加
FileUtils.writeStringToFile(new File("write.txt"),"小","UTF-8",true);
FileUtils.writeByteArrayToFile(new File("write.txt"),"彬".getBytes("UTF-8"),true);
//写出列表
List<String> msgList = new ArrayList<String>();
msgList.add("第");
msgList.add("一");
FileUtils.writeLines(new File("write.txt"),msgList,"/",true);
⑷文件转移
public class No101_CommonsIO_02 {
public static void main(String[] args) throws Exception {
// 拷贝文件到文件
FileUtils.copyFile(new File("timg.jpeg"), new File("timg-copy.jpeg"));
// 拷贝文件到目录
FileUtils.copyFileToDirectory(new File("timg.jpeg"), new File("dest"));
// 复制目录及子孙所有文件到目录
FileUtils.copyDirectoryToDirectory(new File("directory"), new File("dest"));
//复制目录下的文件到另外一个目录
FileUtils.copyDirectory(new File("directory"), new File("dest"));
//拷贝url到文件
FileUtils.copyURLToFile(new URL("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1540034625381&di=419a1f10036b4421ae95a4ac5dbd9b07&imgtype=0&src=http%3A%2F%2Fpic31.nipic.com%2F20130728%2F7447430_145214729000_2.jpg"), new File("url.jpg"));
}
}