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接口)

详细代码见:序列化

相关文章
|
存储 消息中间件 缓存
Redis分片集群的探讨
随着互联网应用的发展和数据量的不断增长,单机的Redis已经无法满足高并发和大规模数据存储的需求。为了解决这个问题,Redis引入了分片集群的概念。本文将探讨Redis分片集群的原理、实现方式以及相关的注意事项。
481 0
|
C语言 Perl
读源码学C之阅读李恒的bioawk
目前尚没有能力直接去阅读htslib的源代码,看到bioawk的代码稍微简单点,因此准备先从这里下手,bioawk的项目地址为https://github.com/lh3/bioawk。
1461 0
|
Python 区块链 数据格式
Flask 区域块简单原理实现
看了好几个从零开始建区块链的文章, 只有以下这几个URL实在, 于是,花了一晚上, 妥妥的自已手打一次, 感觉棒棒哒~~:)
2327 0
|
前端开发 JavaScript 数据格式
jQuery使用手册之Ajax支持(8)
$.ajax(prop)    通过一个ajax请求,回去远程数据,prop是一个hash表,它可以传递的key/value有以下几种。          (String)type:数据传递方式(get或post)。
885 0
|
2天前
|
人工智能 自然语言处理 Shell
🦞 如何在 Moltbot 配置阿里云百炼 API
本教程指导用户在开源AI助手Clawdbot中集成阿里云百炼API,涵盖安装Clawdbot、获取百炼API Key、配置环境变量与模型参数、验证调用等完整流程,支持Qwen3-max thinking (Qwen3-Max-2026-01-23)/Qwen - Plus等主流模型,助力本地化智能自动化。
🦞 如何在 Moltbot 配置阿里云百炼 API
|
6天前
|
人工智能 API 开发者
Claude Code 国内保姆级使用指南:实测 GLM-4.7 与 Claude Opus 4.5 全方案解
Claude Code是Anthropic推出的编程AI代理工具。2026年国内开发者可通过配置`ANTHROPIC_BASE_URL`实现本地化接入:①极速平替——用Qwen Code v0.5.0或GLM-4.7,毫秒响应,适合日常编码;②满血原版——经灵芽API中转调用Claude Opus 4.5,胜任复杂架构与深度推理。
|
10天前
|
JSON API 数据格式
OpenCode入门使用教程
本教程介绍如何通过安装OpenCode并配置Canopy Wave API来使用开源模型。首先全局安装OpenCode,然后设置API密钥并创建配置文件,最后在控制台中连接模型并开始交互。
4601 8
|
16天前
|
人工智能 JavaScript Linux
【Claude Code 全攻略】终端AI编程助手从入门到进阶(2026最新版)
Claude Code是Anthropic推出的终端原生AI编程助手,支持40+语言、200k超长上下文,无需切换IDE即可实现代码生成、调试、项目导航与自动化任务。本文详解其安装配置、四大核心功能及进阶技巧,助你全面提升开发效率,搭配GitHub Copilot使用更佳。
10403 21
|
3天前
|
人工智能 自然语言处理 Cloud Native
大模型应用落地实战:从Clawdbot到实在Agent,如何构建企业级自动化闭环?
2026年初,开源AI Agent Clawdbot爆火,以“自由意志”打破被动交互,寄生社交软件主动服务。它解决“听与说”,却缺“手与脚”:硅谷Manus走API原生路线,云端自主执行;中国实在Agent则用屏幕语义理解,在封闭系统中精准操作。三者协同,正构建AI真正干活的三位一体生态。
2344 9
|
1天前
|
存储 安全 数据库
使用 Docker 部署 Clawdbot(官方推荐方式)
Clawdbot 是一款开源、本地运行的个人AI助手,支持 WhatsApp、Telegram、Slack 等十余种通信渠道,兼容 macOS/iOS/Android,可渲染实时 Canvas 界面。本文提供基于 Docker Compose 的生产级部署指南,涵盖安全配置、持久化、备份、监控等关键运维实践(官方无预构建镜像,需源码本地构建)。
1246 2