Java-IO

简介: Java-IO

Java-IO

IO:I,Input(in)。O,Output(out)。Stream,流转。

数据流处理

数据流:数据+流(转)+处理

图解数据流:

image-20230112184059488

关于Stream:

image-20230112184147790

在IO中,IN和OUT是有阀门的,打开时才进行传输:

image-20230112184256528

文件流

image-20230112220958009

File file = new File("D:\\Do_it\\java\\new\\demo1\\data\\test.txt");
System.out.println(file);// D:\Do_it\java\new\demo1\data\test.txt
AI 代码解读

判断是否为文件,注意这里是File对象是关联的文件或者文件夹

File file = new File("D:\\Do_it\\java\\new\\demo1\\data\\test.txt");
File file1 = new File("D:\\Do_it\\java\\new\\demo1\\data");

System.out.println(file.isFile());// true
System.out.println(file1.isFile());// false
AI 代码解读

判断是否为文件夹

File file = new File("D:\\Do_it\\java\\new\\demo1\\data\\test.txt");
File file1 = new File("D:\\Do_it\\java\\new\\demo1\\data");

System.out.println(file.isDirectory());// false
System.out.println(file1.isDirectory());// true
AI 代码解读

判断File对象是否存在关联(是否有这个路径)

File file = new File("D:\\Do_it\\java\\new\\demo1\\data\\test.txt");
File file1 = new File("D:\\Do_it\\java\\new\\demo1\\node");

System.out.println(file.exists());// true
System.out.println(file1.exists());// false
AI 代码解读

文件流的常用方法:

import java.io.File;
import java.io.IOException;

public class Demo_01 {
    public static void main(String[] args) throws IOException {
        File file = new File("D:\\Do_it\\java\\new\\demo1\\data\\test.txt");

        getFileAbout(file);
//        文件对象存在关联
//        文件名为:test.txt
//        文件绝对路径为:D:\Do_it\java\new\demo1\data\test.txt
//        文件长度为:5
//        文件最后修改时间为:1673529597503
    }

    public static void getFileAbout(File file, String... fileOrDir) throws IOException {
        if (file.exists()) {
            System.out.println("文件对象存在关联");
            if (file.isFile()) {
                System.out.println("文件名为:" + file.getName());
                System.out.println("文件绝对路径为:" + file.getAbsolutePath());
                System.out.println("文件长度为:" + file.length());
                System.out.println("文件最后修改时间为:" + file.lastModified());
                return;
            }
            if (file.isDirectory()) {
                System.out.println("文件夹名为:" + file.getName());
                System.out.println("文件夹绝对路径为:" + file.getAbsolutePath());
                System.out.println("文件夹最后修改时间为:" + file.lastModified());

                String[] list = file.list();
                System.out.println("文件夹下目录为:" + list);
                for (String s : list) {
                    System.out.println(s);
                }
                return;
            }
        }

        System.out.println("文件/文件夹路径不存在,开始创建");
        file.mkdirs();// 创建文件夹
        file.createNewFile();// 创建文件
    }
}
AI 代码解读

复制文件:

import java.io.*;

public class Demo_02 {
    public static void main(String[] args) {
        // TODO 原文件
        File srcFile = new File("D:\\Do_it\\java\\new\\demo1\\data\\test.txt");
        // TODO 复制的文件(自动创建)
        File destFile = new File("D:\\Do_it\\java\\new\\demo1\\data\\test.txt.copy");

        // TODO 文件输入流(管道对象)
        FileInputStream in = null;
        // TODO 文件输出流(管道对象)
        FileOutputStream out = null;

        try {
            in = new FileInputStream(srcFile);
            out = new FileOutputStream(destFile);
            
            int data;
            // TODO 打卡阀门,流转数据(输入)。(打开一次关闭一次,所以用循环。当没有数据后读取-1)
            while ((data = in.read()) != -1) {
                // TODO 打卡阀门,流转数据(输出)
                out.write(data);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}
AI 代码解读

缓冲流

建立一个缓冲区,使其输入输出的阀门都只开一次。

image-20230112225352373

读取的时候读取缓冲区的数据,写的时候也是。

import java.io.*;

public class Demo_03 {
    public static void main(String[] args) {
        // TODO 原文件
        File srcFile = new File("D:\\Do_it\\java\\new\\demo1\\data\\test.txt");
        // TODO 复制的文件(自动创建)
        File destFile = new File("D:\\Do_it\\java\\new\\demo1\\data\\test.txt.copy");

        // TODO 文件输入流(管道对象)
        FileInputStream in = null;
        // TODO 文件输出流(管道对象)
        FileOutputStream out = null;

        // TODO 缓冲输入流(管道对象)
        BufferedInputStream bufferIn = null;
        // TODO 缓冲输出流(管道对象)
        BufferedOutputStream bufferOut = null;
        // TODO 缓冲区
        byte[] cache = new byte[1024];


        try {
            in = new FileInputStream(srcFile);
            out = new FileOutputStream(destFile);

            bufferIn = new BufferedInputStream(in);
            bufferOut = new BufferedOutputStream(out);

            int data;
            // TODO 打卡阀门,流转数据(输入)。(打开一次关闭一次,所以用循环。当没有数据后读取-1)
            while ((data = bufferIn.read(cache)) != -1) {
                // TODO 打卡阀门,流转数据(输出)
                bufferOut.write(cache, 0, data);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            if (bufferIn != null) {
                try {
                    bufferIn.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            if (bufferOut != null) {
                try {
                    bufferOut.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}
AI 代码解读

字符流

之前都是流转字节(byte),非常不方便。我们将流转的数据转为字符:

字符流中,一行一行的进行流转。

import java.io.*;

public class Demo_04 {
    public static void main(String[] args) {
        // TODO 原文件
        File srcFile = new File("D:\\Do_it\\java\\new\\demo1\\data\\test.txt");
        // TODO 复制的文件(自动创建)
        File destFile = new File("D:\\Do_it\\java\\new\\demo1\\data\\test.txt.copy");

        // TODO 文件输入流(管道对象)
        FileInputStream in = null;
        // TODO 文件输出流(管道对象)
        FileOutputStream out = null;

        // TODO 字符输入流(管道对象)
        BufferedReader reader = null;
        // TODO 字符输出流(管道对象)
        PrintWriter writer = null;

        try {
            reader = new BufferedReader(new FileReader(srcFile));
            writer = new PrintWriter(destFile);

            String line = null;

            // TODO 打卡阀门,流转数据(输入)。(打开一次关闭一次,所以用循环。当没有字符串返回null)
            while ((line = reader.readLine()) != null) {
                // TODO 打卡阀门,流转数据(输出)
                writer.println(line);
                System.out.println(line);
            }
            // hello
            // nice demo!
            writer.flush();

        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            if (writer != null) {
                writer.close();
            }
        }
    }
}
AI 代码解读

序列化与反序列化

我们之前将字符串进行流转,那么对象是否也可以呢?我们如何将程序中的对象写入文件呢?

image-20230112233234676image-20230112233324210

在java中,我们将对象变成字节写入文件,这个过程叫序列化过程。而将文件中的数据读成对象叫反序列化

序列化

需要对象的类实现Serializable接口(可序列化的)

package chapter08;

import java.io.*;

public class Demo_05 {
    public static void main(String[] args) {
        // TODO 数据文件对象
        File dateFile = new File("D:\\Do_it\\java\\new\\demo1\\data\\obj.dat");

        // TODO 对象输出流(管道对象)
        ObjectOutputStream objectOutput = null;
        FileOutputStream out = null;


        try {
            out = new FileOutputStream(dateFile);
            objectOutput = new ObjectOutputStream(out);
            User user = new User();
            
            objectOutput.writeObject(user);

            objectOutput.flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            if (objectOutput != null) {
                try {
                    objectOutput.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}

class User implements Serializable {
}
AI 代码解读

这时候已经将对象写入了文件。

反序列化

import java.io.*;

public class Demo_05 {
    public static void main(String[] args) {
        // TODO 数据文件对象
        File dateFile = new File("D:\\Do_it\\java\\new\\demo1\\data\\obj.dat");

        // TODO 对象输出流(管道对象)
        ObjectInputStream objectIn = null;
        FileInputStream in = null;


        try {
            in = new FileInputStream(dateFile);
            objectIn = new ObjectInputStream(in);
            Object o = objectIn.readObject();
            System.out.println(o);// chapter08.User@1cf4f579
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

class User implements Serializable {
}
AI 代码解读

常见异常

在使用FileInputStream创建文件输入对象时,可能会出现FileNotFoundException,文件未找到的异常。

FileInputStream input = new FileInputStream("xxx");// 异常: java.io.FileNotFoundException
AI 代码解读

所以我们通常采用这样的套路:

FileInputStream input = null;
try {
    input = new FileInputStream("xxx");
} catch (FileNotFoundException e) {
    throw new RuntimeException(e);
} finally {
    try {
        if (input != null) {
            input.close();
        }
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}
AI 代码解读

其中,我们将input对象初始化为null,并且在try/catch语句中尝试使用new FileInputStream来时对象指向它的实例。

然后再进行对FileNotFoundException异常的捕捉。

由于流对象会占资源,所以我们最后要将这个管道进行关闭。而这里也需要对IOException异常进行捕捉。

对于ObjectInputStream类可能出现ClassNotFoundException,这是因为程序不知道该段程序中是否有这个对象的类,如果没有则会抛出异常。

ObjectInputStream objectInput = null;
try {
    objectInput.readObject();
} catch (IOException e) {
    throw new RuntimeException(e);
} catch (ClassNotFoundException e) {
    throw new RuntimeException(e);
}
AI 代码解读

对于ObjectOutputStream类可能会出现NotSerializableException异常,这是因为我们在序列化时应该允许序列化,如果不允许则会抛出异常。(需要对象的类实现Serializable接口)

详细代码见:序列化

目录
打赏
0
0
0
0
1
分享
相关文章
kde
|
5天前
|
Docker镜像加速指南:手把手教你配置国内镜像源
配置国内镜像源可大幅提升 Docker 拉取速度,解决访问 Docker Hub 缓慢问题。本文详解 Linux、Docker Desktop 配置方法,并提供测速对比与常见问题解答,附最新可用镜像源列表,助力高效开发部署。
kde
2900 7
国内如何安装和使用 Claude Code镜像教程 - Windows 用户篇
国内如何安装和使用 Claude Code镜像教程 - Windows 用户篇
542 0
Dify MCP 保姆级教程来了!
大语言模型,例如 DeepSeek,如果不能联网、不能操作外部工具,只能是聊天机器人。除了聊天没什么可做的。
798 9
2025年最新版最细致Maven安装与配置指南(任何版本都可以依据本文章配置)
本文详细介绍了Maven的项目管理工具特性、安装步骤和配置方法。主要内容包括: Maven概述:解释Maven作为基于POM的构建工具,具备依赖管理、构建生命周期和仓库管理等功能。 安装步骤: 从官网下载最新版本 解压到指定目录 创建本地仓库文件夹 关键配置: 修改settings.xml文件 配置阿里云和清华大学镜像仓库以加速依赖下载 设置本地仓库路径 附加说明:包含详细的配置示例和截图指导,适用于各种操作系统环境。 本文提供了完整的Maven安装和配置
2025年最新版最细致Maven安装与配置指南(任何版本都可以依据本文章配置)
【保姆级图文详解】大模型、Spring AI编程调用大模型
【保姆级图文详解】大模型、Spring AI编程调用大模型
330 7
【保姆级图文详解】大模型、Spring AI编程调用大模型
Excel数据治理新思路:引入智能体实现自动纠错【Python+Agent】
本文介绍如何利用智能体与Python代码批量处理Excel中的脏数据,解决人工录入导致的格式混乱、逻辑错误等问题。通过构建具备数据校验、异常标记及自动修正功能的系统,将数小时的人工核查任务缩短至分钟级,大幅提升数据一致性和办公效率。
DeepSeek R1+Open WebUI实现本地知识库的搭建和局域网访问
本文介绍了使用 DeepSeek R1 和 Open WebUI 搭建本地知识库的详细步骤与注意事项,涵盖核心组件介绍、硬件与软件准备、模型部署、知识库构建及问答功能实现等内容,适用于本地文档存储、向量化与检索增强生成(RAG)场景的应用开发。
363 0
让AI时代的卓越架构触手可及,阿里云技术解决方案开放免费试用
阿里云推出基于场景的解决方案免费试用活动,新老用户均可领取100点试用点,完成部署还可再领最高100点,相当于一年可获得最高200元云资源。覆盖AI、大数据、互联网应用开发等多个领域,支持热门场景如DeepSeek部署、模型微调等,助力企业和开发者快速验证方案并上云。
301 22
让AI时代的卓越架构触手可及,阿里云技术解决方案开放免费试用
FLUX.1 Kontext 的全生态教程来啦!AIGC专区在线试玩!
Flux.1 Kontext [dev] 开源模型大家都用上了吗?小编汇总了3个使用教程,打包送上!
402 1

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等