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

详细代码见:序列化

相关文章
|
程序员 编译器 C++
【深入探究Qt内部架构】QObject、事件循环与Q_OBJECT宏的协同作用(一)
【深入探究Qt内部架构】QObject、事件循环与Q_OBJECT宏的协同作用
1039 0
|
2月前
|
人工智能 自然语言处理 监控
Jev 能否用于银行风控?从规则引擎到语义决策层
Jev 并不是为了取代 Blaze、Drools 等传统规则引擎,而是为银行风控补充一层语义决策能力。规则引擎继续负责确定性业务规则,风险模型负责统计预测,Jev 则适合处理通话、短信、备注等非结构化信息中的还款意愿、承诺可信度、投诉风险和客户状态,并将结果交给策略引擎形成下一步动作。尤其在贷后催收中,可进一步推动从单纯依赖 DPD 的策略,演进为“规则 + 风险模型 + 语义决策 + 工作流”的组合式架构。
193 0
|
1月前
|
人工智能 开发者
阿里云优惠券是什么?在哪领取?2026年10月最新整理代金券、域名口令及学生券指南
阿里云2026年最新优惠券指南:涵盖AI焕新季1728元券、通用代金券、学生300元无门槛券、企业上云补贴、域名口令及1元购活动;详解权益中心/高校计划/企业补贴三大领取入口,以及查券路径(费用→卡券)和支付时自动抵扣用法。
623 0
|
3月前
|
数据采集 人工智能 搜索推荐
AI 搜索时代的 Q4 备战手册:GEO 优化的底层逻辑与落地三步法
随着 ChatGPT、Google AI Overview 等生成式 AI 成为消费者购物决策的新入口,品牌能否出现在 AI 的推荐列表中,将直接影响 Q4 黑五的流量与转化。 本文从技术层面拆解了 GEO(生成式引擎优化)的核心逻辑:大模型存在 30–60 天的实体索引滞后期,这意味着 10 月才开始优化已为时过晚。
|
供应链 监控 安全
1688商品详情API接口实战指南:合规获取数据,驱动B2B业务增长
1688商品详情API(alibaba.product.get)是合规获取B2B商品数据的核心工具,支持全维度信息调用,助力企业实现智能选品、供应链优化与市场洞察,推动数字化转型。
|
10月前
|
人工智能 算法 测试技术
人工智能测试工程师,需要掌握哪些真正「能落地」的技能?
AI时代,测试工程师正面临能力重构。AI未取代测试,却重塑其核心:从验证功能到保障不确定系统的稳定性与可信性。真正的AI测试需具备三层能力:理解模型逻辑、以数据驱动测试设计、构建智能化自动化体系。转型关键不在知识碎片,而在工程闭环实践。未来属于能让AI系统可靠落地的测试人。
|
11月前
|
算法 安全 数据安全/隐私保护
比较一下 DES、AES、SM4
DES、AES和SM4均为对称加密算法。DES采用56位密钥,已不推荐使用;AES支持128、192、256位密钥,全球广泛采用;SM4为我国商用密码标准,支持128位密钥,主要用于国内信息安全领域。
php常见问题,php.ini文件不存在或者找不到,mb_strlen()函数未定义系列问题,dll模块找不到的解决
本文介绍了解决PHP常见问题的步骤,包括定位和创建`php.ini`文件,以及解决`mb_strlen()`函数未定义和DLL模块加载错误的具体方法。
php常见问题,php.ini文件不存在或者找不到,mb_strlen()函数未定义系列问题,dll模块找不到的解决
|
SQL 存储 数据管理
《深入SQL事务:数据一致性与完整性的守护者》
在数据库中,事务是确保数据一致性和完整性的关键机制。它通过原子性、一致性、隔离性和持久性(ACID原则)保障操作的可靠性。事务将一组相关操作视为不可分割的工作单元,要么全部成功,要么完全回滚。例如银行转账场景中,扣款与存款必须同步完成以保证资金准确无误。此外,合理定义事务边界、选择合适隔离级别及避免长事务等实践策略,有助于提升系统性能和数据安全性。在电商订单处理、金融转账及ERP系统等复杂业务场景中,事务技术广泛应用,为高并发环境下的数据管理提供了坚实保障。随着数据库技术发展,事务机制将持续优化,满足日益复杂的业务需求。
626 2