【从零开始重学Java】第11天

发布时间 2024-01-10 16:33:05作者: 迷路的哨兵甲

前情提示

从零开始重学Java 第0天
从零开始重学Java 第1天
从零开始重学Java 第2天
从零开始重学Java 第3天
从零开始重学Java 第4天
从零开始重学Java 第5天
从零开始重学Java 第6天
从零开始重学Java 第7天
从零开始重学Java 第8_9_10天

Java数据流

关于文件的操作建议使用新的API Java NIO.2
JDK9以后 输入输出流的抽象类新增了一些方便的方法,NIO.2的工具类也新增很多方便的方法
可以说常见的流写入读取操作都有了自带封装

数据流的基本概念

输入数据流

输出数据流

基本字节数据流类

早期的write和read只能读写ASCII 字符集中的一部分字符
字节流更适用于二进制文件的读写,字符流适用于处理文本类文件的读写

文件数据流

过滤流

管道数据流

好像实际开发里完全没用过......
看源码是PipedOutputStream引用了connect链接的PipedInputStream,然后共同使用PipedInputStream的buffer内容

对象流

和Serializable序列化相关的一种流

可持久化

序列化有一个很大的问题,当类发生修改时,已经序列化的文件,不一定还能正常反序列化回去
通过手动指定死serialVersionUID可以反序列化,但可能因为类结构不兼容而抛出异常
所以现在大家更习惯使用JSON或者数据库来保存自己的对象数据

基本字符流

读者和写者

缓冲区读者和缓冲区写者

文件的处理

文件的读写建议用NIO.2的API,简单易懂

read
write
newStream
copy
delete
move
create
exists
is

File类

建议用Paths来替代,可以省去File.separator拼接

Paths

随机访问文件

可以用于做断点续传,记录文件指针指向的位置

第十一章习题

  • 设计一个通讯录,保存联系人信息,持久化到文件
public class ContactsTxtDemo {

    private static final Path txtPath = Paths.get("contacts.txt");

    public static void main(String[] args) {
        checkTxtFile();
        LinkedHashSet<String> allLinesSet = readTxtFile();
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNextLine()){
            String line = scanner.nextLine();
            if ("stop".equals(line)){
                break;
            }
            if (allLinesSet.contains(line)){
                System.out.println("已存在 " + line);
            }else {
                allLinesSet.add(line);
                System.out.println("已添加 " + line);
            }
        }
        writeTxtFile(allLinesSet);

    }

    private static void checkTxtFile() {
        if (Files.notExists(txtPath)){
            try {
                Files.createFile(txtPath);
            }catch (Exception e){
                throw new RuntimeException("创建文件失败",e);
            }
        }
    }
    private static LinkedHashSet<String> readTxtFile(){
        LinkedHashSet<String> linkedHashSet;
        try {
            linkedHashSet = Files.readAllLines(txtPath).stream()
                    .filter(e -> !e.isBlank())
                    .collect(Collectors.toCollection(LinkedHashSet::new));
        }catch (Exception e){
            throw new RuntimeException("读取文件失败",e);
        }
        System.out.println("读取了" + linkedHashSet.size()+"条记录");
        linkedHashSet.forEach(System.out::println);
        return linkedHashSet;
    }
    private static void writeTxtFile(LinkedHashSet<String> allLinesSet){
        System.out.println("即将写入" + allLinesSet.size()+"条记录");
        allLinesSet.forEach(System.out::println);
        try {
            Files.write(txtPath,allLinesSet);
        }catch (Exception e){
            throw new RuntimeException("写入文件失败",e);
        }
    }
}

// 读取了3条记录
// 小明 88
// 小兰 99
// 小张 99
// xiaoming 88
// 已添加 xiaoming 88
// 小明 88
// 已存在 小明 88
// 小兰 99
// 已存在 小兰 99
// xiaoming 88
// 已存在 xiaoming 88
// stop
// 即将写入4条记录
// 小明 88
// 小兰 99
// 小张 99
// xiaoming 88