Java研学-IO流(三)

六 字节流 – 字节输出流系列 OutPutStream体系

1 OutPutStream系列 – 字节输出流

// 表示字节输出流所有类的超类,输出流接受输出字节并将其发送到某个接收器
public abstract class OutputStream

FileOutputStream/BufferedOutputStream

2 FileOutputStream类设计

// 用于写入如图像数据的原始字节流,可实例化OutPutStream对象
public class FileOutputStream

// 当前路径下创建指定名字的文件
public FileOutputStream(String name)

// 例子
public class Test {
    public static void main(String[] args) {
        FileOutputStream fo=null;
        try {
            fo=new FileOutputStream("play2.txt");
            // public void write(byte[] bs)  写入字节数组
            // public void write(int b)  写入一个字节
            // public void write(byte[] bs,int start,int len)  写入字节数组,自指定位置始写指定长度
            fo.write(97);  // a
            fo.write("\r\n".getBytes());  // 换行
            fo.write("这里是一段文字通过字符串转换".getBytes(),0,12);
            // 这里是一 2字节1汉字
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fo!=null){
                try {
                    fo.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

  由于计算机中底层操作的都是字节数据,而OutputStream正好也是字节流,因此可以直接将数据写入到指定文件中,不需flush

3 BufferedOutputStream类设计 需flush

// 该类实现缓冲输出流,可直接向底层输入流写入字节
public class BufferedOutputStream

// 通过传递OutputStream实现类对象完成对文件的操作
public BufferedOutputStream(OutputStream out)

// 例子
public class Test {
    public static void main(String[] args) {
        BufferedOutputStream bo=null;
        try {
            bo=new BufferedOutputStream(new FileOutputStream("play.txt"));
            bo.write(66);
            bo.write("\r\n".getBytes());
            bo.write("烤鸡翅膀我最爱吃".getBytes(),0,12);
            // 烤鸡翅膀  1汉字2字节
            bo.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(bo!=null){
                try {
                    bo.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

  BufferedOutputStream不能直接将数据写入到指定文件中,因为其操作的是缓存区,需要将数据刷新到指定的文件中:,建议使用BufferedOutputStream操作字节流可降低内存资源的消耗

七 字节流 – 字节输入流系列 InputStream体系

1 InputStream系列 – 字节输入流

// InputStream 类设计
Class InputStream

FileInputStream/BufferedInputStream

2 FileInputStream类设计

// 用于读取图像等数据的原始字节流
public class FileInputStream

// 打开与实际文件的链接创建FileInputStream文件,由name命名读取文件中的数据,可实例化 InputStream类对象
public FileInputStream(String name)

// 例子
public class Test {
    public static void main(String[] args) {
        FileInputStream fi=null;
        try {
            fi=new FileInputStream("play.txt");
            int data=0;
            byte[] bs=new byte[1024*5];
            while ((data=fi.read(bs))!=-1){
                System.out.println(new String(bs,0,data));
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fi.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

  一个汉字(包括数字)在UTF-8编码下占用3个字节,在GBK编码下占用2个字节。因此,如果4个汉字存储需要12个字节,那么可以推断出这些汉字是在UTF-8编码下存储的。具体存储方式是将每个汉字转换为UTF-8编码下的3个字节,共计12个字节存储。

3 BufferedInputStream类设计

// 直接操作缓存区降低内存消耗
public class BufferedInputStream

// 读取InputStream 参数实现类指定的文件,创建一个BufferedInputStream并保存其参数,内部缓冲区数组创建并存在buf
public BufferedInputStream(InputStream in)

// 例子
public class Test {
    public static void main(String[] args) {
        BufferedInputStream bi=null;
        try {
            bi=new BufferedInputStream(new FileInputStream("play.txt"));
            int data=0;
            byte[] bs=new byte[1024*5];
            while ((data=bi.read(bs))!=-1){
                System.out.println(new String(bs,0,data));
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(bi!=null){
                    bi.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

字节流小结

  字节流高效流(带有Buffered缓存技术的流),没有像字符流那样提供高效的方法(newLine()和readLine());定义字节高效流的原因,就是操作缓存区代替直接操作系统底层,降低系统资源消耗;

八 例子

将指定盘符下的指定文件,复制粘贴到指定的盘符

public class FC {
    // 实现盘符下文件的读写操作,startName原文件名,endName目标文件名
    public void copy(String startName,String endName){
        // 分别定义两个字符高效流对象
        BufferedReader start=null;
        BufferedWriter end=null;
        try {
            // 分别实例化对象
            start=new BufferedReader(new FileReader(startName));
            end=new BufferedWriter(new FileWriter(endName));
            String data=null;
            while ((data=start.readLine())!=null){
                // 读一行写一行
                end.write(data);
                end.newLine();
                end.flush();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 防止start.close();出现异常导致end.close();无法关闭
            // 关闭多个异常时需要分别关,关闭资源操作是没有顺序的
            if (start!=null){
                try {
                    start.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (end!=null){
                try {
                    end.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

九 序列化

1 流转换

在这里插入图片描述
开发中可使用更高效的替代品

InputStreamReader – System.in — Scanner

OutPutStreamWriter – System.out.print()

2 序列化与反序列化

① 序列化:指使用指定的技术(OutputStream流,ObjectOutputStream类),将对象中的数据(通过对象调用方法获取的结果),存储到指定的文件中(也就是写的过程),或通过网络上传的过程

② 反序列化:将指定文件中或网络上的对象中的数据获取到(也就是读操作InputStream流,ObjectInputStream类)

// 创建序列化对象
public class Dog implements Serializable {
	// 将序列化号固定为常量
    private static final long serialVersionUID=1L;
    // Serializable接口是一个声明接口,他没有任何抽象方法,但想实现序列化反序列化操作必须实现它
    private String name;
    private int kg;
    public  Dog(){
        super();
    }

    public Dog(String name, int kg) {
        super();
        this.name = name;
        this.kg = kg;
    }

    public String getName() {
        return name;
    }

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

    public int getKg() {
        return kg;
    }

    public void setKg(int kg) {
        this.kg = kg;
    }

    @Override
    public String toString() {
        return "Dog{" +
                "name='" + name + '\'' +
                ", kg='" + kg + '\'' +
                '}';
    }
}

// 序列化
public class DXTest {
    public static void main(String[] args) {
        // 声明序列化操作流对象
        ObjectOutputStream oo=null;
        try {
            oo=new ObjectOutputStream(new FileOutputStream("play.txt"));
            // 实例化需序列化的对象
            Dog yellow = new Dog("大黄",24);
            // public void writeObject(Object obj) 将序列化对象写入流中(需要flush)
            oo.writeObject(yellow);
            oo.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(oo!=null){
                try {
                    oo.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("成功上传");
        }
    }
}

// 反序列化
public class DFTest {
    public static void main(String[] args) {
        // 声明反序列化对象
        ObjectInputStream oi=null;
        try {
            oi=new ObjectInputStream(new FileInputStream("play.txt"));
            // public Object readObject() 将文件中的对象读出来 序列化对象接收是Object因此需要强转
            Dog yellow= (Dog) oi.readObject();
            System.out.println(yellow.toString());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            if(oi!=null){
                try {
                    oi.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

  上传数据(序列化),是将数据以字节码的形式存储到指定的文件中,打开文件之后,无法直接阅读,需要下载(反序列化)后才能阅读
  在类的序列化过程中,如果添加新的属性,需要再次进行序列化和反序列化,这样同步操作才能不报错,如果一个没做,就会出现类无效异常 java.io.InvalidClassException

// 其中 stream classdesc serialVersionUID = 4216129340136042751 是本地读取类的序列化号
// local class serialVersionUID = 8800134341386811038 是本次已经存在的序列化号
java.io.InvalidClassException: com.Test.Dog; local class incompatible: stream classdesc serialVersionUID = 4216129340136042751, local class serialVersionUID = 8800134341386811038

  读取就是反序列化操作;而已存在就是序列化操作,两个版本号不同就会出现异常
  为了避免异常的出现,序列化后版本号进行固定;一般在实现序列化接口后,在类中(Dog类)将序列化号直接定义为常量

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

python 实现链表

链表基础知识 链表是在物理内存中不连续,数据通过链表中的指针来链接到下一个元素。 链表由一系列节点组成,节点在运行时动态生成,节点一般包括两个部分:存储数据的数据域,存储下一个节点的指针域 链表的常用操作&a…

<JavaEE> 什么是线程安全?产生线程不安全的原因和处理方式

目录 一、线程安全的概念 二、线程不安全经典示例 三、线程不安全的原因和处理方式 3.1 线程的随机调度和抢占式执行 3.2 修改共享数据 3.3 关键代码或指令不是“原子”的 3.4 内存可见性和指令重排序 四、Java标准库自带的线程安全类 一、线程安全的概念 线程安全是指…

抑郁症由什么引起?

抑郁症的发生并不是单一原因所导致,而是多种因素相互作用的结果。以下是一些主要的原因: 首先,生物学因素在抑郁症的发病中起到了关键作用。研究显示,抑郁症可能与遗传有关,家族中有患抑郁症的成员会增加个体患病的风…

Android studio Load error:undefined path variables

android stuido 报错 Load error:undefined path variables Gson is undefined 处理方法: 点击进行Sync Project with Gradle Files

了解 ignore_above 参数对 Elasticsearch 中磁盘使用的影响

在 Elasticsearch 中,ignore_above 参数允许你忽略(而不是索引)长于指定长度的字符串。 这对于限制字段的大小以避免性能问题很有用。 在本文中,我们将探讨 “ignore_above” 参数如何影响 Elasticsearch 中字段的大小&#xff0c…

ESP32 MicroPython WEB蓝牙红外遥控小车⑬

ESP32 MicroPython WEB蓝牙红外遥控小车⑬ 1、蓝牙遥控小车2 、红外遥控小车3 、WEB网页摄像头遥控小车 1、蓝牙遥控小车 实验目的 使用“YQD蓝牙小车”APP控制小车 实验内容 使用小车显示屏显示蓝牙连接情况,开启蓝牙名称为“yqd-car”,并设置连接到小…

Hdoop学习笔记(HDP)-Part.16 安装HBase

目录 Part.01 关于HDP Part.02 核心组件原理 Part.03 资源规划 Part.04 基础环境配置 Part.05 Yum源配置 Part.06 安装OracleJDK Part.07 安装MySQL Part.08 部署Ambari集群 Part.09 安装OpenLDAP Part.10 创建集群 Part.11 安装Kerberos Part.12 安装HDFS Part.13 安装Ranger …

2023年AI时代中小企业智能化发展报告

今天分享的是AI系列深度研究报告:《2023年AI时代中小企业智能化发展报告》。 (报告出品方:创业邦) 报告共计:47页 AI——中小企业的智能化增长利器 继蒸汽机、电气化、信息化时代之后,由第四次工业革命开…

基于STM32 + TIM _定时器的基本机构和工作原理详解

前言 本篇博客主要学习了解定时器的基本结构和工作原理,掌握定时器的驱动程序和设计。本篇博客大部分是自己收集和整理,如有侵权请联系我删除。 本次博客板子使用的是正点原子精英版,芯片是STM32F103ZET6,需要资料可以我拿取。 本博客内容原…

校园门禁可视化系统解决方案

随着科技的持续进步,数字化校园在教育领域中的地位日益上升,各种智能门禁、安防摄像头等已遍布校园各个地方,为师生提供安全便捷的通行体验。然而数据收集分散、缺乏管理、分析困难等问题也逐渐出现,在这个数字化环境中&#xff0…

【漏洞复现】大华智慧园区综合管理平台deleteFtp接口远程命令执行

漏洞描述 大华智慧园区综合管理平台deleteFtp接口存在远程命令执行,攻击者可利用该漏洞执行任意命令,获取服务器控制权限。 免责声明 技术文章仅供参考,任何个人和组织使用网络应当遵守宪法法律,遵守公共秩序,尊重社会公德,不得利用网络从事危害国家安全、荣誉和利益…

高速风梳的方案特点--【其利天下技术】

风梳作为美容美发用的一种设备,一直受国内外很多女性用户的喜爱。它对比高速风筒来说,因其设计的用途略有区别,一方面风梳可以做梳子用,换了头还可以作为风筒使用,所以在一定意义上,风梳更受人欢迎。 近年…

ES-ELSER 如何在内网中离线导入ES官方的稀疏向量模型(国内网络环境下操作方法)

ES官方训练了稀疏向量模型,用来支持语义检索。(目前该模型只支持英文) 最好是以离线的方式安装。在线的方式,在国内下载也麻烦,下载速度也慢。还不如用离线的方式。对于一般的生产环境,基本上也是网络隔离的…

Vulhub-信息泄露

1.Jetty WEB-INF 敏感信息泄露漏洞(CVE-2021-28164) docker-compose up -d 启动环境,显示8080端口被占用 修改 docker-compose.yml 中的映射端口 curl 访问 http://192.168.48.129:8090/WEB-INF/web.xml 显示404: 通过 %2e 绕过…

「C++」类和对象2

🎇个人主页:Ice_Sugar_7 🎇所属专栏:C启航 🎇欢迎点赞收藏加关注哦! 文章目录 🍉前言🍉构造函数🍌参数🍌默认构造函数🥝两种类型🥝编译…

设计模式---第三篇

系列文章目录 文章目录 系列文章目录前言一、模板方法模式二、知道享元模式吗?三、享元模式和单例模式的区别?前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享给你的码吧。 一…

mac修改默认shell为bash

1. 打开系统偏好设置 2. 点击用户群组 3. 按住ctrl,点击用户名 4. 点击高级选项,修改登录shell 参考:在 Mac 上将 zsh 用作默认 Shell - 官方 Apple 支持 (中国)

js 搜索记录

背景: 移动端的搜索记录,不可能通过调取接口来记录瑟,所以通过在某某.js一个文件定义和处理逻辑。 代码: //某某.js var yumingSearch {init: function () {initF7.GloblalF7.onPageInit("yumingSearch", function …

go开发之个微机器人的二次开发

简要描述: 下载消息中的语音 请求URL: http://域名地址/getMsgVoice 请求方式: POST 请求头Headers: Content-Type:application/jsonAuthorization:login接口返回 参数: 参数名必选类型…

Tkinter 面向对象框架《二》

一、说明 Tkinter 教程 开发完整的 Tkinter 面向对象应用程序开发完整的 Tkinter 面向对象应用程序。 即使OOP的高手,也未必对面向对象全部掌握。至于 Tkinter的OOP编程,其实高手们也是在摸索实践中。 为了面向对象和Tkinter参与本教程。如果你来这里纯…