案例
- 案例1:将集合中的对象排序之后存储到文件中。选择TreeSet。
package com.jxufe_ldl.selfstudy;
public class Student {
private String name;
private int chenise;
private int math;
private int enghish;
public Student() {
}
public Student(String name, int chenise, int math, int enghish) {
this.name = name;
this.chenise = chenise;
this.math = math;
this.enghish = enghish;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getChenise() {
return chenise;
}
public void setChenise(int chenise) {
this.chenise = chenise;
}
public int getMath() {
return math;
}
public void setMath(int math) {
this.math = math;
}
public int getEnghish() {
return enghish;
}
public void setEnghish(int enghish) {
this.enghish = enghish;
}
public int getSun() {
return chenise + math + enghish;
}
}
package com.jxufe_ldl.selfstudy;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.*;
/*
从键盘输入5个学生的信息,保存到集合,再写入到文件
格式:姓名,语文成绩,数学成绩,英语成绩
*/
public class ListToFile {
public static void main(String[] args) throws IOException {
// 创建TreeSet集合对象
Set<Student> ts = new TreeSet<Student>(new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
// 主要条件
int num = s2.getSun() - s1.getSun();
// 次要条件
int num2 = num == 0? s2.getChenise() - s1.getChenise() : num;
int num3 = num2 == 0? s2.getMath() - s1.getMath() : num2;
int num4 = num3 == 0 ? s1.getName().compareTo(s1.getName()) :num3;
return num4;
}
});
// 键盘录入5个学生成绩
Scanner sc = new Scanner(System.in);
System.out.println("请录入5个学生成绩:");
for (int i = 0; i < 5; i++) {
System.out.println("请输入第"+(i+1)+"学生姓名:");
String name = sc.next();
System.out.println("请输入语文成绩:");
int chenise = sc.nextInt();
System.out.println("请输入数学成绩:");
int math = sc.nextInt();
System.out.println("请输入英语成绩:");
int enghtis = sc.nextInt();
// 创建学生对象
Student stu = new Student(name, chenise, math, enghtis);
// 添加到集合
ts.add(stu);
}
// 创建字符缓冲输出流对象
BufferedWriter bw = new BufferedWriter(new FileWriter("day10//java//student.txt"));
// 遍历集合,并写数据
for (Student stu : ts) {
// 把学生对象拼接成指定字符串
StringBuilder sb = new StringBuilder();
sb.append(stu.getName()).append("-").append(stu.getChenise()).append("-").append(stu.getMath()).append(
"-").append(stu.getEnghish()).append("-").append(stu.getSun());
//写数据
bw.write(sb.toString());
bw.newLine();
bw.flush();
}
// 释放资源
bw.close();
}
}
- 案例2:复制单级目录
package com.jxufe_ldl.selfstudy;
import java.io.*;
/*
复制单级文件夹中的内容
*/
public class OneFolderCopy {
public static void main(String[] args) throws IOException {
// 创建源数据文件对象
File srcFolder = new File("D://jxufe");
// 获取源数据目录的名称
String srcFolderName = srcFolder.getName();
// 创建目的数据文件对象
File destFolder = new File("day10//java", srcFolderName);
// 创建目的数据的目录
if (!destFolder.exists()) {
destFolder.mkdir();
}
// 获取源数据目录下的文件数组
File[] listFiles = srcFolder.listFiles();
// 遍历文件数组
for (File srcFile : listFiles) {
// 获取文件名
String foldername = srcFile.getName();
//拼接目的文件对象
File destFile = new File(destFolder, foldername);
// 复制文件
copyFile(srcFile, destFile);
}
}
private static void copyFile(File srcFile, File destFile) throws IOException {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcFile));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFile));
byte[] bys = new byte[1024];
int len = 0;
while ((len = bis.read(bys)) != -1) {
bos.write(bys, 0, len);
}
bis.close();
bos.close();
}
}
- 案例3:复制多级目录
package com.jxufe_ldl.selfstudy;
import java.io.*;
public class listFolderCopy {
public static void main(String[] args) throws IOException{
// 创建源数据文件对象
File srcFile = new File("D:\\jxufe");
// 创建目的地数据文件对象
File distFile = new File("F:\\");
// 把D盘的文件赋值到F盘
copyFolder(srcFile, distFile);
}
private static void copyFolder(File srcFile, File distFile) throws IOException {
// 判断srcFile是否为目录
if (srcFile.isDirectory()) {
// 在目的地下创建和源数据一样的目录
File newFolder = new File(distFile, srcFile.getName());
if (!newFolder.exists()) {
newFolder.mkdir();
}
//获取源数据目录下的所有文件或目录数组
File[] files = srcFile.listFiles();
// 变量files数组,得到每一个File对象
for (File file:files) {
copyFolder(file, newFolder);
}
} else {
// 否则就是文件,就把该文件用字节流复制到指定目录下
File newFile = new File(distFile, srcFile.getName());
copyFile(srcFile, newFile);
}
}
private static void copyFile(File srcFile, File destFile) throws IOException {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcFile));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFile));
byte[] bys = new byte[1024];
int len = 0;
while ((len = bis.read(bys)) != -1) {
bos.write(bys, 0, len);
}
bis.close();
bos.close();
}
}
标准输入流和输出流
-
System.in:标准输入流,是一个字节输入流,可以接收控制台输入的内容
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
String s = br.readLine();
-
System.out:标准输出流,是一个字节输出流,可以将内容输出到控制台。
打印流:打印流都是输出流
- 字节打印流:PrintStream
- write(97)、print(97)以及println(97)的区别?
write(97); //a
print(97); //97
println(97); //97并且换行
- write(97)、print(97)以及println(97)的区别?
- 字符打印流:PrintWriter
- 构造方法:
PrintWriter(String fileName):根据字符串类型的文件路径创建字符打印流对象,需要手动调用flush方法获取close方法刷新到文件中。
PrintWriter(Writer out, boolean autoFlush):创建字符打印流对象,需要一个Writer,参数2表示自动刷新。当调用println ,printf ,或format方法时自动刷新。
- 成员方法:
public void println("字符串");
- 构造方法:
package com.jxufe_ldl.class02;
import java.io.*;
public class PrintWriteDemo {
public static void main(String[] args) {
// 复制文件
// 1. 创建字符缓冲输入流和字符打印流对象
try(BufferedReader br = new BufferedReader(new FileReader("day10//oneFloderCopy.java"));
PrintWriter pw = new PrintWriter(new FileWriter("day10//java//oneFloderCopy.java"));) {
// 复制文件
String line;
while ((line = br.readLine()) != null) {
pw.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
序列化流和反序列化流
-
序列化:将对象写到文件中叫做序列化
-
反序列化:将文件中的对象读出来叫做反序列化
- 序列化流:ObjectOutputStream 是一个字节流,能够将一个对象写到文件中
- 构造方法:
ObjectOutputStream(OutputStream out):创建一个写入指定的OutputStream的ObjectOutputStream。
- 成员方法:
void writeObject(Object obj):将obj对象写到文件中
- 反序列化流:ObjectInputStream 是一个字节流,能够将文件中的对象读到内存中
- 构造方法:
ObjectInputStream(InputStream in):创建从指定的InputStream读取的ObjectInputStream。
- 成员方法:
Object readObject():从ObjectInputStream读取一个对象。
-
注意事项:
1. 序列化的对象必须实现一个Serializable标记型接口。
2. class文件中的序列化id和序列化文件中的id不一致导致InvalidClassException异常解决办法:固定序列化id值:private static final long serialVersionUID = 42L;
-
如果某个成员变量不想被序列化,那么使用transient修饰该成员变量
-
如果序列化了多个对象需要使用使用反序列化流while循环读对象,读到文件的末尾不是返回null,而是抛出一个EOFException异常
解决办法:
方式1:使用try…catch处理异常,不打印异常信息。
方式2:如果是需要将多个对象序列化到文件中,可以先将对象存到集合中,将集合序列化到文件中。(还是序列化一个对象)
package com.jxufe_ldl.class02;
import java.io.Serializable;
public class Student implements Serializable {
private static final long serialVersionUID = 42L;
private String name;
private int chinese;
private transient int math;
public Student() {
}
public Student(String name, int chinese, int math) {
this.name = name;
this.chinese = chinese;
this.math = math;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getChinese() {
return chinese;
}
public void setChinese(int chinese) {
this.chinese = chinese;
}
public int getMath() {
return math;
}
public void setMath(int math) {
this.math = math;
}
public int getSum() {
return chinese + math;
}
@Override
public String toString() {
return name + "," + chinese + "," + math + "," + getSum();
}
}
package com.jxufe_ldl.class02;
import java.io.*;
public class SerializableObjectDemo {
public static void main(String[] args) throws IOException, ClassNotFoundException {
write();
read();
}
private static void read() throws IOException, ClassNotFoundException {
// 创建反序列化对象
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("day10//java//oos.txt"));
// 反序列化对象
Student s1 = (Student) ois.readObject();
// 打印
System.out.println(s1);
// 释放资源
ois.close();
}
private static void write() throws IOException {
// 创建序列化对象
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("day10//java//oos.txt"));
// 创建一个学生对象
Student s1 = new Student("于曼丽", 99, 98);
// 序列化对象
oos.writeObject(s1) ;
// 释放资源
oos.close();
}
}
Properties集合
- 构造方法:
Properties prop=new Properties()
- 成员方法:
Object setProperty(String key, String value):根据key存value值,返回值是被替换的value。
String getProperty(String key):根据key获取对应的value值
- Properties集合和IO流结合使用
- 将集合中的数据存到文件中:
void store(Writer writer, String comments):参数2comments表示添加的数据的描述信息,相当于注释。可以是null表示没有
- 将文件中的数据读到集合中
void load(Reader reader):读取文件中的数据到集合中。
- 将集合中的数据存到文件中:
package com.jxufe_ldl.class03;
import java.util.Random;
import java.util.Scanner;
public class Guess {
public Guess() {
}
public void start() {
// 产生一个随机数
Random r = new Random();
int num = r.nextInt(100)+1;
// 键盘录入一个数字
Scanner sc = new Scanner(System.in);
while (true) {
System.out.println("请输入你猜的数字");
int guessNum = sc.nextInt();
if (guessNum > num) {
System.out.println("你猜大了");
} else if (guessNum < num) {
System.out.println("你猜小了");
} else {
System.out.println("恭喜你,猜对了!");
break;
}
}
}
}
package com.jxufe_ldl.class03;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
/*
实现玩猜数字小游戏,试玩3次,3次之后显示请充值
分析:
1. 创建玩游戏的方法
2. 编写一个配置文件
3. 使用Properties中的load方法加载配置文件
4. 玩游戏
*/
public class GuessDemo {
public static void main(String[] args) throws IOException {
// 创建Guess对象
Guess g = new Guess();
// 创建Properties对象
Properties prop = new Properties();
// 常见字符输入流对象
FileReader fr = new FileReader("day10//java//guess.properties");
// 调用load方法加载到集合中
prop.load(fr);
fr.close();
int count = Integer.parseInt(prop.getProperty("count"));
if (count <= 3) {
g.start();
count++;
// 更新配置文件
prop.setProperty("count", String.valueOf(count));
FileWriter fw = new FileWriter("day10//java//guess.properties");
prop.store(fw, null);
fw.close();
} else {
System.out.println("请充值!");
}
}
}
guess.properties // 记录游戏次数的配置文件
#Thu Aug 15 19:44:08 CST 2019
count=1