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

判断是否为文件,注意这里是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

判断是否为文件夹

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

判断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

文件流的常用方法:

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();// 创建文件
    }
}

复制文件:

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);
                }
            }
        }
    }
}

缓冲流

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

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);
                }
            }
        }
    }
}

字符流

之前都是流转字节(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();
            }
        }
    }
}

序列化与反序列化

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

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 {
}

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

反序列化

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 {
}

常见异常

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

FileInputStream input = new FileInputStream("xxx");// 异常: java.io.FileNotFoundException

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

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);
    }
}

其中,我们将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);
}

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

详细代码见:序列化

相关文章
|
网络安全 数据安全/隐私保护
|
24天前
|
人工智能 JSON API
全网刷屏的 Jev 模型正式开放!一手实战测评 + 保姆级教程
全网爆火的 Jev 模型是什么?有什么用?怎么使用?怎么接入 AI 编程工具?效果真的好么?傻子可懂的 Jev 保姆级实战教程 + 项目实战测评来啦
9456 31
|
1天前
|
云安全 人工智能 运维
当攻击全面Agent化,你的安全防御能否跟上AI Speed?
多起客户侧AK泄露事件应急的真实观察
1153 0
|
10天前
|
存储 人工智能 并行计算
大模型本地部署终端选型方法论:以 Qwen3.8-27B 为例的四档分层完整流程
本文提出一套大模型本地部署终端选型方法论:定约束、定档位、定框架、定参数四步决策法,配合入门、主力、质量、无损四档分层模型。以 Qwen3.8-27B 实测数据为例,逐环节解读显存、带宽、存储、散热、系统、预算等要素,给出面向不同预算的优选方案、决策自查清单与市场观察框架。文末前瞻 AI 笔记本的 CPU+GPU 与统一内存两条路线,论证四步决策法在新品类上的延续性。
|
8天前
|
人工智能 JSON 自然语言处理
2026 年 Jev 决策模型深度拆解:原理解读、实战测评与保姆级落地教程
有一款特殊AI模型在开发者圈子刷屏,它摒弃传统大模型擅长的对话聊天能力,专注做高速结构化决策,它就是TypeSafe AI推出的Jev模型。该模型由ChatGPT共同发明人Diogo Almeida主导研发,定位为**System One Model(系统一模型)**,对标人类大脑快速直觉判断的思维模式,在响应延迟、调用成本、结构化输出稳定性上相比传统生成式大模型有着巨大差异。本文会完整拆解Jev底层原理、三大核心原语能力、适用业务场景,同时提供可直接运行的curl、Python代码示例,并且结合多组实测数据,客观分析模型优势与能力边界,帮助普通开发者和AI应用从业者快速上手落地。
702 1
|
5天前
|
人工智能 JSON 自然语言处理
2026 年 Jev 决策模型全解析:核心原理拆解,性能实战测评与落地部署教程
有一款特殊AI模型在开发者圈子刷屏,它摒弃传统大模型擅长的对话聊天能力,专注做高速结构化决策,它就是TypeSafe AI推出的Jev模型。该模型由ChatGPT共同发明人Diogo Almeida主导研发,定位为System One Model(系统一模型),对标人类大脑快速直觉判断的思维模式,在响应延迟、调用成本、结构化输出稳定性上相比传统生成式大模型有着巨大差异。本文会完整拆解Jev底层原理、三大核心原语能力、适用业务场景,同时提供可直接运行的curl、Python代码示例,并且结合多组实测数据,客观分析模型优势与能力边界,帮助普通开发者和AI应用从业者快速上手落地。
454 0
|
22天前
|
人工智能 测试技术 API
最近全网爆火的 Jev 到底是什么?适合干什么、怎么用,一篇讲透!
Jev是TypeSafe AI推出的“系统一模型”,不生成文本,专做毫秒级结构化决策:Choice(多选)、Score(打分)、Noul(是非概率)。响应快193倍、成本低444倍,适合工单路由、内容审核、测试定级等高频判断场景。
2528 4
最近全网爆火的 Jev 到底是什么?适合干什么、怎么用,一篇讲透!
|
3天前
|
存储 缓存 测试技术
QWT 3D 模块重构记:旧渲染管线改进介绍及实时瀑布图示例
QWT 3D模块完成重大重构:解耦窗口与图形(Plot+Item),摒弃OpenGL 1.x固定管线,迁至Core Profile着色器渲染;支持多图元同场景叠加,并以实时3D瀑布图验证——滑动窗口、固定色域、64帧×256点达61fps。兼容Qt 5.12+/6,LGPL协议。
170 120