文章目录
- 1. File类
- 1.1 File类概述和构造方法
- 1.2 File类创建功能
- 1.3 File类判断和获取功能
- 1.4 File类删除功能
- 2. 递归
- 2.1 递归
- 2.2 递归求阶乘
- 2.3 递归遍历目录
- 3. IO流
- 3.1 IO流概述和分类
- 3.2 字节流写数据
- 3.3 字节流写数据的三种方式
- 3.4 字节流写数据的两个小问题
- 3.5 字节流写数据加异常处理
- 3.6 字节流读数据(一次读一个字节数据)
- 3.7 字节流复制文本文件
- 3.8 字节流读数据(一次读一个字节数组数据)
- 3.9 字节流复制图片
- 4. 字节缓冲流
-
- 5. 字符流
- 5.1 为什么会出现字符流
- 5.2 编码表
- 5.3 字符串中的编码解码问题
- 5.4 字符流中的编码解码问题
- 5.5 字符流写数据的5种方式
- 5.6 字符流读数据的2种方式
- 5.7 字符流复制Java文件
- 5.8 字符流复制Java文件改进版
- 5.9 字符缓冲流
- 5.10 字符缓冲流复制Java文件
- 5.11 字符缓冲流特有功能
- 5.12 字符缓冲流特有功能复制Java文件
- 5.13 IO流小结
- 6. 练习案例
- 6.1 集合到文件
- 6.2 文件到集合
- 6.3 点名器
- 6.4 集合到文件改进版
- 6.5 文件到集合改进版
- 7. IO流案例
- 7.1 集合到文件数据排序改进版
- 7.1.1 案例需求
- 7.1.2 分析步骤
- 7.1.3 代码实现
- 7.2 复制单级文件夹
- 7.2.1 案例需求
- 7.2.2 分析步骤
- 7.2.3 代码实现
- 7.3 复制多级文件夹
- 7.3.1 案例需求
- 7.3.2 分析步骤
- 7.3.3 代码实现
- 7.4 复制文件的异常处理
- 7.4.1 基本做法
- 7.4.2 JDK7版本改进
- 7.4.3 JDK9版本改进
- 8. IO特殊操作流
- 8.1 标准输入流
- 8.2 标准输出流
- 8.3 字节打印流
- 8.4 字符打印流
- 8.5 复制Java文件打印流改进版
- 8.6 对象序列化流
- 8.7 对象反序列化流
- 8.8 serialVersionUID&transient
- 9. Properties集合
- 9.1 Properties作为Map集合的使用
- 9.2 Properties作为Map集合的特有方法
- 9.3 Properties和IO流相结合的方法
- 9.4 游戏次数案例
1. File类
1.1 File类概述和构造方法
-
File类介绍
- 它是文件和目录路径名的抽象表示
- 文件和目录是可以通过File封装成对象的
- 对于File而言,其封装的并不是一个真正存在的文件,仅仅是一个路径名而已。它可以是存在的,也可以是不存在的。将来是要通过具体的操作把这个路径的内容转换为具体存在的
-
File类的构造方法
方法名 | 说明 |
---|
File(String pathname) | 通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例 |
File(String parent, String child) | 从父路径名字符串和子路径名字符串创建新的 File实例 |
File(File parent, String child) | 从父抽象路径名和子路径名字符串创建新的 File实例 |
-
示例代码
public class FileDemo01 {
public static void main(String[] args) {
File f1 = new File("/Volumes/DATA1/000-develop/demo/java.txt");
System.out.println(f1);
File f2 = new File("/Volumes/DATA1/000-develop/demo","java.txt");
System.out.println(f2);
File f3 = new File("/Volumes/DATA1/000-develop/demo");
File f4 = new File(f3,"java.txt");
System.out.println(f4);
}
}
1.2 File类创建功能
1.3 File类判断和获取功能
1.4 File类删除功能
2. 递归
2.1 递归
2.2 递归求阶乘
2.3 递归遍历目录
-
案例需求
给定一个路径(/Volumes/DATA1/000-develop/IdeaProjects/myFile),通过递归完成遍历该目录下所有内容,并把所有文件的绝对路径输出在控制台
-
代码实现
public class DiGuiDemo02 {
public static void main(String[] args) {
File srcFile = new File("/Volumes/DATA1/000-develop/IdeaProjects/myFile");
getAllFilePath(srcFile);
}
public static void getAllFilePath(File srcFile) {
File[] fileArray = srcFile.listFiles();
if(fileArray != null) {
for(File file : fileArray) {
if(file.isDirectory()) {
getAllFilePath(file);
} else {
System.out.println(file.getAbsolutePath());
}
}
}
}
}
3. IO流
3.1 IO流概述和分类
- IO流介绍
- IO:输入/输出(Input/Output)
- 流:是一种抽象概念,是对数据传输的总称。也就是说数据在设备间的传输称为流,流的本质是数据传输
- IO流就是用来处理设备间数据传输问题的。常见的应用:文件复制;文件上传;文件下载
- IO流的分类
- IO流的使用场景
- 如果操作的是纯文本文件,优先使用字符流
- 如果操作的是图片、视频、音频等二进制文件。优先使用字节流
- 如果不确定文件类型,优先使用字节流。字节流是万能的流
3.2 字节流写数据
3.3 字节流写数据的三种方式
-
写数据的方法分类
方法名 | 说明 |
---|
void write(int b) | 将指定的字节写入此文件输出流 一次写一个字节数据 |
void write(byte[] b) | 将 b.length字节从指定的字节数组写入此文件输出流 一次写一个字节数组数据 |
void write(byte[] b, int off, int len) | 将 len字节从指定的字节数组开始,从偏移量off开始写入此文件输出流 一次写一个字节数组的部分数据 |
-
示例代码
public classFileOutputStreamDemo02 {
public static void main(String[] args) throws IOException {
FileOutputStream fos = new FileOutputStream("myByteStream/fos.txt");
byte[] bys = "abcde".getBytes();
fos.write(bys,1,3);
fos.close();
}
}
3.4 字节流写数据的两个小问题
3.5 字节流写数据加异常处理
3.6 字节流读数据(一次读一个字节数据)
3.7 字节流复制文本文件
-
案例需求
把“/Volumes/DATA1/000-develop/IdeaProjects/myByteStream/abc.txt”复制到模块目录下的“def.txt”
-
实现步骤
-
复制文本文件,其实就把文本文件的内容从一个文件中读取出来(数据源),然后写入到另一个文件中(目的地)
-
数据源:
/Volumes/DATA1/000-develop/IdeaProjects/myByteStream/abc.txt — 读数据 — InputStream — FileInputStream
-
目的地:
myByteStream/def.txt — 写数据 — OutputStream — FileOutputStream
-
代码实现
public class CopyTxtDemo {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("myByteStream/abc.txt");
FileOutputStream fos = new FileOutputStream("myByteStream/def.txt");
int by;
while ((by=fis.read())!=-1) {
fos.write(by);
}
fos.close();
fis.close();
}
}
3.8 字节流读数据(一次读一个字节数组数据)
-
一次读一个字节数组的方法
- public int read(byte[] b):从输入流读取最多b.length个字节的数据
- 返回的是读入缓冲区的总字节数,也就是实际的读取字节个数
-
示例代码
public class FileInputStreamDemo02 {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("myByteStream/fos.txt");
byte[] bys = new byte[1024];
int len;
while ((len=fis.read(bys))!=-1) {
System.out.print(new String(bys,0,len));
}
fis.close();
}
}
3.9 字节流复制图片
-
案例需求
把“myByteStream/helloworld.jpeg”复制到模块目录下的“myByteStream/helloworldNew.jpeg”
-
实现步骤
- 根据数据源创建字节输入流对象
- 根据目的地创建字节输出流对象
- 读写数据,复制图片(一次读取一个字节数组,一次写入一个字节数组)
- 释放资源
-
代码实现
public class _040_CopyJpgDemo {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("myByteStream/helloworld.jpeg");
FileOutputStream fos = new FileOutputStream("myByteStream/helloworldNew.jpeg");
byte[] bys = new byte[1024];
int len;
while ((len=fis.read(bys))!=-1) {
fos.write(bys,0,len);
}
fos.close();
fis.close();
}
}
4. 字节缓冲流
4.1 字节缓冲流构造方法
-
字节缓冲流介绍
-
构造方法:
方法名 | 说明 |
---|
BufferedOutputStream(OutputStream out) | 创建字节缓冲输出流对象 |
BufferedInputStream(InputStream in) | 创建字节缓冲输入流对象 |
-
示例代码
public class BufferStreamDemo {
public static void main(String[] args) throws IOException {
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("myByteStream/bos.txt"));
bos.write("hello\r\n".getBytes());
bos.write("world\r\n".getBytes());
bos.close();
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("myByteStream/bos.txt"));
byte[] bys = new byte[1024];
int len;
while ((len=bis.read(bys))!=-1) {
System.out.print(new String(bys,0,len));
}
bis.close();
}
}
4.2 字节流复制视频
-
案例需求
把myByteStream/字节流复制图片.avi 复制到模块目录下的 字节流复制图片New.avi
-
实现步骤
-
根据数据源创建字节输入流对象
-
根据目的地创建字节输出流对象
-
读写数据,复制视频
-
释放资源
-
代码实现
public class CopyAviDemo {
public static void main(String[] args) throws IOException {
long startTime = System.currentTimeMillis();
method4();
long endTime = System.currentTimeMillis();
System.out.println("共耗时:" + (endTime - startTime) + "毫秒");
}
public static void method4() throws IOException {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("myByteStream/字节流复制图片.avi"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("myByteStream/字节流复制图片New.avi"));
byte[] bys = new byte[1024];
int len;
while ((len=bis.read(bys))!=-1) {
bos.write(bys,0,len);
}
bos.close();
bis.close();
}
public static void method3() throws IOException {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("myByteStream/字节流复制图片.avi"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("myByteStream/字节流复制图片New.avi"));
int by;
while ((by=bis.read())!=-1) {
bos.write(by);
}
bos.close();
bis.close();
}
public static void method2() throws IOException {
FileInputStream fis = new FileInputStream("myByteStream/字节流复制图片.avi");
FileOutputStream fos = new FileOutputStream("myByteStream/字节流复制图片New.avi");
byte[] bys = new byte[1024];
int len;
while ((len=fis.read(bys))!=-1) {
fos.write(bys,0,len);
}
fos.close();
fis.close();
}
public static void method1() throws IOException {
FileInputStream fis = new FileInputStream("myByteStream/字节流复制图片.avi");
FileOutputStream fos = new FileOutputStream("myByteStream/字节流复制图片New.avi");
int by;
while ((by=fis.read())!=-1) {
fos.write(by);
}
fos.close();
fis.close();
}
}
5. 字符流
5.1 为什么会出现字符流
-
字符流的介绍
由于字节流操作中文不是特别的方便,所以Java就提供字符流
字符流 = 字节流 + 编码表
-
中文的字节存储方式
用字节流复制文本文件时,文本文件也会有中文,但是没有问题,原因是最终底层操作会自动进行字节拼接成中文,如何识别是中文的呢?
汉字在存储的时候,无论选择哪种编码存储,第一个字节都是负数
5.2 编码表
5.3 字符串中的编码解码问题
5.4 字符流中的编码解码问题
-
字符流中和编码解码问题相关的两个类
-
InputStreamReader:是从字节流到字符流的桥梁
它读取字节,并使用指定的编码将其解码为字符
它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集
-
OutputStreamWriter:是从字符流到字节流的桥梁
是从字符流到字节流的桥梁,使用指定的编码将写入的字符编码为字节
它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集
-
构造方法
方法名 | 说明 |
---|
InputStreamReader(InputStream in) | 使用默认字符编码创建InputStreamReader对象 |
InputStreamReader(InputStream in,String chatset) | 使用指定的字符编码创建InputStreamReader对象 |
OutputStreamWriter(OutputStream out) | 使用默认字符编码创建OutputStreamWriter对象 |
OutputStreamWriter(OutputStream out,String charset) | 使用指定的字符编码创建OutputStreamWriter对象 |
-
代码演示
public class ConversionStreamDemo {
public static void main(String[] args) throws IOException {
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("myCharStream/osw.txt"),"GBK");
osw.write("中国");
osw.close();
InputStreamReader isr = new InputStreamReader(new FileInputStream("myCharStream/osw.txt"),"GBK");
int ch;
while ((ch=isr.read())!=-1) {
System.out.print((char)ch);
}
isr.close();
}
}
5.5 字符流写数据的5种方式
-
方法介绍
方法名 | 说明 |
---|
void write(int c) | 写一个字符 |
void write(char[] cbuf) | 写入一个字符数组 |
void write(char[] cbuf, int off, int len) | 写入字符数组的一部分 |
void write(String str) | 写一个字符串 |
void write(String str, int off, int len) | 写一个字符串的一部分 |
-
刷新和关闭的方法
方法名 | 说明 |
---|
flush() | 刷新流,之后还可以继续写数据 |
close() | 关闭流,释放资源,但是在关闭之前会先刷新流。一旦关闭,就不能再写数据 |
-
代码演示
public class OutputStreamWriterDemo {
public static void main(String[] args) throws IOException {
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("myCharStream/osw.txt"));
char[] chs = {'a', 'b', 'c', 'd', 'e'};
osw.write("abcde", 1, 3);
osw.close();
}
}
5.6 字符流读数据的2种方式
-
方法介绍
方法名 | 说明 |
---|
int read() | 一次读一个字符数据 |
int read(char[] cbuf) | 一次读一个字符数组数据 |
-
代码演示
public class InputStreamReaderDemo {
public static void main(String[] args) throws IOException {
InputStreamReader isr = new InputStreamReader(new FileInputStream("myCharStream/ConversionStreamDemo.java"));
char[] chs = new char[1024];
int len;
while ((len = isr.read(chs)) != -1) {
System.out.print(new String(chs, 0, len));
}
isr.close();
}
}
5.7 字符流复制Java文件
-
案例需求
把模块目录下的“ConversionStreamDemo.java” 复制到模块目录下的“Copy.java”
-
实现步骤
- 根据数据源创建字符输入流对象
- 根据目的地创建字符输出流对象
- 读写数据,复制文件
- 释放资源
-
代码实现
public class CopyJavaDemo01 {
public static void main(String[] args) throws IOException {
InputStreamReader isr = new InputStreamReader(new FileInputStream("myCharStream/ConversionStreamDemo.java"));
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("myCharStream/Copy.java"));
char[] chs = new char[1024];
int len;
while ((len=isr.read(chs))!=-1) {
osw.write(chs,0,len);
}
osw.close();
isr.close();
}
}
5.8 字符流复制Java文件改进版
-
案例需求
使用便捷流对象,把模块目录下的“ConversionStreamDemo.java” 复制到模块目录下的“Copy.java”
-
实现步骤
-
根据数据源创建字符输入流对象
-
根据目的地创建字符输出流对象
-
读写数据,复制文件
-
释放资源
-
代码实现
public class CopyJavaDemo02 {
public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("myCharStream/ConversionStreamDemo.java");
FileWriter fw = new FileWriter("myCharStream/Copy.java");
char[] chs = new char[1024];
int len;
while ((len=fr.read(chs))!=-1) {
fw.write(chs,0,len);
}
fw.close();
fr.close();
}
}
5.9 字符缓冲流
-
字符缓冲流介绍
-
构造方法
方法名 | 说明 |
---|
BufferedWriter(Writer out) | 创建字符缓冲输出流对象 |
BufferedReader(Reader in) | 创建字符缓冲输入流对象 |
-
代码演示
public class BufferedStreamDemo01 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("myCharStream/bw.txt"));
char[] chs = new char[1024];
int len;
while ((len=br.read(chs))!=-1) {
System.out.print(new String(chs,0,len));
}
br.close();
}
}
5.10 字符缓冲流复制Java文件
-
案例需求
把模块目录下的ConversionStreamDemo.java 复制到模块目录下的 Copy.java
-
实现步骤
- 根据数据源创建字符缓冲输入流对象
- 根据目的地创建字符缓冲输出流对象
- 读写数据,复制文件,使用字符缓冲流特有功能实现
- 释放资源
-
代码实现
public class CopyJavaDemo01 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("myCharStream/ConversionStreamDemo.java"));
BufferedWriter bw = new BufferedWriter(new FileWriter("myCharStream/Copy.java"));
char[] chs = new char[1024];
int len;
while ((len=br.read(chs))!=-1) {
bw.write(chs,0,len);
}
bw.close();
br.close();
}
}
5.11 字符缓冲流特有功能
5.12 字符缓冲流特有功能复制Java文件
-
案例需求
使用特有功能把模块目录下的ConversionStreamDemo.java 复制到模块目录下的 Copy.java
-
实现步骤
- 根据数据源创建字符缓冲输入流对象
- 根据目的地创建字符缓冲输出流对象
- 读写数据,复制文件,使用字符缓冲流特有功能实现
- 释放资源
-
代码实现
public class CopyJavaDemo02 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("myCharStream/ConversionStreamDemo.java"));
BufferedWriter bw = new BufferedWriter(new FileWriter("myCharStream/Copy.java"));
String line;
while ((line=br.readLine())!=null) {
bw.write(line);
bw.newLine();
bw.flush();
}
bw.close();
br.close();
}
}
5.13 IO流小结
6. 练习案例
6.1 集合到文件
-
案例需求
把文本文件中的数据读取到集合中,并遍历集合。要求:文件中每一行数据是一个集合元素
-
实现步骤
- 创建字符缓冲输入流对象
- 创建ArrayList集合对象
- 调用字符缓冲输入流对象的方法读数据
- 把读取到的字符串数据存储到集合中
- 释放资源
- 遍历集合
-
代码实现
public class ArrayListToTxtDemo {
public static void main(String[] args) throws IOException {
ArrayList<String> array = new ArrayList<String>();
array.add("hello");
array.add("world");
array.add("java");
BufferedWriter bw = new BufferedWriter(new FileWriter("myCharStream/array.txt"));
for(String s : array) {
bw.write(s);
bw.newLine();
bw.flush();
}
bw.close();
}
}
6.2 文件到集合
-
案例需求
把ArrayList集合中的字符串数据写入到文本文件。要求:每一个字符串元素作为文件中的一行数据
-
实现步骤
- 创建ArrayList集合
- 往集合中存储字符串元素
- 创建字符缓冲输出流对象
- 遍历集合,得到每一个字符串数据
- 调用字符缓冲输出流对象的方法写数据
- 释放资源
-
代码实现
public class TxtToArrayListDemo {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("myCharStream/array.txt"));
ArrayList<String> array = new ArrayList<String>();
String line;
while ((line=br.readLine())!=null) {
array.add(line);
}
br.close();
for(String s : array) {
System.out.println(s);
}
}
}
6.3 点名器
-
案例需求
我有一个文件里面存储了班级同学的姓名,每一个姓名占一行,要求通过程序实现随点名器
-
实现步骤
- 创建字符缓冲输入流对象
- 创建ArrayList集合对象
- 调用字符缓冲输入流对象的方法读数据
- 把读取到的字符串数据存储到集合中
- 释放资源
- 使用Random产生一个随机数,随机数的范围在:[0,集合的长度)
- 把第6步产生的随机数作为索引到ArrayList集合中获取值
- 把第7步得到的数据输出在控制台
-
代码实现
public class CallNameDemo {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("myCharStream/names.txt"));
ArrayList<String> array = new ArrayList<String>();
String line;
while ((line=br.readLine())!=null) {
array.add(line);
}
br.close();
Random r = new Random();
int index = r.nextInt(array.size());
String name = array.get(index);
System.out.println("幸运者是:" + name);
}
}
6.4 集合到文件改进版
-
案例需求
把ArrayList集合中的学生数据写入到文本文件。要求:每一个学生对象的数据作为文件中的一行数据
格式:学号,姓名,年龄,居住地 举例:itheima001,林青霞,30,西安
-
实现步骤
- 定义学生类
- 创建ArrayList集合
- 创建学生对象
- 把学生对象添加到集合中
- 创建字符缓冲输出流对象
- 遍历集合,得到每一个学生对象
- 把学生对象的数据拼接成指定格式的字符串
- 调用字符缓冲输出流对象的方法写数据
- 释放资源
-
代码实现
-
学生类
public class Student {
private String sid;
private String name;
private int age;
private String address;
public Student() {
}
public Student(String sid, String name, int age, String address) {
this.sid = sid;
this.name = name;
this.age = age;
this.address = address;
}
public String getSid() {
return sid;
}
public void setSid(String sid) {
this.sid = sid;
}
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 String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
-
测试类
public class ArrayListToFileDemo {
public static void main(String[] args) throws IOException {
ArrayList<Student> array = new ArrayList<Student>();
Student s1 = new Student("itheima001", "林青霞", 30, "西安");
Student s2 = new Student("itheima002", "张曼玉", 35, "武汉");
Student s3 = new Student("itheima003", "王祖贤", 33, "郑州");
array.add(s1);
array.add(s2);
array.add(s3);
BufferedWriter bw = new BufferedWriter(new FileWriter("myCharStream/students.txt"));
for (Student s : array) {
StringBuilder sb = new StringBuilder();
sb.append(s.getSid()).append(",").append(s.getName()).append(",").append(s.getAge()).append(",").append(s.getAddress());
bw.write(sb.toString());
bw.newLine();
bw.flush();
}
bw.close();
}
}
6.5 文件到集合改进版
7. IO流案例
7.1 集合到文件数据排序改进版
7.1.1 案例需求
- 键盘录入5个学生信息(姓名,语文成绩,数学成绩,英语成绩)。要求按照成绩总分从高到低写入文本文件
- 格式:姓名,语文成绩,数学成绩,英语成绩 举例:林青霞,98,99,100
7.1.2 分析步骤
- 定义学生类
- 创建TreeSet集合,通过比较器排序进行排序
- 键盘录入学生数据
- 创建学生对象,把键盘录入的数据对应赋值给学生对象的成员变量
- 把学生对象添加到TreeSet集合
- 创建字符缓冲输出流对象
- 遍历集合,得到每一个学生对象
- 把学生对象的数据拼接成指定格式的字符串
- 调用字符缓冲输出流对象的方法写数据
- 释放资源
7.1.3 代码实现
-
学生类
public class Student {
private String name;
private int chinese;
private int math;
private int english;
public Student() {
super();
}
public Student(String name, int chinese, int math, int english) {
super();
this.name = name;
this.chinese = chinese;
this.math = math;
this.english = english;
}
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 getEnglish() {
return english;
}
public void setEnglish(int english) {
this.english = english;
}
public int getSum() {
return this.chinese + this.math + this.english;
}
}
-
测试类
public class TreeSetToFileDemo {
public static void main(String[] args) throws IOException {
TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
int num = s2.getSum() - s1.getSum();
int num2 = num == 0 ? s1.getChinese() - s2.getChinese() : num;
int num3 = num2 == 0 ? s1.getMath() - s2.getMath() : num2;
int num4 = num3 == 0 ? s1.getName().compareTo(s2.getName()) : num3;
return num4;
}
});
for (int i = 0; i < 5; i++) {
Scanner sc = new Scanner(System.in);
System.out.println("请录入第" + (i + 1) + "个学生信息:");
System.out.println("姓名:");
String name = sc.nextLine();
System.out.println("语文成绩:");
int chinese = sc.nextInt();
System.out.println("数学成绩:");
int math = sc.nextInt();
System.out.println("英语成绩:");
int english = sc.nextInt();
Student s = new Student();
s.setName(name);
s.setChinese(chinese);
s.setMath(math);
s.setEnglish(english);
ts.add(s);
}
BufferedWriter bw = new BufferedWriter(new FileWriter("myCharStream/ts.txt"));
for (Student s : ts) {
StringBuilder sb = new StringBuilder();
sb.append(s.getName()).append(",").append(s.getChinese()).append(",").append(s.getMath()).append(",").append(s.getEnglish()).append(",").append(s.getSum());
bw.write(sb.toString());
bw.newLine();
bw.flush();
}
bw.close();
}
}
7.2 复制单级文件夹
7.2.1 案例需求
- 把“/Volumes/DATA1/000-develop/itcast”这个文件夹复制到模块目录下
7.2.2 分析步骤
-
创建数据源目录File对象,路径是/Volumes/DATA1/000-develop/itcast
-
获取数据源目录File对象的名称
-
创建目的地目录File对象,路径由(模块名+第2步获取的名称)组成
-
判断第3步创建的File是否存在,如果不存在,就创建
-
获取数据源目录下所有文件的File数组
-
遍历File数组,得到每一个File对象,该File对象,其实就是数据源文件
-
获取数据源文件File对象的名称
-
创建目的地文件File对象,路径由(目的地目录+第7步获取的名称)组成
-
复制文件
由于不清楚数据源目录下的文件都是什么类型的,所以采用字节流复制文件
采用参数为File的构造方法
7.2.3 代码实现
public class CopyFolderDemo {
public static void main(String[] args) throws IOException {
File srcFolder = new File("/Volumes/DATA1/000-develop/itcast");
String srcFolderName = srcFolder.getName();
File destFolder = new File("myCharStream",srcFolderName);
if(!destFolder.exists()) {
destFolder.mkdir();
}
File[] listFiles = srcFolder.listFiles();
for(File srcFile : listFiles) {
String srcFileName = srcFile.getName();
File destFile = new File(destFolder,srcFileName);
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;
while ((len=bis.read(bys))!=-1) {
bos.write(bys,0,len);
}
bos.close();
bis.close();
}
}
7.3 复制多级文件夹
7.3.1 案例需求
- 把“/Volumes/DATA1/000-develop/itcast”这个文件夹复制到 F盘目录下
7.3.2 分析步骤
-
创建数据源File对象,路径是/Volumes/DATA1/000-develop/itcast
-
创建目的地File对象,路径是/Volumes/DATA1
-
写方法实现文件夹的复制,参数为数据源File对象和目的地File对象
-
判断数据源File是否是文件
是文件:直接复制,用字节流
不是文件:
在目的地下创建该目录
遍历获取该目录下的所有文件的File数组,得到每一个File对象
回到3继续(递归)
7.3.3 代码实现
public class CopyFoldersDemo {
public static void main(String[] args) throws IOException {
File srcFile = new File("/Volumes/DATA1/000-develop/itcast");
File destFile = new File("/Volumes/DATA1");
copyFolder(srcFile,destFile);
}
private static void copyFolder(File srcFile, File destFile) throws IOException {
if(srcFile.isDirectory()) {
String srcFileName = srcFile.getName();
File newFolder = new File(destFile,srcFileName);
if(!newFolder.exists()) {
newFolder.mkdir();
}
File[] fileArray = srcFile.listFiles();
for(File file : fileArray) {
copyFolder(file,newFolder);
}
} else {
File newFile = new File(destFile,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;
while ((len = bis.read(bys)) != -1) {
bos.write(bys, 0, len);
}
bos.close();
bis.close();
}
}
7.4 复制文件的异常处理
7.4.1 基本做法
public class CopyFileDemo {
public static void main(String[] args) {
}
private static void method2() {
FileReader fr = null;
FileWriter fw = null;
try {
fr = new FileReader("fr.txt");
fw = new FileWriter("fw.txt");
char[] chs = new char[1024];
int len;
while ((len = fr.read()) != -1) {
fw.write(chs, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if(fw!=null) {
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(fr!=null) {
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private static void method1() throws IOException {
FileReader fr = new FileReader("fr.txt");
FileWriter fw = new FileWriter("fw.txt");
char[] chs = new char[1024];
int len;
while ((len = fr.read()) != -1) {
fw.write(chs, 0, len);
}
fw.close();
fr.close();
}
}
7.4.2 JDK7版本改进
public class CopyFileDemo {
public static void main(String[] args) {
}
private static void method3() {
try(FileReader fr = new FileReader("fr.txt");
FileWriter fw = new FileWriter("fw.txt");){
char[] chs = new char[1024];
int len;
while ((len = fr.read()) != -1) {
fw.write(chs, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
7.4.3 JDK9版本改进
public class CopyFileDemo {
public static void main(String[] args) {
}
private static void method4() throws IOException {
FileReader fr = new FileReader("fr.txt");
FileWriter fw = new FileWriter("fw.txt");
try(fr;fw){
char[] chs = new char[1024];
int len;
while ((len = fr.read()) != -1) {
fw.write(chs, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
8. IO特殊操作流
8.1 标准输入流
8.2 标准输出流
8.3 字节打印流
8.4 字符打印流
8.5 复制Java文件打印流改进版
-
案例需求
- 把模块目录下的PrintStreamDemo.java 复制到模块目录下的 Copy.java
-
分析步骤
- 根据数据源创建字符输入流对象
- 根据目的地创建字符输出流对象
- 读写数据,复制文件
- 释放资源
-
代码实现
public class CopyJavaDemo {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("myOtherStream/PrintStreamDemo.java"));
PrintWriter pw = new PrintWriter(new FileWriter("myOtherStream/Copy.java"),true);
String line;
while ((line=br.readLine())!=null) {
pw.println(line);
}
pw.close();
br.close();
}
}
8.6 对象序列化流
8.7 对象反序列化流
-
对象反序列化流: ObjectInputStream
- ObjectInputStream反序列化先前使用ObjectOutputStream编写的原始数据和对象
-
构造方法
方法名 | 说明 |
---|
ObjectInputStream(InputStream in) | 创建从指定的InputStream读取的ObjectInputStream |
-
反序列化对象的方法
方法名 | 说明 |
---|
Object readObject() | 从ObjectInputStream读取一个对象 |
-
示例代码
public class ObjectInputStreamDemo {
public static void main(String[] args) throws IOException, ClassNotFoundException {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("myOtherStream/oos.txt"));
Object obj = ois.readObject();
Student s = (Student) obj;
System.out.println(s.getName() + "," + s.getAge());
ois.close();
}
}
8.8 serialVersionUID&transient
-
serialVersionUID
- 用对象序列化流序列化了一个对象后,假如我们修改了对象所属的类文件,读取数据会不会出问题呢?
- 会出问题,会抛出InvalidClassException异常
- 如果出问题了,如何解决呢?
- 重新序列化
- 给对象所属的类加一个serialVersionUID
- private static final long serialVersionUID = 42L;
-
transient
- 如果一个对象中的某个成员变量的值不想被序列化,又该如何实现呢?
- 给该成员变量加transient关键字修饰,该关键字标记的成员变量不参与序列化过程
-
示例代码
-
学生类
public class Student implements Serializable {
private static final long serialVersionUID = 42L;
private String name;
private transient int age;
public Student() {
}
public Student(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 ObjectStreamDemo {
public static void main(String[] args) throws IOException, ClassNotFoundException {
read();
}
private static void read() throws IOException, ClassNotFoundException {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("myOtherStream/oos.txt"));
Object obj = ois.readObject();
Student s = (Student) obj;
System.out.println(s.getName() + "," + s.getAge());
ois.close();
}
private static void write() throws IOException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("myOtherStream/oos.txt"));
Student s = new Student("林青霞", 30);
oos.writeObject(s);
oos.close();
}
}
9. Properties集合
9.1 Properties作为Map集合的使用
-
Properties介绍
- 是一个Map体系的集合类
- Properties可以保存到流中或从流中加载
- 属性列表中的每个键及其对应的值都是一个字符串
-
Properties基本使用
public class PropertiesDemo01 {
public static void main(String[] args) {
Properties prop = new Properties();
prop.put("itheima001", "林青霞");
prop.put("itheima002", "张曼玉");
prop.put("itheima003", "王祖贤");
Set<Object> keySet = prop.keySet();
for (Object key : keySet) {
Object value = prop.get(key);
System.out.println(key + "," + value);
}
}
}
9.2 Properties作为Map集合的特有方法
-
特有方法
方法名 | 说明 |
---|
Object setProperty(String key, String value) | 设置集合的键和值,都是String类型,底层调用 Hashtable方法 put |
String getProperty(String key) | 使用此属性列表中指定的键搜索属性 |
Set stringPropertyNames() | 从该属性列表中返回一个不可修改的键集,其中键及其对应的值是字符串 |
-
示例代码
public class PropertiesDemo02 {
public static void main(String[] args) {
Properties prop = new Properties();
prop.setProperty("itheima001", "林青霞");
prop.setProperty("itheima002", "张曼玉");
prop.setProperty("itheima003", "王祖贤");
Set<String> names = prop.stringPropertyNames();
for (String key : names) {
String value = prop.getProperty(key);
System.out.println(key + "," + value);
}
}
}
9.3 Properties和IO流相结合的方法
-
和IO流结合的方法
方法名 | 说明 |
---|
void load(InputStream inStream) | 从输入字节流读取属性列表(键和元素对) |
void load(Reader reader) | 从输入字符流读取属性列表(键和元素对) |
void store(OutputStream out, String comments) | 将此属性列表(键和元素对)写入此 Properties表中,以适合于使用 load(InputStream)方法的格式写入输出字节流 |
void store(Writer writer, String comments) | 将此属性列表(键和元素对)写入此 Properties表中,以适合使用 load(Reader)方法的格式写入输出字符流 |
-
示例代码
public class PropertiesDemo03 {
public static void main(String[] args) throws IOException {
myLoad();
}
private static void myLoad() throws IOException {
Properties prop = new Properties();
FileReader fr = new FileReader("myOtherStream/fw.txt");
prop.load(fr);
fr.close();
System.out.println(prop);
}
private static void myStore() throws IOException {
Properties prop = new Properties();
prop.setProperty("itheima001","林青霞");
prop.setProperty("itheima002","张曼玉");
prop.setProperty("itheima003","王祖贤");
FileWriter fw = new FileWriter("myOtherStream/fw.txt");
prop.store(fw,null);
fw.close();
}
}
9.4 游戏次数案例
-
案例需求
- 实现猜数字小游戏只能试玩3次,如果还想玩,提示:游戏试玩已结束,想玩请充值(www.itcast.cn)
-
分析步骤
-
写一个游戏类,里面有一个猜数字的小游戏
-
写一个测试类,测试类中有main()方法,main()方法中写如下代码:
从文件中读取数据到Properties集合,用load()方法实现
文件已经存在:game.txt 里面有一个数据值:count=0
通过Properties集合获取到玩游戏的次数
判断次数是否到到3次了
如果到了,给出提示:游戏试玩已结束,想玩请充值(www.itcast.cn) 如果不到3次: 次数+1,重新写回文件,用Properties的store()方法实现玩游戏
-
代码实现
public class PropertiesTest {
public static void main(String[] args) throws IOException {
Properties prop = new Properties();
FileReader fr = new FileReader("myOtherStream/game.txt");
prop.load(fr);
fr.close();
String count = prop.getProperty("count");
int number = Integer.parseInt(count);
if(number >= 3) {
System.out.println("游戏试玩已结束,想玩请充值(www.itcast.cn)");
} else {
GuessNumber.start();
number++;
prop.setProperty("count",String.valueOf(number));
FileWriter fw = new FileWriter("myOtherStream/game.txt");
prop.store(fw,null);
fw.close();
}
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)