day10作业答卷

YangeIT大约 10 分钟

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 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文件。 (注意事项:是先拷贝,拷贝成功后才可以改后缀名的)

实现提示

  1. 用File对象封装目录
  2. 通过listFiles()方法获取该目录下所有的文件或者文件夹的File对象数组
  3. 遍历这个File数组,得到每一个File对象
  4. 判断该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中字符流的基本使用

需求描述

实现一个验证程序运行次数的小程序,要求如下:

  1. 当程序运行超过3次时给出提示:本软件只能免费使用3次,欢迎您注册会员后继续使用
  2. 程序运行演示如下:
  • 第一次运行控制台输出: 欢迎使用本软件,第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文件,即读和写的操作时针对同一个文件,应该如何操作

实现提示

  1. 应该从文件中,把数据一行一行读出来
  2. 拿到数据后,判断哪个不是数字,则使用不是数字的字符,切割字符串
  3. 再把切割后的字符串,转成数字
  4. 再匹配切割的字符的类型,进行相应的操作
点击查看代码

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 + " 中。");
    }
}