• Java IO2:字节流


    输入输出流:

    • 输入/输出时, 数据在通信通道中流动。 所谓“数据流(stream)”指的是所有数据通信通道之中,数据的起点和终点。 信息的通道就是一个数据流。只要是数据从一个地方“流” 到另外一个地方,这种数据流动的通道都可以称为数据流。
    • 输入/输出是相对于程序来说的。 程序在使用数据时所扮演的角色有两个:一个是源, 一个是目的。若程序是数据流的源, 即数据的提供者, 这个数据流对程序来说就是一个“输出数据流” (数据从程序流出)。 若程序是数据流的终点, 这个数据流对程序而言就是一个“输入数据流” ( 数据从程序外流向程序)
    • 从功能上分为两大类:输入流和输出流。
    • 从流结构上可分为字节流( 以字节为处理单位或称面向字节)和字符流(以字符为处理单位或称面向字符) 。
    • 字节流的输入流和输出流基础是InputStream和OutputStream这两个抽象类,字节流的输入输出操作由这两个类的子类实现。字符流是Java 1.1版后新增加的以字符为单位进行输入输出处理的流, 字符流输入输出的基础是抽象类Reader和Writer

    • 需要声明:在最底层,所有的输入/输出都是字节形式的。基于字符的流只为处理字符提供方便有效的方法。

    流的分类

    • 节点流:从特定的地方读写的流类,例如:磁盘或一块内存区域。
    • 过滤流:使用节点流作为输入或输出。过滤流是使用一个已经存在的输入流或输出流连接创建的。

    字节流与字符流

    • 字节流类(Byte Streams) 字节流类用于向字节流读写8位二进制的字节。一般地,字节流类主要用于读写诸如图象或声音等的二进制数据。
    • 字符流类(Character Streams) 字符流类用于向字符流读写16位二进制字符。

    Byte Streams Character Streams
    InputStream Reader
    OutputStream Writer

    • 两种基本的流是:输入流(Input Stream)和输出流(Output Stream)。可从中读出一系列字节的对象称为输入流。而能向其中写入一系列字节的对象称为输出流。

    输入流

    读数据的逻辑为:
    open a stream
    while more information
    read information
    close the stream

    输出流

    写数据的逻辑为:
    open a stream
    while more information
    write information
    close the stream

    字节流类以InputStream 和OutputStream为顶层类,它们都是抽象类(abstract)

    • 抽象类InputStream 和 OutputStream定义了实现其他流类的关键方法。最重要的两种方法是read()和write(),它们分别对数据的字节进行读写。两种
    方法都在InputStream 和OutputStream中被定义为抽象方法。 它们被派生的流类重写。

    OutputStream(字节输出流):将信息写到文件中

    OutputStream是定义了Java流式字节输入模式的抽象类。该类的所有方法返回一个void值并且在出错的情况下引发一个IOException。

    三个基本的写方法
    abstract void write(int b) : 往输出流中写入一个字节。
    void write(byte[] b) : 往输出流中写入数组b中的所有字节。
    void write(byte[] b, int off,int len) : 往输出流中写入数组b中从偏移量off开始的len个字节的数据。

    其它方法
    void flush() : 刷新输出流,强制缓冲区中的输出字节被写出。
    void close() : 关闭输出流,释放和这个流相关的系统资源。

    • 通过打开一个到目标的输出流,程序可以向外部目标顺序写数据。当Java程序需要将数据输出到外设时, 可根据数据的不同形式, 创建一个适当的OutputStream子类类型的对象来完成与该外设的连接, 然后再调用执行这个流类对象的特定输出方法来实现对相应外设的输出操作。

    FileOutputStream(文件字节输出流)

    FileOutpuStream应该是Java中最常见的字节输出流了,它创建一个可向文件写入字节的类OutputStream,它常用的构造方法如下:

    1、FileOutputStream(String name)

    2、FileOutputStream(File file)

    3、FileOutputStream(File file, boolean append)

    前两个构造方法类似,前者输入文件的绝对路径,后者输入File的实例对象,推荐后者。第三个构造方法有一点不同

    if true, then bytes will be written to the end of the file rather than the beginning

    即原来的文件有内容的话不会冲掉,会在原有内容的基础上追加。

    public class OutputStreamTest1 {
        public static void main(String[] args) throws Exception {
    
            File file = new File("c:\out.txt");
    
            OutputStream os = new FileOutputStream(file, true);
    
    
            byte[] buffer = "hello world".getBytes();
    
            os.write(buffer);
    
            os.close();
        }
    }

    此时打开"out.txt":

    看到C盘下多了"out.txt",且文件中的内容和我们写入的一致.

    InputStream(字节输入流):将信息从文件读到程序中

    InputStream是定义了Java流式字节输入模式的抽象类。该类所有方法在出错的时候都会引发一个IOException,InputStream提供的抽象方法有:

    三个基本的读方法
    abstract int read() : 读取一个字节数据,并返回读到的数据,如果返回-1,表示读到了输入流的末尾。
    int read(byte[] b) : 将数据读入一个字节数组,同时返回实际读取的字节数。如果返回-1,表示读到了输入流的末尾。
    int read(byte[] b, int off, int len) : 将数据读入一个字节数组,同时返回实际读取的字节数。如果返回-1,表示读到了输入流的末尾。 off指定在数组b中存放数据的起始偏移位置; len指定读取的最大字节数。

    • 因为第二个read方法依靠第三个read方法来实现,而第三个read方法又依靠第一个read方法来实现,所以说只有第一个read方法是与具体的I/O设备相关的,它需要InputStream的子类来实现。

    其他方法

    long skip(long n) : 在输入流中跳过n个字节,并返回实际跳过的字节数。
    int available() : 返回在不发生阻塞的情况下,可读取的字节数。
    void close() : 关闭输入流,释放和这个流相关的系统资源。
    void mark(int readlimit) : 在输入流的当前位置放置一个标记,如果读取的字节数多于readlimit设置的值,则流忽略这个标记。
    void reset() : 返回到上一个标记。
    boolean markSupported() : 测试当前流是否支持mark和reset方法。如果支持,返回true,否则返回false。

    • 通过打开一个到数据源(文件、内存或网络端口上的数据)的输入流,程序可以从数据源上顺序读取数据。

    FileInputStream(文件字节输入流)

    FileInputStream是Java中最常见的字节输入流,它创建一个能从文件读取字节的InputStream类,它的两个常用构造方法如下:

    1、FileInputStream(String name)

    2、FileInputStream(File file)

    推荐后者的用法。

    public class InputStreamTest {
    public static void main(String[] args) throws Exception { File file = new File("c:\test.txt"); InputStream is = new FileInputStream(file); //缓存,读取的字节先放在缓存中 byte[] buffer = new byte[200]; //实际读取的字节数 int length = 0; while ((length = is.read(buffer, 0, 200)) != -1) { //把读取的字节数组转换成字符串 String str = new String(buffer, 0, length); System.out.println(str); } is.close(); } }

    运行结果

    Heroes come and go!But legends are forever!
    曼巴谢幕
    传奇永恒
  • 相关阅读:
    异常:调用链顺序
    日志分割建议
    java异常处理规范
    忽略字母大小写情况下统计字符出现的次数
    十六进制转化为十进制
    搜索(剪枝优化):HDU 5113 Black And White
    水题:HDU 5112 A Curious Matt
    综合(奇技淫巧):HDU 5118 GRE Words Once More!
    网络流(费用流)CodeForces 321B:Ciel and Duel
    数学(概率)CodeForces 626D:Jerry's Protest
  • 原文地址:https://www.cnblogs.com/winner-0715/p/5392725.html
Copyright © 2020-2023  润新知