广告
返回顶部
首页 > 资讯 > 后端开发 > JAVA >Java IO详解
  • 748
分享到

Java IO详解

java 2023-08-20 20:08:34 748人浏览 薄情痞子
摘要

一、I/O简介 io即Input和Output,即输入和输出。这里的输入和输出都是相对于内存来说的,具体见下图。 InputStream/Reader:所有输入流的基类,前者是字节输入流,后者是字符输入流。 OutputStream/Wr

一、I/O简介

io即Input和Output,即输入和输出。这里的输入和输出都是相对于内存来说的,具体见下图。
在这里插入图片描述
InputStream/Reader:所有输入流的基类,前者是字节输入流,后者是字符输入流。
OutputStream/Writer:所有输出流的基类,前者是字节输出流,后者是字符输出流。
字节是计算机存储容量的基本单位(Byte),1B=8b,二进制中占8位。
字符是文字或符号的统称。
字节流什么类型的文件都可以读取,字符流只能读取纯文本文件。

二、字节流

1、InputStream && OutputStream

InputStream 类图如下:
在这里插入图片描述
OutputStream类图如下:
在这里插入图片描述

jdk8文档中,InputStream 方法如下:
在这里插入图片描述
OutputStream方法如下:
在这里插入图片描述
从 Java 9 开始,InputStream 新增加了多个实用的方法:

readAllBytes():读取输入流中的所有字节,返回字节数组
readNBytes(byte[] b, int off, int len):阻塞直到读取 len 个字节。
transferTo(OutputStream out):将所有字节从一个输入流传递到一个输出流。

2、FileInputStream && FileOutputStream

我们日常使用的话,比较常见的就是FileInputStream了,其可直接指定文件路径,可以直接读取单字节数据,也可以读取至字节数组中。
FileInputStream 示例代码如下:

 public static void main(String[] args) {        try {            FileInputStream fileInputStream = new FileInputStream("inputTest.txt");            //1、返回从该输入流中可以读取(或跳过)的字节数的估计值,而不会被下一次调用此输入流的方法阻塞。            int available = fileInputStream.available();            System.out.println("available:" + available);            //2、跳过并丢弃来自此输入流的 2字节数据。            long skip = fileInputStream.skip(2);            System.out.println("skip:" + skip);            //3、读取文件内容,为了减少IO,我们创建一个Byte数组作为接收缓冲区            byte[] bytes = new byte[4];            int read;            //4、从输入流读取一些字节数,并将它们存储到缓冲区 b 。            while ((read = fileInputStream.read(bytes)) != -1) {                // 把byte数组转换成字符串                System.out.print(new String(bytes, 0, read));            }            if (fileInputStream != null) {                fileInputStream.close();            }        } catch (FileNotFoundException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }    }

inputTest.txt文件如下:
在这里插入图片描述
输出结果如下:

available:11skip:2adafadsff

FileOutputStream有如下构造方法:

public FileOutputStream(String name, boolean append)

boolean append为true表示在创建的文件存在时,不会清空原文件内容,以追加的方式写入。
若文件不存在,则新增文件。
示例代码如下:

 public static void main(String[] args) {        try {            FileOutputStream fileOutputStream = new FileOutputStream("outputTest.txt");            String s = "lalalaaadhawe";            // 将字符串转换为byte数组            byte[] bytes = s.getBytes();            fileOutputStream.write(bytes);            fileOutputStream.flush();            fileOutputStream.close();        } catch (FileNotFoundException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }    }

运行结果如下:
在这里插入图片描述

3、字节流的文件复制

学完了FileInputStream && FileOutputStream,我们可以利用其做文件复制,代码如下:

public static void main(String[] args) {        try {            FileInputStream fileInputStream = new FileInputStream("inputTest.txt");            FileOutputStream fileOutputStream = new FileOutputStream("copy.txt");            //一次拷贝4个字节            byte[] bytes = new byte[4];            int read;            //4、从输入流读取一些字节数,并将它们存储到缓冲区 b 。            while ((read = fileInputStream.read(bytes)) != -1) {                fileOutputStream.write(bytes, 0, read);            }            fileOutputStream.flush();            if (fileInputStream != null) {                fileInputStream.close();            }            if (fileOutputStream != null) {                fileOutputStream.close();            }        } catch (FileNotFoundException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }    }

4、BufferedInputStream && BufferedOutputStream

我们通过上面代码,可以看到,为了减少IO次数,可以设立一个缓冲池byte,提高读取效率。而BufferedInputStream 和BufferedOutputStream的设计初衷就是如此,通常我们也是使用带缓冲区的BufferedInputStream ,其源码如下:

publicclass BufferedInputStream extends FilterInputStream {    // 内部缓冲区数组    protected volatile byte buf[];    // 缓冲区的默认大小    private static int DEFAULT_BUFFER_SIZE = 8192;    // 使用默认的缓冲区大小    public BufferedInputStream(InputStream in) {        this(in, DEFAULT_BUFFER_SIZE);    }    // 自定义缓冲区大小    public BufferedInputStream(InputStream in, int size) {        super(in);        if (size <= 0) {            throw new IllegalArgumentException("Buffer size <= 0");        }        buf = new byte[size];    }}

5、DataInputStream && DataOutputStream

这一对类可以直接写入java基本类型数据(没有String),但写入以后是一个二进制文件的形式,不可以直接查看。
示例代码如下:

DataInputStream dis = new DataInputStream(fileInputStream);            dis.readInt();                        dis.readShort();            dis.readLong();            dis.readByte();            dis.readChar();            dis.readDouble();            dis.close()

6、序列化和反序列化 ObjectInputStream && ObjectOutputStream

Java 序列化就是指将对象转换为字节序列的过程,而反序列化则是将字节序列转换成目标对象的过程。具体参考:java中的序列化和transient关键字
ObjectInputStream 用于从输入流中读取 Java 对象(反序列化),ObjectOutputStream 用于将对象写入到输出流(序列化)。
示例如下:

ObjectInputStream input = new ObjectInputStream(new FileInputStream("object.data"));MyClass object = (MyClass) input.readObject();input.close();

7、打印流PrintStream

PrintStream源自OutputStream,其为标准字节的输出流,默认输出到控制台,也就是我们常用的System.out.println()方法。
在这里插入图片描述
日志框架的实现原理就是通过PrintStream的使用,输出到日志文件,示例如下:

public static void log(String msg) {        try {            // 指向一个日志文件            PrintStream ps = new PrintStream(new FileOutputStream("log.txt",true));            // 改变流的输出方向            System.setOut(ps);            // 获取系统当前时间            Date nowTime = new Date();            // 日期格式化            SimpleDateFORMat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");            String strTime = sdf.format(nowTime);            System.out.println(strTime+": "+msg);            ps.close();        } catch (FileNotFoundException e) {            e.printStackTrace();        }    }    public static void main(String[] args) {        log("第1次打印日志");        log("第2次打印日志");        log("第3次打印日志");    }

运行结果如图:
在这里插入图片描述

三、字符流

首先,确认一个问题,已经有字节流了,可以读取任意文件,为什么还要有字符流呢?
主要有以下原因:
1、对于字符文件,先作为字节传输,再转成字符,耗时耗力。
2、对于字符文件,转成字节之后,再转回来,如果是中文,很容易乱码。

1、Reader && Writer

类图如下:
在这里插入图片描述
在这里插入图片描述

2、FileReader && FileWriter

字符流常用的读写类为FileReader 与 FileWriter,我们还用复制文件来做示例,示例代码如下:

 public static void main(String[] args) throws IOException {            FileReader fileReader = new FileReader("file.txt");            FileWriter fileWriter = new FileWriter("file2.txt");            //一次拷贝4个字节            char[] chars = new char[1024*1024];            int read;            while ((read = fileReader.read(chars)) != -1) {                fileWriter.write(chars, 0, read);            }            fileWriter.flush();            if (fileReader != null) {                fileReader.close();            }            if (fileWriter != null) {                fileWriter.close();            }    }

执行结果如下:
在这里插入图片描述
中文没有乱码。
BufferedReader和BufferedWriter,类似于BufferedInputStream和BufferedOutputStream,内部都维护了一个字节数组作为缓冲区。

四、随机访问流RandoMaccessFile

RandomAccessFile 支持随意跳转到文件的任意位置进行读写,任意位置进入文件。
RandomAccessFile 比较常见的就是断点续传,适用于大文件的分片上传,后面单独开一篇文章进行总结

五、IO中的设计模式

1、适配器模式

适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。具体参考:java(面向对象)的23种设计模式(5)——适配器模式。
在Java IO中,为了实现字符流和字节流之间的相互转换,就产生了两个适配器的类,InputStreamReader 和 OutputStreamWriter 。
代码如下:

InputStreamReader isr = new InputStreamReader(new FileInputStream(fileName), "UTF-8");BufferedReader bufferedReader = new BufferedReader(isr);

2、装饰器模式

装饰器模式可以将新功能动态地附加于现有对象而不改变现有对象的功能。具体参考:java(面向对象)的23种设计模式(7)——装饰模式。
InputStream 的子类 FilterInputStream,OutputStream 的子类 FilterOutputStream,Reader 的子类 BufferedReader 以及 FilterReader,还有 Writer 的子类 BufferedWriter、FilterWriter 以及 PrintWriter 等,它们都是抽象装饰类。增强了子类对象的功能。

3、工厂模式

工厂模式,通过定义工厂父类负责创建对象的公共接口,而子类则负责生成具体的对象。具体参考:
java(面向对象)的23种设计模式(3)——工厂模式。

NIO 中大量用到了工厂模式,比如 Files 类的 newInputStream 方法用于创建 InputStream 对象(静态工厂)、 Paths 类的 get 方法创建 Path 对象(静态工厂)、ZipFileSystem 类(sun.nio包下的类,属于 java.nio 相关的一些内部实现)的 getPath 的方法创建 Path 对象(简单工厂)。

4、观察者模式

观察者模式:指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。具体参考:java(面向对象)的23种设计模式(11)——观察者模式。
NIO 中的文件目录监听服务基于 WatchService 接口和 Watchable 接口。WatchService 属于观察者,Watchable 属于被观察者。WatchService 用于监听文件目录的变化,同一个 WatchService 对象能够监听多个文件目录。

来源地址:https://blog.csdn.net/liwangcuihua/article/details/131050868

--结束END--

本文标题: Java IO详解

本文链接: https://www.lsjlt.com/news/376643.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Java IO详解
    一、I/O简介 IO即Input和Output,即输入和输出。这里的输入和输出都是相对于内存来说的,具体见下图。 InputStream/Reader:所有输入流的基类,前者是字节输入流,后者是字符输入流。 OutputStream/Wr...
    99+
    2023-08-20
    java
  • Java io流 详解
    文章目录 前言一、IO流的分类二、流的原理及流的数量三、Java IO流对象1. 输入字节流InputStream2. 输出字节流OutputStream 前言 "IO流"(Inpu...
    99+
    2023-09-17
    java 开发语言
  • JAVA—IO流详解
    1. 流概述 1.1. 什么是IO IO:Input/Output即输入&输出,也称之为流(河流,水流),指的是数据从一个地点到另一个地点过程;对于计算机来说文件的拷贝过程,文件的编写保存,显示功能都是使用到IO;将数据的传输过程看做一个输...
    99+
    2023-08-16
    java jvm 网络
  • Java 中的io模型详解
    目录1. BIO2. NIO3. 多路复用最后再说几个小问题1. BIO 我们先看一个 Java 例子: package cn.bridgeli.demo;   imp...
    99+
    2022-11-12
  • Java IO之流的分类详解
    目录一、根据流向分为输入流和输出流:二、根据传输数据单位分为字节流和字符流三、根据功能分为节点流和包装流总结一、根据流向分为输入流和输出流: 注意输入流和输出流是相对于程序而言的。 ...
    99+
    2022-11-13
  • 【JAVA IO 详细介绍】
    JAVA IO 详细介绍 目录一、什么是IO?1.1 IO的介绍1.2 流的介绍1.2.1 流的特征1.2.2 数据流的特征1.2.3 输入流的特征1.2.4 输出流的特征 二、...
    99+
    2023-10-26
    java
  • Java IO读取文件的实例详解
    Java中文件流的两个主要方式就是字符流和字节流,如下图:具体的使用方法可以参考官方文档,这里主要介绍四种常见的文件读取方式通过字节来读取文件(常用于二进制文件:图片、声音、视频等)2.通过字符来读取文件(常用于文本的读取)3.通过行来读取...
    99+
    2023-05-31
    java io 读取文件
  • Java中IO流解析及代码实例详解
    目录1、IO流1.流和流的分类什么是IO流?IO流的分类?java.io包下需要掌握的流有16个:2.如何使用流1、输入流(读文件):FileInputStream2、输出流(写文件...
    99+
    2022-11-12
  • 详解Java多线程和IO流的应用
    目录Java多线程和流的应用RamdomAccessFile多线程本地文件复制(完整代码)多线程网络下载(完整代码)测试代码及结果总结Java多线程和流的应用 最近看到了一个例子,是...
    99+
    2023-05-15
    Java多线程 Java IO流
  • Java 基础详解(泛型、集合、IO、反射)
    计划把 Java 基础的有些部分再次看一遍,巩固一下,下面以及以后就会分享自己再次学习的一点笔记!不是有关标题的所有知识点,只是自己觉得模糊的一些知识点。1.对于泛型类而言,你若没有指明其类型,默认为Object;2.在继承泛型类以及接口的...
    99+
    2023-05-30
    java 泛型 集合
  • Java详细讲解IO流的Writer与Reader操作
    目录接口连接一、Writer方法二、Reader方法接口连接 public static void main(String[] args) throws Exception io流的...
    99+
    2022-11-13
  • Python的io模块详解
    Python的io模块提供了多个流式处理接口,具体的处理函数实现位于_pyio.py模块中。 在_io.py模块中,提供了唯一的模块方法open(name, mode=None, buffering=None),但是没有read()方法。...
    99+
    2023-01-31
    详解 模块 Python
  • Java非阻塞IO和异步IO的详细介绍
    这篇文章主要讲解了“Java非阻塞IO和异步IO的详细介绍”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java非阻塞IO和异步IO的详细介绍”吧!阻塞模式 IO我们已经介绍过使用 Java...
    99+
    2023-06-02
  • Java详解IO流创建读取与写入操作
    目录概念io流对应的方法一、File方法(创建文件)二、FileInputStream(获取字节方法)输入流三、FileOutputStream(写入字节方法)输出流总结概念 IO流...
    99+
    2022-11-13
  • Java基础学习之IO流应用案例详解
    目录一、点名器二、集合到文件三、文件到集合一、点名器 需求: 我有一个文件里面存储了班级同学的姓名,每一个姓名占一行,要求通过程序实现随机点名器 实现步骤: 创建字符缓冲输入流对象创...
    99+
    2022-11-13
  • Java中文件的读写方法之IO流详解
    目录1.File类1.1File类概述和构造方法1.2File类创建功能1.3File类判断和获取功能1.4File类删除功能2.递归2.1递归2.2递归求阶乘2.3递归遍历目录3....
    99+
    2022-11-13
  • Java中IO流的详细介绍
    这篇文章主要介绍“Java中IO流的详细介绍”,在日常操作中,相信很多人在Java中IO流的详细介绍问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java中IO流的详细介绍”的疑惑有所帮助!接下来,请跟着小编...
    99+
    2023-06-20
  • 文件操作和IO详解
    文件操作 和 IO 文件,File 这个概念,在计算机里,也是“一词多用”. 文件的狭义和广义 狭义的文件: 指的是硬盘上的文件和目录(文件夹) 广义的文件: 泛指计算机中很多的软硬件资源.操作系统...
    99+
    2023-10-25
    网络 java-ee 学习 学习方法 面试
  • Java文件操作之IO流 File类的使用详解
    File类概述 File类能新建、删除、重命名文件和目录,但不能访问文件内容本身,如果需要访问文件内容本身,则需要使用后续的输入/输出流。 要在Java程序中表示一个真实存在的文件或...
    99+
    2022-11-12
  • Java IO流深入理解
    目录阻塞(Block)和非阻塞(Non-Block)同步(Synchronization)和异步(Asynchronous)BIO与NIO对比面向流与面向缓冲阻塞与非阻塞选择器的问世...
    99+
    2022-11-12
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作