file与io流(2)

news2025/1/13 9:46:24

具体的流的介绍:

-1-  字节流;

1 字节输入流:InputStream

java.io.InputStream抽象类是表示字节输入流的所有类的超类,可以读取字节信息到内存中。它定义了字节输入流的基本共性功能方法。

  • public int read(): 通过输入流的对象调用该方法,从输入流中读取一个字节。返回读取的字节值。虽然读取了一个字节,但是会自动提升为int类型。如果已经到达流末尾,没有数据可读,则返回-1。 (在应用字节流数组的情况下,常常用在for循环语句中作为终止条件
  • public int read(byte[] b): 通过输入流的对象调用该方法,并传入实参byte数组。从输入流中读取一些字节数,并将它们存储到字节数组 b中 。每次最多读取b.length个字节。返回实际读取的字节个数。如果已经到达流末尾,没有数据可读,则返回-1。
  • public int read(byte[] b,int off,int len):从输入流中读取一些字节数,并将它们存储到字节数组 b中,从b[off]开始存储,每次最多读取len个字节 。返回实际读取的字节个数。如果已经到达流末尾,没有数据可读,则返回-1。
  • public void close() :关闭此输入流并释放与此流相关联的任何系统资源。

说明:close()方法,当完成流的操作时,必须调用此方法,释放系统资源。因此,可以使用try-catch-finally结构

2 字节输出流:OutputStream

java.io.OutputStream抽象类是表示字节输出流的所有类的超类,将指定的字节信息写出到目的地。它定义了字节输出流的基本共性功能方法。

  • public void write(int b) :将指定的字节输出流。虽然参数为int类型四个字节,但是只会保留一个字节的信息写出。
  • public void write(byte[] b):将 b.length字节从指定的字节数组写入此输出流。
  • public void write(byte[] b, int off, int len) :从指定的字节数组写入 len字节,从偏移量 off开始输出到此输出流末尾
  • public void flush() :刷新此输出流并强制任何缓冲的输出字节被写出。
  • public void close() :关闭此输出流并释放与此流相关联的任何系统资源。

说明:close()方法,当完成流的操作时,必须调用此方法,释放系统资源。

public class FileStreamTest {
    @Test
    public void test(){
        //1、创建File的实例对象
        //2、创建相应的字节流
        //3、读入和写出数据
        //4、关闭资源

        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            File srcFile = new File("Edney.jpg");//创建File对象
            File destFile = new File("Edney_copy.jpg");

            fis = new FileInputStream(srcFile);//创建字节流
            fos = new FileOutputStream(destFile);

            byte[] buffer = new byte[1024];//因为是字节流,所以创建byte[]数组。如果是创建字符流,则此处创建char数组
            int len;
            while ((len = fis.read(buffer))!=-1){
                fos.write(buffer,0,len);
            }//输入流读取结束返回-1为循环终止条件
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            System.out.println("Successfully copy!");
            try {
                fis.close();
                fos.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

    }
}

字符流:利用char数组存储和输出流,适用于文本文件,不适用于非文本文件如jpg文件等。

字节流:利用byte数组的存入和输出流,通常可以完成非文本文件的操作。如果涉及文本文件的复制操作,也可以使用字节流。但读取中文字符时可能会出错。

因为中文字符正常UTF-8占用3个字节,若读取时出现拆开中文字节的情况,可能出现乱码。

gbk中,中文字符只占用2字节。

文本文件:.txt  .java  .c   .cpp  .py等

非文本文件:.doc  .xls  .jpg  .mp3  .mp4  .avi  等

-2-  缓冲流的使用

(1)主要的缓冲流:

BufferedInputStream

BufferedOutputStream

BufferedReader

BufferedWriter

处理非文本文件的字节流

BufferedInputStream    read(byte[] buffer)

BufferedOutputStream   write(byte[]  buffer,0,len)

处理文本文件的字符流

BufferedReader read(byte[] buffer)

BufferedWriter write(byte[]  buffer,0,len)

前一篇博客中已总结过,字符流对应文本文件,字节流对应非文本文件,

(2)flush方法

内置缓冲区的原因,如果FileWriter不关闭输出流,无法写出字符到文件中。但是关闭流的对象,是无法继续写出数据的。如果我们既想写出数据,又想继续使用流,就需要flush() 方法了。

  • flush() :刷新缓冲区,流对象可以继续使用。
  • close():先刷新缓冲区,然后通知系统释放资源。流对象不可以再被使用了。

注意:即便是flush()方法写出了数据,操作的最后还是要调用close方法,释放系统资源。

//关于缓冲流BufferedInputStream and BufferedOutputStream的使用
@Test
public void test1(){
    File srcFile = new File("Edney.jpg");//创建File类的对象
    File destFile = new File("Edney_copy.jpg");//字节流可以处理非文本文件的复制操作

    FileInputStream fis = null;//创建输入流的对象
    FileOutputStream fos = null;//创建输出流的对象

    BufferedInputStream bis = null;//创建缓冲输入流的对象
    BufferedOutputStream bos = null;//创建缓冲输出流的对象
    try {
        fis = new FileInputStream(srcFile);
        fos = new FileOutputStream(destFile);

        bis = new BufferedInputStream(fis);
        bos = new BufferedOutputStream(fos);
        //分别对各对象进行初始化。为了防止编译时异常,此处进行try-catch捕获异常。

        byte[] buffer = new byte[5];//创建byte[]数组
        int len;
        while ((len = bis.read(buffer))!=-1){
            bos.write(buffer,0,len);//写出缓冲输入流的对象锁读取的byte字节,长度为读取对象字节的长度
        }
        System.out.println("successfully copy!");
    } catch (IOException e) {
        System.out.println(e.getMessage());
    } finally {
        try {
            if (bos!=null)
                bos.close();//分别关闭bos与bis的资源,防止资源的泄露。
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

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

-3-  转换流的使用:

(1)字符编码与字符解码:

字符编码:字符、字符串、字符数组--->字节、字节数组  由可见可懂的转化为不可懂的

字符解码:字节、字节数组--->字符、字符串  由不可懂的转化为可见可懂的

(2)转换流的作用:

实现字节与字符之间的转换。

public void test2(){
    //将使用gbk格式的文件转换为使用utf-8字符集的文件存储

    InputStreamReader isr = null;
    OutputStreamWriter osw = null;
    try {
        File file = new File("WithYou.text");
        File file1 = new File("WithYou_to_utf8");//转换后的文件

        FileInputStream fis = null;
        isr = null;

        fis = new FileInputStream(file);//初始化输入流
        isr = new InputStreamReader(fis,"GBK");//指定编码字符集为GBK

        FileOutputStream fos = null;
        osw = null;

        fos = new FileOutputStream(file1);//初始化输出流
        osw = new OutputStreamWriter(fos,"utf8");//指定输出流转化为utf8的字符集

        char[] cBuffer = new char[1024];//因为讨论的是文件格式所以使用字符流,创建char数组。
        int len;
        while ((len=isr.read(cBuffer))!=-1){
            osw.write(cBuffer,0,len);
        }

        System.out.println("finish");
    } catch (IOException e) {
        System.out.println(e.getMessage());
    } finally {
        try {
            if (osw!=null)
            osw.close();
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }
        try {
            if (isr!=null)
            isr.close();
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }
    }
}

数据流;

DataOutputStream:将内存中的基本数据类型和String类型的变量写出到具体的文件中

   DataInputStream:将文件中保存的数据还原为基本数据类型和引用数据类型

-4-  对象流:

(1)常用API:

对象输入流:ObjectInputStream

对象输出流:ObjectOutputStream

(2)作用:

可以读写基本数据类型的变量、引用数据类型变量

序列化:使用ObjectOutputStream  将内存中的java对象保存在文件中。

反序列化;使用ObjectInputStream  将文件中的数据额或网络传输过来的数据还原为内存中的java对象

@Test
public void test() throws IOException {
    //序列化
    File file = new File("object.txt");
    ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file));
    //根据构造器,应当传入输出流OutputStream
    // 因为file文件不是流对象,只是一个标识文件名称和路径的对象,此时需要对输出流进行创建,此处选择了匿名的方式创建。

    oos.writeUTF("How pity that I didn't try to detain you that time.");
    oos.flush();

    oos.writeObject("Though I know it would not change anything.");//写object对象
    oos.flush();

    oos.close();
}

@Test
public void test1()throws IOException{
    //反序列化
    File file = new File("object.txt");
    ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));

    String str = ois.readUTF();
    System.out.println(str);

    String str2 = null;
    try {
        str2 = (String)ois.readObject();//对写入的object对象进行读取,因为进行强转,所以需要try-catch捕获异常
    } catch (ClassNotFoundException e) {
        throw new RuntimeException(e);
    } finally {
        System.out.println(str2);
        ois.close();
    }
}

自定义类实现序列化:

1、自定义类实现接口Serializable

2、要求自定义类声明一个全局常量  static final long serialVersionUID

若不声明该全局常量,系统会自动生成。但改变自定义类的时候,因为序列号会改变,可能会导致异常。

要求定义的类的各个属性也必须是可序列化的

@Test
public void test2() throws IOException{
    //序列化
    File file = new File("object1.dat");
    ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file));

    Person p1 = new Person("Qum",18);//自定义类实现接口,Serializable
    oos.writeObject(p1);
    oos.flush();

    Person p2 = new Person("Dit",1024,new Account(1314));
    oos.writeObject(p2);
    oos.flush();

    oos.close();

}

@Test
public void test3() throws IOException{
    //反序列化
    File file = new File("object1.dat");
    ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));

    Person person = null;
    try {
        person = (Person) ois.readObject();
    } catch (ClassNotFoundException e) {
        throw new RuntimeException(e);
    }

    Person person1 = null;

    try {
        person1 = (Person)ois.readObject();
    } catch (ClassNotFoundException e) {
        throw new RuntimeException(e);
    }

    System.out.println(person);
    System.out.println(person1);
        ois.close();

}

关于class Person与class Account

public class Person implements Serializable {
    //自动生成序列常量
    private String name;
    private int age;

    Account account;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;

    }

    public Person(String name, int age, Account account) {
        this.name = name;
        this.age = age;
        this.account = account;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", account=" + account +
                '}';
    }
}


class Account implements Serializable{

    static final long serialVersionUID = 32574967298758L;
    private int balance;

    public Account(int balance) {
        this.balance = balance;
    }

    public int getBalance() {
        return balance;
    }

    @Override
    public String toString() {
        return "Account{" +
                "balance=" + balance +
                '}';
    }

    public void setBalance(int balance) {
        this.balance = balance;
    }
}

加上transient关键字则属性不可序列化。

静态变了不可序列化。

-5- 其他流(仅做了解)

1、标准输入输出流

System.in:标准输入流,默认为键盘输入

System.out:标准输出流,默认为控制台(显示器)输出

通过调用如下方法,修改输入流和输出流的位置

setIn(InputStream is)

setOut(PrintStream ps)

2、打印流

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2275917.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

mark 一下conductor github

Netflix 关闭conductor 后,后续https://orkes.io/content/ 继续在维护,github地址如下 https://github.com/conductor-oss/conductor 最新release为3.21.11

PyCharm文档管理

背景:使用PyCharmgit做文档管理 需求:需要PyCharm自动识别docx/xslx/vsdx等文件类型,并在PyCharm内点击文档时唤起系统内关联应用(如word、excel、visio) 设置步骤: 1、file -》 settings -》file types 2、在Files opened i…

嘉立创画原理图和PCB

一、环境 进入立创EDA官网 注册登录的环节就不介绍了。 登录账号后,选择专业版 二、原理图 工程中,有原理图和PCB,这里选择原理图 那么接下来就是进行绘制 元器件在如下区域搜索使用。 双击进行放置,也可以左键提前预览。 网…

科创驱动 | 华望系统科技荣膺西湖区年度前沿创新新锐企业

2025年1月3日,由中共西湖区党委、西湖区人民政府主办的“新年第一会”—西湖区科技创新大会在杭州隆重举行。大会现场揭晓了西湖区年度科技创新团队与项目,并发布了“2024西湖区科技十大事件”与“西湖区五大年度科技榜单”。杭州华望系统科技有限公司榜…

Monorepo设置:新手指南

Monorepo是一种项目代码管理方法,指在单个代码仓库中管理多个项目,有助于简化代码共享、版本控制、构建和部署的复杂性,并提供更好的可重用性和协作性。 简单理解:所有项目都在一个代码仓库中 📦,但这并不意…

[Python学习日记-75] 计算机基础与网络

[Python学习日记-75] 计算机基础与网络 简介 计算机基础 什么是网络编程 计算机网络 简介 本篇主要介绍的计算机基础是浓缩的,这是因为我们主要学习的是 Python,而 Python 主要是为了开发应用程序的,并不会用它来开发操作系统和嵌入式程序…

1. Doris分布式环境搭建

一. 环境准备 本次测试集群采用3台机器hadoop1、hadoop2、hadoop3, Frontend和Backend部署在同一台机器上,Frontend部署3台组成高可用,Backend部署3个节点,组成3副本存储。 主机IP操作系统FrontendBackendhadoop1192.168.47.128Centos7Foll…

【Java】-- 利用 jar 命令将配置文件添加到 jar 中

目录 1、准备 2、目标 3、步骤 3.1、安装 jdk 3.2、添加配置文件 3.3、校验 1、准备 java 环境hadoop-core-1.2.1.jar 和 core-site.xml 2、目标 将 core-site.xml 添加到 hadoop-core-1.2.1.jar 中。 3、步骤 3.1、安装 jdk 3.2、添加配置文件 jar -cvf hadoop-core-…

day14-Linux系统基础权限知识精讲

1. 给文件加特殊属性 1.1 chattr a:只能追加内容,不能删除 i:不能修改,不能删除;保护关键文件,防止非法写入 [rootoldboy ~]# chattr a test.txt [rootoldboy ~]# chattr i test.txt [rootoldboy ~]# echo 123 >> test.txt -bash: t…

Android使用系统消息与定时器实现霓虹灯效果

演示效果: 界面设计: 在帧布局FrameLayout中添加6个TextView 依次设置这6个TextView的宽,高,权重 也可在XML中直接设置 添加自定义颜色 关联自定义颜色到数组变量 关联6个TextView控件到数组变量 处理自定义系统消息 Handler _sysHandler new Han…

数据结构大作业——家谱管理系统(超详细!完整代码!)

目录 设计思路: 一、项目背景 二、功能分析 查询功能流程图: 管理功能流程图: 三、设计 四、实现 代码实现: 头文件 结构体 函数声明及定义 创建家谱树头结点 绘制家谱树(打印) 建立右兄弟…

vue3+elementPlus之后台管理系统(从0到1)(day1)

vue3官方文档:https://cn.vuejs.org/guide/introduction.html 1、项目创建 确保电脑已安装node 查看命令: node -v进入项目目录,创建项目 npm init vuelatest Need to install the following packages: create-vue3.13.0 Ok to procee…

汉图科技XP356DNL高速激光打印一体机综合性能测评

汉图科技XP356DNL高速激光打印一体机效率方面表现出色,支持A4纸型的高速打印,单面打印速度高达35页/分钟,自动双面打印速度可达32面/分钟,这样的速度在日常办公中能够极大地提高打印效率,减少等待时间,满足…

【芯片封测学习专栏 -- 什么是 Chiplet 技术】

请阅读【嵌入式开发学习必备专栏 Cache | MMU | AMBA BUS | CoreSight | Trace32 | CoreLink | ARM GCC | CSH】 文章目录 OverviewChiplet 背景UCIeChiplet 的挑战 Overview Chiplet 又称为小芯片。该技术通过将大型SoC划分为更小的芯片,使得每个部分都能采用不同…

1.CSS的复合选择器

1.1 什么是复合选择器 在CSS中,可以根据选择器的类型把选择器分为基础选择器和复合选择器,复合选择器是建立在基础选择器之上,对基础选择器进行组合形成的。 复合选择器可以更精准、更高效的选择目标元素(标签) 复…

【MySQL】SQL菜鸟教程(一)

1.常见命令 1.1 总览 命令作用SELECT从数据库中提取数据UPDATE更新数据库中的数据DELETE从数据库中删除数据INSERT INTO向数据库中插入新数据CREATE DATABASE创建新数据库ALTER DATABASE修改数据库CREATE TABLE创建新表ALTER TABLE变更数据表DROP TABLE删除表CREATE INDEX创建…

docker 自建rustdesk服务器测试

参考https://blog.csdn.net/tootsy_you/article/details/130010564 注意: docker-compose.yml version: 3networks:rustdesk-net:external: falseservices:hbbs:container_name: hbbsports:- 21115:21115- 21116:21116- 21116:21116/udp- 21118:21118image: rust…

检验统计量与p值笔记

一、背景 以雨量数据为例,当获得一个站点一年的日雨量数据后,我们需要估计该站点的雨量的概率分布情况,因此我们利用有参估计的方式如极大似然法估计得到了假定该随机变量服从某一分布的参数,从而得到该站点的概率密度函数&#x…

每日十题八股-2025年1月12日

1.为什么四次挥手之后要等2MSL? 2.服务端出现大量的timewait有哪些原因? 3.TCP和UDP区别是什么? 4.TCP为什么可靠传输 5.怎么用udp实现http? 6.tcp粘包怎么解决? 7.TCP的拥塞控制介绍一下? 8.描述一下打开百度首页后发生的网络过…

制造企业“数字化转型”典型场景参考

聚焦产业链上下游企业研发设计、生产制造、运维服务、经营管理、供应链管理等场景,以场景为切入点梳理数字化转型痛点需求,绘制重点行业、重点产业链数字化转型场景图谱(简称“一图谱”),明确企业数字化转型路径&#…