首页 > 编程语言 >38 | JAVA_IO_OutputStream

38 | JAVA_IO_OutputStream

时间:2022-09-05 19:44:37浏览次数:66  
标签:OutputStream JAVA 字节 写入 write 38 缓冲区 output

OutputStream

InputStream相反,OutputStream是Java标准库提供的最基本的输出流。

InputStream类似,OutputStream也是抽象类,它是所有输出流的超类。这个抽象类定义的一个最重要的方法就是void write(int b),签名如下:

public abstract void write(int b) throws IOException;

这个方法会写入一个字节到输出流。要注意的是,虽然传入的是int参数,但只会写入一个字节,即只写入int最低8位表示字节的部分(相当于b & 0xff)。

InputStream类似,OutputStream也提供了close()方法关闭输出流,以便释放系统资源。

要特别注意:OutputStream还提供了一个flush()方法,它的目的是将缓冲区的内容真正输出到目的地。


补充:以下内容为操作系统的内容,具体还有 行缓冲全缓冲无缓冲 的区别,在 unix 系统中,可以调用对应的C函数进行特定流的缓冲模式的更改。

为什么要有flush()?因为向磁盘、网络写入数据的时候,出于效率的考虑,操作系统并不是输出一个字节就立刻写入到文件或者发送到网络,而是把输出的字节先放到内存的一个缓冲区里(本质上就是一个byte[]数组),等到缓冲区写满了,再一次性写入文件或者网络。对于很多IO设备来说,一次写一个字节和一次写1000个字节,花费的时间几乎是完全一样的,所以OutputStream有个flush()方法,能强制把缓冲区内容输出。

通常情况下,我们不需要调用这个flush()方法,因为缓冲区写满了OutputStream会自动调用它,并且,在调用close()方法关闭OutputStream之前,也会自动调用flush()方法。

但是,在某些情况下,我们必须手动调用flush()方法。举个栗子:

小明正在开发一款在线聊天软件,当用户输入一句话后,就通过OutputStreamwrite()方法写入网络流。小明测试的时候发现,发送方输入后,接收方根本收不到任何信息,怎么肥四?

原因就在于写入网络流是先写入内存缓冲区,等缓冲区满了才会一次性发送到网络。如果缓冲区大小是4K,则发送方要敲几千个字符后,操作系统才会把缓冲区的内容发送出去,这个时候,接收方会一次性收到大量消息。

解决办法就是每输入一句话后,立刻调用flush(),不管当前缓冲区是否已满,强迫操作系统把缓冲区的内容立刻发送出去。

实际上,InputStream也有缓冲区。例如,从FileInputStream读取一个字节时,操作系统往往会一次性读取若干字节到缓冲区,并维护一个指针指向未读的缓冲区。然后,每次我们调用int read()读取下一个字节时,可以直接返回缓冲区的下一个字节,避免每次读一个字节都导致IO操作。当缓冲区全部读完后继续调用read(),则会触发操作系统的下一次读取并再次填满缓冲区。


输出单个字节

public void writeFile() throws IOException {
    OutputStream output = new FileOutputStream("out/readme.txt");
    output.write(72); // H
    output.write(101); // e
    output.write(108); // l
    output.write(108); // l
    output.write(111); // o
    output.close();
}

输出多个字节

字符串的 getBytes() 方法进行编码成 字节流 ,毕竟我们用的是 OutputStream字节输出流

联想: python 中的字符编码函数为 encode()

public void writeFile() throws IOException {
    OutputStream output = new FileOutputStream("out/readme.txt");
    output.write("Hello".getBytes("UTF-8")); // Hello
    output.close();
}

InputStream一样,上述代码没有考虑到在发生异常的情况下如何正确地关闭资源。写入过程也会经常发生IO错误,例如,磁盘已满,无权限写入等等。我们需要用try(resource)来保证OutputStream在无论是否发生IO错误的时候都能够正确地关闭:

public void writeFile() throws IOException {
    try (OutputStream output = new FileOutputStream("out/readme.txt")) {
        output.write("Hello".getBytes("UTF-8")); // Hello
    } // 编译器在此自动为我们写入finally并调用close()
}

OutputStream实现类

FileOutputStream可以从文件获取输出流,这是OutputStream常用的一个实现类。此外,ByteArrayOutputStream可以在内存中模拟一个OutputStream

import java.io.*;
public class Main {
    public static void main(String[] args) throws IOException {
        byte[] data;
        try (ByteArrayOutputStream output = new ByteArrayOutputStream()) {
            output.write("Hello ".getBytes("UTF-8"));
            output.write("world!".getBytes("UTF-8"));
            data = output.toByteArray();
        }
        System.out.println(new String(data, "UTF-8"));
    }
}

在这里插入图片描述

标签:OutputStream,JAVA,字节,写入,write,38,缓冲区,output
From: https://www.cnblogs.com/mmxingye/p/16659321.html

相关文章

  • 39 | JAVA_IO_Filter模式(Decorator模式)-cnblog
    Filter模式(Decorator模式)为了解决依赖继承会导致子类数量失控的问题,JDK首先将InputStream分为两大类:一类是直接提供数据的基础InputStream,例如:FileInputStreamByteA......
  • 【Java基础】package、import关键字和JDK中主要包
    1.package声明在源文件首行,每一个.表示一层文件夹,指明该类所在包,包名通常都小写。根据项目需要将代码放在不同包中2.import(1)导入指定包下所需要的类、接口,xxx.*表示......
  • Java 使用技巧-如何抛出一个异常并捕获它
    工作中需要使用Java编写插件,但并不是主要技术栈,所以简单地学习记录一下。背景与Javascript不同,Java中类型的概念非常强,函数中不能返回与声明不同类型的返回值。例如下面......
  • 【Java基础】关键字this
    1.this是什么this是一个对象,表示当前对象或当前正在创建的对象2.使用在类的方法中,使用this.属性或this.方法调用当前对象属性或方法,但一般都省略。方法的形式参数和类......
  • 2022-08-30 day38 第一小组 王鸣赫
    目录HttpServletRequest//请求HttpServletResponse//响应路径匹配servlet加载时期常见传参有2种:GET和POST区别获取一个key对应的多个值请求转发作用域其他方法Respo......
  • 【Java基础】JavaBean是什么
    1.JavaBean是什么符合如下标准的Java类类是公共的public有一个无参的公共的构造器有属性,且有对应的get、set方法2.示例publicclassJavaBean{privateStrin......
  • 【Java基础】类的结构之三:构造器(构造方法)
    1.构造器是什么也称为构造方法、构造函数。(1)方法名与类名相同(2)没有返回值类型(3)不能被static、final、synchronized、abstract、native修饰publicclassCircle{......
  • JavaDoc
    JavaDocjavadoc命令是用来生成自己API文档的参数信息:@author作者名@version版本号@since指明需要最早使用的jdk版本@param参数名@return返回值情况......
  • 【设计模式】Java设计模式 - 建造者模式
    【设计模式】Java设计模式-建造者模式......
  • Java学习-第一部分-第二阶段-第八节:IO流
    IO流笔记目录:(https://www.cnblogs.com/wenjie2000/p/16378441.html)IO流体系图文件什么是文件文件.对我们并不陌生,文件是保存数据的地方,比如大家经常使用的word文......