0. 概述
按照操作方式分类
按照操作对象分类
1.递归遍历目录
public class Demo02 {
public static void main(String[] args) {
File f = new File("E:\\MISC");
getAllFile(f);
}
public static void getAllFile(File f) {
//获取目录下所有文件或目录,并赋值给File数组
File[] files = f.listFiles();
//循环遍历,获取每一个file对象
//Objects.requireNonNull(files)判断非空
for (File file : Objects.requireNonNull(files)) {
//如果是文件,则递归调用方法
if (file.isDirectory()) {
getAllFile(file);
//否则输出绝对路径
} else System.out.println(file.getAbsolutePath());
}
}
}
2. 字节流
2.1 字节流和字符流区别
- 用txt打开,人能看懂的是字符流,看不懂的是字节流
- 用Input和Output的是字节流,用Wridter和Reader的是字符流,带Buffer的是缓冲流
- 获取文本信息的二进制文件,比如图片,mp3,视频文件等,使用字节流
- 文本信息使用字符流
- 字符流=字节流+编码表
2.2 字节流写数据
字节流写数据的三种方式
第一种:一次写一个字节的数据
public class Demo03 {
public static void main(String[] args) throws IOException {
//此处使用的是相对路径
FileOutputStream fos = new FileOutputStream("test.txt");
/*
做了三件事情:
调用系统功能创建文件
创建字节输出对象
让字节输出对象指向创建好的文件
*/
fos.write(97);
//释放资源
fos.close();
}
}
第二种:一次写一个字节数组的数据
public class Demo03 {
public static void main(String[] args) throws IOException {
FileOutputStream fos = new FileOutputStream("test.txt");
//获取字节数组
byte[] bytes = "啊哈哈哈".getBytes();
//写入数据
fos.write(bytes);
//释放资源
fos.close();
}
}
第三种:一次写一个字节数组的部分数据
public class Demo03 {
public static void main(String[] args) throws IOException {
FileOutputStream fos = new FileOutputStream("test.txt");
byte[] bytes = "啊哈哈哈".getBytes();
//写入[啊哈],一个中文占3个字节
fos.write(bytes,0,6);
//释放资源
fos.close();
}
}
字节流写数据实现换行
public class Demo04 {
public static void main(String[] args) throws IOException {
FileOutputStream fos = new FileOutputStream("demo.txt");
for (int i = 0; i < 10; i++) {
//写入数据
fos.write("bug".getBytes());
//换行操作
fos.write("\r\n".getBytes());
}
fos.close();
}
}
不同操作系统的换行符不同
- Windows:\r\n
- Linux:\n
- Mac:\r
字节流数据追加写入
public class Demo04 {
public static void main(String[] args) throws IOException {
//创建字节输出流对象
FileOutputStream fos = new FileOutputStream("demo.txt", true);
//循环写入数据
for (int i = 0; i < 10; i++) {
fos.write("bug".getBytes());
fos.write("\r\n".getBytes());
}
fos.close();
}
}
FileOutputStream fos = new FileOutputStream("demo.txt", true);
中两个参数分别为(写入的文件位置,是否追加写入)。其中第二个参数若不填或为false,则视为不追加写入,每次运行写入均是覆盖原文件从头开始写入数据。
2.3 字节流读数据
读取中文数据
public class Demo06 {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("test.txt");
// 声明一个字节数组
byte[] b = new byte[1024];
StringBuffer str = new StringBuffer();
int len;
// 循环读取
while ((len = fis.read(b)) != -1) {
str.append(new String(b, 0, len));
}
System.out.println(str.toString());
fis.close();
}
}
复制文本文件
public class Demo07 {
public static void main(String[] args) throws IOException {
//根据数据源创建字节输入流对象
FileInputStream fis = new FileInputStream("test.txt");
//根据目标位置创建字节输出流对象
FileOutputStream fos = new FileOutputStream("E:\\demo\\test.txt");
//通过循环读写数据达到复制文本文件的目的
int by;
while ((by = fis.read()) != -1) {
fos.write(by);
}
fos.close();
fis.close();
}
}
复制图片
public class Demo08 {
public static void main(String[] args) throws IOException {
//根据数据源创建字节输入流对象
FileInputStream fis = new FileInputStream("huahua.jpg");
//根据目标位置创建字节输出流对象
FileOutputStream fos = new FileOutputStream("E:\\demo\\huahua.jpg");
//创建字节数组
byte[] bytes = new byte[1024];
//定义长度
int len;
//通过循环读写数据达到复制图片的目的
while ((len = fis.read(bytes)) != -1) {
fos.write(bytes, 0, len);
}
fos.close();
fis.close();
}
}
复制视频
public class CopyVideo {
public static void main(String[] args) throws IOException {
//记录开始时间
long startTime = System.currentTimeMillis();
//根据数据源创建输入流
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("huahua.mp4"));
//根据目标位置创建输出流
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("E:\\demo\\huahua.mp4"));
//定义字节数组
byte[] bytes = new byte[1024];
//定义长度
int len;
//循环读取
while ((len = bis.read(bytes)) != -1) {
bos.write(bytes, 0, len);
}
//关闭资源
bis.close();
bos.close();
//记录结束时间
long endTime = System.currentTimeMillis();
System.out.println((endTime - startTime) + "毫秒");
}
}
3.字符流
3.2 字符流写数据
public class OutputStreamOne {
public static void main(String[] args) throws IOException {
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("a.txt"));
//osw.write("啊哈");
osw.write("abcd", 0, 3);
//先刷新flush()后关闭
osw.close();
}
}
3.3 字符流读数据
public class InputStreamOne {
public static void main(String[] args) throws IOException {
InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"));
char[] chs = new char[1024];
int len;
while ((len = isr.read()) != -1) {
System.out.println(new String(chs, 0, len));
}
}
}
3.4 集合和文件操作
把集合数据写入到文件中
public class ListStreamDemo {
public static void main(String[] args) throws IOException {
//创建集合
ArrayList<Student> al = new ArrayList<>();
//创建学生对象
Student s1 = new Student(101, "阿猫", 18, "北京");
Student s2 = new Student(102, "阿狗", 18, "上海");
Student s3 = new Student(103, "阿里", 18, "杭州");
Student s4 = new Student(104, "阿豹", 18, "深圳");
Student s5 = new Student(105, "阿毛", 18, "广州");
//添加学生对象到集合
al.add(s1);
al.add(s2);
al.add(s3);
al.add(s4);
al.add(s5);
//创建字符缓冲输出流对象
BufferedWriter bw = new BufferedWriter(new FileWriter("student.txt"));
//遍历集合,得到学生对象
for (Student s : al) {
StringBuilder sb = new StringBuilder();
sb.append(s.getNum()).append(",").append(s.getName()).append(",").append(s.getAge()).append(",").append(s.getAddress());
//写数据
bw.write(sb.toString());
bw.newLine();
bw.flush();
}
bw.close();
}
}
读取文件数据到集合
public class StreamListDemo {
public static void main(String[] args) throws IOException {
//创建字符缓冲输入流对象
BufferedReader br = new BufferedReader(new FileReader("student.txt"));
//创建集合对象
ArrayList<Student> al = new ArrayList<>();
String line;
//循环读数据
while ((line = br.readLine()) != null) {
//用string.split()方法分割字符串
String[] split = line.split(",");
//创建学生对象
Student s = new Student();
//取出字符串每个元素并进行赋值,Integer.parseInt()把String类型转换为int
s.setNum(Integer.parseInt(split[0]));
s.setName(split[1]);
s.setAge(Integer.parseInt(split[2]));
s.setAddress(split[3]);
al.add(s);
}
//释放资源
br.close();
//遍历集合
for (Student s : al) {
//定义StringBuilder用于拼接
StringBuilder sb = new StringBuilder();
//输出拼接后的数据
System.out.println(sb.append(s.getNum()).append(",").append(s.getName()).append(",").append(s.getAge()).append(",").append(s.getAddress()));
}
}
}
3.5 字符打印流
public class PrintWriterDemo {
public static void main(String[] args) throws IOException {
//两个参数分别为:打印输出的文件位置,是否自动刷新
PrintWriter pw = new PrintWriter(new FileWriter("demo1.txt"), true);
pw.println("hello");
pw.println("world");
pw.close();
}
}
3.6 对象的序列化和反序列化
序列化:ObjectOutputStream
//完成序列化需要实现Serializable,Serializable只是一个标识接口没有实现方法
public class Animal implements Serializable {
private String name;
private int age;
public Animal() {
}
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public class Output {
public static void main(String[] args) throws IOException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("oos.txt"));
//创建阿猫对象
Animal a = new Animal("阿猫", 3);
//执行序列化方法
oos.writeObject(a);
//关闭资源
oos.close();
}
}
反序列化
public class Input {
public static void main(String[] args) throws IOException, ClassNotFoundException {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("oos.txt"));
//从ObjectInputStream读取一个对象
Object o = ois.readObject();
Animal a = (Animal) o;
System.out.println(a.getName() + a.getAge());
//释放资源
ois.close();
}
}
序列化流常见问题
- 用对象序列化流序列化一个对象后,修改对象所属的类文件会抛出InvalidClassException异常
- 针对上述问题的解决方法为:给对象所属的类添加一个字段serialVersionUID。注意:改字段必须是static, final, long类型,建议使用private修饰,同时建议所有可序列化的类显式声明serialVersionUid. 数组类除外,数组类具有默认的计算值不能声明一个显式的serialVersionUID,并且也放弃了匹配serialVersionUID值得要求
- 若一个对象中的某个成员变量的值不想被序列化,需要给成员变量添加 transient 关键字进行修饰
3.7 Properties
Properties作为Map使用
public class Demo01 {
public static void main(String[] args) {
//创建集合对象
Properties p = new Properties();
//存储元素
p.put("a001", "阿猫");
p.put("a002", "阿狗");
p.put("a003", "阿豹");
//遍历
for (Object key : p.keySet()) {
System.out.println(key + "," + p.get(key));
}
//也可以直接输出
System.out.println(p);
}
}
集合操作之
store(fw, null)
参数为(输出流,注释信息)- p.load(fr) 参数为(输出流)
public class Demo02 {
public static void main(String[] args) throws IOException {
store();
load();
}
//读文件
private static void load() throws IOException {
Properties p = new Properties();
FileReader fr = new FileReader("fw.txt");
p.load(fr);
System.out.println(p);
fr.close();
}
//写文件
private static void store() throws IOException {
Properties p = new Properties();
p.setProperty("b001", "阿猫");
p.setProperty("b002", "阿狗");
p.setProperty("b003", "阿豹");
//调用字符流写入
FileWriter fw = new FileWriter("fw.txt");
p.store(fw, null);
fw.close();
}
}