day10作业答卷
day10作业答卷
一、选择题:
1.下面哪个流类属于面向字符的输入流()
A.BufferedWriter
B.FilelnputStream
C. ObjectInputStream
D. InputStreamReader
答案
D 转换流
⒉.要从文件”file.txt”文件中读出第10个字节到变量c中,下列哪个正确( )
A.
FileInputStream in=new FileInputStream("file.txt");
in.skip(9); // skip() 跳过前几个字节数据
int c=in.read();
B.
FileInputStream in=new FileInputStream("file.txt");
in.skip(10);// skip() 跳过前几个字节数据
int c=in.read();
C.
FileInputStream in=new FileInputStream("file.txt");
int c=in.read();
D.
FileInputStream in=new FileInputStream("file.txt");
in.skip(7);// skip() 跳过前几个字节数据
int c=in.readByte();
答案
A skip跳过
3. 实现下列哪个接口,可以启用序列化功能( )
A. Runnable接口
B. Comparable接口
C. Serializable接口
D. Comparator接口
答案
C Serializable接口是一个标记接口
4. 下面的程序段创建了BufferedReader类的对象in,以便读取本机d盘my文件夹下的文件1.txt。File构造函数中正确的路径和文件名的表示是( )
File f=new File(填代码处);
file=new FileReader(f);
in=new BufferedReader(file);
A. "1.txt"
B. "d:\\my\\1"
C. "d:\\my\\1.txt"
D. "d:\ my\1.txt"
答案
C 双斜杠转义
5. 【多选题】下面关于IO流的说法正确的是( )
- A. IO流可以分为字节流和字符流
- B. FileReader和FileWriter是专门用于读取和写入文本文件的
- C. 字节流类有InputStream和OutputStream
- D. 顶层类有Reader和Writer,他们都是接口
答案
D Reader和Writer是抽象类
6.【多选题】关于打印流PrintWriter说法正确的是( )
- A. 该流只操作数据目的,不操作数据源
- B. 该流只操作数据源,不操作数据目的
- C. 如果启用了自动刷新,该流调用println()方法时可以自动刷新
- D. 该流是Writer的子类
答案
ACD PrintWriter是一个包装流,只能打印
7. 关于对象的序列化说法错误的是( )
- A. 实现序列化的对象必须实现Serializable接口
- B. 实现序列化的对象必须自定义序列号
- C. ObjectOutputStream中的writeObject()方法可以将对象写出
- D. ObjectInputStream中的readObject()方法可以读取对象
答案
B 会自动指定自定义序列号
8. 【多选题】下面关于java中输入/输出流的说法正确的是( )
- A.FileInputStream与FileOutputStream类用来读、写字节流。
- B. FileReader与FileWriter类用来读、写字符流。
- C. File类既可以用来读文件,也可以用来写文件。
- D. File类用来处理与文件相关的操作。
答案
ABD File不能读取文件,那是流的事情
9. 与InputStream流相对应的Java系统的标准输入对象是()
- A.System.in
- B.System.out
- C.System.err
- D.System.exit()
答案
A B-System.out是输出 D-是退出
10. 以下对于缓冲流描述错误的是()
- A. 缓冲流可以直接读写文件,所以完全不用普通流
- B. 缓冲流是一种装饰模式,它本身不具备读写功能,读写依旧要依赖于普通流
- C. 如果都准备数组读写数据的情况下,缓冲流效率同普通流相差无几
- D. 缓冲流内置一个8192的数组,用来提高读写效率
答案
A 缓冲流只是一个包装流
二、今日方法:
1. 字符流中所涉及到的类名以及方法名称:
提示:参考笔记
2. 字符缓冲流中的特殊方法名称以及作用:
答:readLine-读一行 newLine换一行
3. 转换流的类名:
提示:参考笔记 OutputStream或者InputStream开头
4. 打印流的类名以及方法名称:
提示:参考笔记 Print开头
5. 数据流的类名以及方法名称:
提示:参考笔记 Data开头
6. 序列化流的类名以及方法名称:
提示:参考笔记 Object开头
三、简答题:
1. 字符流有什么作用?能不能操作图片文件?会有什么问题?
提示:拷贝字符,特有的api,不能操作图片(需要无码操作)
2. 什么是缓冲流?缓冲流能否直接读写文件?有什么好处?
提示:提速,包装流,缓冲字节数据
3. 转换流是字节流还是字符流?有什么作用?
字节+码表=字符
4. 打印流有什么作用?
提示:不光存下,而且输出控制台
5. flush()和close()方法的区别?
提示:可以续写,关流不能续写
6. 什么是序列化和反序列化?需要注意什么?
答:标记接口、概念图
四、排错题:
排错题1:
// 以下代码是否能正常运行?为什么?
public class Demo3 {
public static void main(String[] args) {
try {
Reader fr = new FileReader("io-app2\\src\\itheima04.txt");
// 创建一个字符缓冲输入流包装原始的字符输入流
BufferedReader br = new BufferedReader(fr);
String line; // 记住每次读取的一行数据
while ((line = br.readLine()) != -1) {
System.out.println(line);
}
br.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
答案提示
readLine()!=null
排错题2:
// 以下代码运行后,文件a.txt中是否会有数据?为什么?
public class Demo3 {
public static void main(String[] args) throws FileNotFoundException {
PrintWriter ps = new PrintWriter(new FileOutputStream("day06-code/a.txt"));
ps.println("123");
ps.print(666);
ps.write(123);
}
}
答案提示
没有数据,没有close()或者flush
排错题3:
// 以下代码运行后,country变量是否会有数据呢?
public class User implements Serializable {
private String Name;
private int age;
// transient 这个成员变量将不参与序列化。
private transient String passWord;
// static 修饰的成员变量也无法被序列化
private static String country;
// 以下set/get/构造方法省略...
}
public class Demo4 {
public static void main(String[] args) throws IOException {
// 1、创建一个Java对象。
User.country = "中国";
User u = new User("张三", 32, "666888xyz");
// 2、创建一个对象字节输出流包装原始的字节 输出流。
ObjectOutputStream oos =
new ObjectOutputStream(new FileOutputStream("io-app2/src/itheima11out.txt"));
// 3、序列化对象到文件中去
oos.writeObject(u);
oos.close();
// 下面反序列化
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("io-app2/src/itheima11out.txt"));
User u = (User) ois.readObject();
// 请问打印出来的User对象中,是否有country的值???
System.out.println(u);
ois.close();
}
}
答案提示
没有country的值
Java序列化是不能序列化static变量的,因为其保存的是对象的状态,而static变量保存在全局数据区,在对象未实例化时就已经生成,属于类的状态。
五、代码题:
第一题:分析以下需求,并用代码实现
训练目标:
掌握java中字符流的基本使用,以及理解其在实际开发中的应用
需求描述:
编写一个程序,把一个目录里边的所有带.java文件拷贝到另一个目录中,拷贝成功后,把后缀名是.java的文件改为.txt文件。 (注意事项:是先拷贝,拷贝成功后才可以改后缀名的)
实现提示:
- 用File对象封装目录
- 通过listFiles()方法获取该目录下所有的文件或者文件夹的File对象数组
- 遍历这个File数组,得到每一个File对象
- 判断该File对象是否是文件
- 如果是文件
- 继续判断是否以.java结尾
- 是:复制文件,再复制完成后改名
- 否:不复制
点击查看代码
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
public class CopyJavaFiles {
public static void main(String[] args) {
File sourceDir = new File("D:\\\subject_java\\79\\code\\javase\\io-app2\\src\\com\\itheima");
File targetDir = new File("D:\\subject_java\\79\\code\\javase\\io-app2\\src\\com\\itheima2");
try {
copyJavaFiles(sourceDir, targetDir);
} catch (IOException e) {
e.printStackTrace();
}
}
private static void copyJavaFiles(File sourceDir, File targetDir) throws IOException {
if (!targetDir.exists()) {
targetDir.mkdirs();
}
if (!sourceDir.isDirectory() || !targetDir.isDirectory()) {
throw new IllegalArgumentException("Both source and target directories must exist.");
}
for (File file : sourceDir.listFiles()) {
if (file.isDirectory()) {
File newDir = new File(targetDir, file.getName());
newDir.mkdir();
copyJavaFiles(file, newDir);
} else if (file.getName().endsWith(".java")) {
Path source = file.toPath();
Path target = new File(targetDir, file.getName().replace(".java", ".txt")).toPath();
Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);
}
}
}
}
第二题: 分析以下需求,并用代码实现
训练目标:
掌握java中字符流的基本使用
需求描述:
实现一个验证程序运行次数的小程序,要求如下:
- 当程序运行超过3次时给出提示:本软件只能免费使用3次,欢迎您注册会员后继续使用
- 程序运行演示如下:
- 第一次运行控制台输出: 欢迎使用本软件,第1次使用免费~
- 第二次运行控制台输出: 欢迎使用本软件,第2次使用免费~
- 第三次运行控制台输出: 欢迎使用本软件,第3次使用免费~
- 第四次及之后运行控制台输出:本软件只能免费使用3次,欢迎您注册会员后继续使用~
实现提示:
1. 程序运行3次,每次运行结果不同,所以控制台打印的数字,应该在写文件中
2. 每次程序运行,读取文件中的数据,打印在控制台
3. 再将数据+1后重新写回文件
4. 每次读文件中的数据,需要判断数据是否超过3,超过3,则打印不同的结果
点击查看代码
public class RunCountValidator {
private static final String RUN_COUNT_PROPERTY_KEY = "run_count";
private static final int MAX_FREE_RUNS = 3;
public static void main(String[] args) {
Properties properties = new Properties();
String propertiesFilePath = "run_count.properties";
File propertiesFile = new File(propertiesFilePath);
int runCount = 0;
if (propertiesFile.exists()) {
try (FileInputStream fis = new FileInputStream(propertiesFile)) {
properties.load(fis);
String runCountString = properties.getProperty(RUN_COUNT_PROPERTY_KEY);
runCount = Integer.parseInt(runCountString);
} catch (IOException e) {
e.printStackTrace();
}
}
if (runCount < MAX_FREE_RUNS) {
runCount++;
System.out.println("欢迎使用本软件,第" + runCount + "次使用免费~");
try (FileOutputStream fos = new FileOutputStream(propertiesFile)) {
properties.setProperty(RUN_COUNT_PROPERTY_KEY, Integer.toString(runCount));
properties.store(fos, null);
} catch (IOException e) {
e.printStackTrace();
}
} else {
System.out.println("本软件只能免费使用3次,欢迎您注册会员后继续使用~");
}
}
}
第三题:【选做题】分析以下需求,并用代码实现
训练目标:
掌握java中字符流的基本使用
需求描述:
// 项目根路径下有个questions.txt文件内容如下:
5+5
150-25
155*155
2555/5
// 要求:读取内容计算出结果,将结果写入到results.txt文件中
5+5=10
...
思考:如果说读取questions.txt文件的内容,算出计算结果,再写入questions.txt文件,即读和写的操作时针对同一个文件,应该如何操作
实现提示:
- 应该从文件中,把数据一行一行读出来
- 拿到数据后,判断哪个不是数字,则使用不是数字的字符,切割字符串
- 再把切割后的字符串,转成数字
- 再匹配切割的字符的类型,进行相应的操作
点击查看代码
public class MathCalculator {
public static void main(String[] args) {
// questions.txt 文件路径
String questionsFilePath = "D:\\subject_java\\79\\code\\javase\\io-app2\\src\\questions.txt";
// results.txt 文件路径
String resultsFilePath = "D:\\subject_java\\79\\code\\javase\\io-app2\\src\\results.txt";
// 用于存储所有问题的列表
List<String> questions = new ArrayList<>();
// 读取 questions.txt 文件
try (BufferedReader br = new BufferedReader(new FileReader(questionsFilePath))) {
String line;
while ((line = br.readLine()) != null) {
// 将每一行问题添加到列表中
questions.add(line);
}
} catch (IOException e) {
e.printStackTrace();
}
// 用于存储所有计算结果的列表
List<String> results = new ArrayList<>();
// 对每个问题进行解析和计算
for (String question : questions) {
// 使用正则表达式将问题拆分为两个操作数和一个运算符
String[] operands = question.split("[+\\-*/]");
String operator = question.replaceAll("[^+\\-*/]", "");
// 获得符号前后的数字
int operand1 = Integer.parseInt(operands[0].trim());
int operand2 = Integer.parseInt(operands[1].trim());
// 定义结果
int result = 0;
// 判断是什么符号
switch (operator) {
case "+":
result = operand1 + operand2;
break;
case "-":
result = operand1 - operand2;
break;
case "*":
result = operand1 * operand2;
break;
case "/":
result = operand1 / operand2;
break;
default:
System.out.println("无法识别的运算符:" + operator);
break;
}
results.add(Integer.toString(result));
}
// 将集合中的结果存到输出流
try (BufferedWriter bw = new BufferedWriter(new FileWriter(resultsFilePath))) {
for (String result : results) {
bw.write(result);
bw.newLine();
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("结果已写入到文件 " + resultsFilePath + " 中。");
}
}