Java基础学习07--IO--字节流

目录

一、流的概念

二、字节流


一、流的概念

流是对 I/O 操作的形象描述,水从一个地方转移到另一个地方就形成了水流,而信息从一处转移到另一处就叫做 I/O 流。

一个流,必有源端和目的端,它们可以是计算机内存的某些区域,也可以是磁盘文件,甚至可以是 Internet 上的某个 URL。对于流而言,不用关心数据是如何传输的,只需要从源端输入数据(读),向目的端输出数据(写)。

如何理解输入和输出呢?简单地说,你听别人唠叨就是输入,你向别人发牢骚就是输出。在计算机的世界中,输入 Input 和输出 Output 都是针对计算机的内存而言的。比如读取一个硬盘上的文件,对于内存就是输入;向控制台打印输出一句话,就是输出。Java 中对于此类输入/输出的操作统称为 I/O,即 Input/Output。

输入流的抽象表示形式是接口 InputStream;输出流的抽象表示形式是接口 OutputStream

System.out.println(); 就是一个典型的输出流,目的是将内存中的数据输出到控制台。而 new Scanner(System.in); 就是一个典型的输入流,目的是将控制台接收的信息输入到内存中。

按照处理数据的单位,流可以分为字节流和字符流。字节流的处理单位是字节,通常用来处理二进制文件,如音乐、图片文件等,并且由于字节是任何数据都支持的数据类型,因此字节流实际可以处理任意类型的数据。而字符流的处理单位是字符,因为 Java 采用 Unicode 编码,Java 字符流处理的即 Unicode 字符,所以在操作文字、国际化等方面,字符流具有优势。

二、字节流

输入字节流类继承自抽象类 InputStream,输出字节流继承自抽象类 OutputStream

  • FileInputStream:把一个文件作为输入源,从本地文件系统中读取数据字节,实现对文件的读取操作。
  • ByteArrayInputStream:把内存中的一个缓冲区作为输入源,从内存数组中读取数据字节。
  • ObjectInputStream:对以前使用 ObjectOutputStream 写入的基本数据和对象进行反序列化,用于恢复那些以前序列化的对象,注意这个对象所属的类必须实现 Serializable 接口。
  • PipedInputStream:实现了管道的概念,从线程管道中读取数据字节。主要在线程中使用,用于两个线程间的通信。
  • SequenceInputStream:其他输入流的逻辑串联。它从输入流的有序集合开始,并从第一个输入流开始读取,直至到达文件末尾,接着从第二个输入流读取,依次类推。
  • System.in:从用户控制台读取数据字节,在 System 类中,in 是 InputStream 类型的静态成员变量。


public class TestByteStream {
    public static void main(String[] args) throws IOException {
        FileInputStream in = null;
        FileOutputStream out = null;
        try {
            File f = new File("/home/project/new_file.txt");
            f.createNewFile();
            //通过构造方法之一:String构造输入流
            in = new FileInputStream("/home/project/ori_file.txt");
            //通过构造方法之一:File类构造输出流
            out = new FileOutputStream(f);
            //通过逐个读取、存入字节,实现文件复制
            int c;
            while ((c = in.read()) != -1) {
                out.write(c);
            }
        } catch (IOException e) {
            System.out.println(e.getMessage());
        } finally {
            if (in != null) {
                in.close();
            }
            if (out != null) {
                out.close();
            }
        }
    }
}

 上面的代码分别通过传入字符串和 File 类,创建了文件输入流和输出流,然后调用输入流类的 read() 方法从输入流读取字节,再调用输出流的 write() 方法写出字节,从而实现了复制文件内容的目的。注意:一是 read() 方法碰到数据流末尾时(即读取完毕时),返回值是 -1,否则返回值 > -1;二是在输入、输出流用完之后,要在异常处理的 finally 块中关闭输入、输出流,以释放资源。

输出流的 write() 方法是覆盖文件内容,而不是在文件内容后面追加内容。如果想采用追加的方式,则在使用构造方法创建字节输出流时,增加第二个值为 true 的参数即可,如 new FileOutputStream(f,true)

InputStream 输入流的可用方法

  • int read():从输入流中读取数据的下一字节,返回 0 ~ 255 范围内的整型字节值;如果输入流中已无新的数据,则返回 -1。
  • int read(byte[] b):从输入流中读取一定数量的字节,并将其存储在字节数组 b 中,以整数形式返回实际读取的字节数(要么是字节数组的长度,要么小于字节数组的长度)。
  • int read(byte[] b, int off, int len):将输入流中最多 len 个数据字节读入字节数组 b 中,以整数形式返回实际读取的字节数,off 指数组 b 中将写入数据的初始偏移量。
  • void close():关闭此输入流,并释放与该流关联的所有系统资源。
  • int available():返回可以不受阻塞地从此输入流读取(或跳过)的估计字节数。
  • void mark(int readlimit):在此输入流中标记当前的位置。
  • void reset():将此输入流重新定位到上次 mark 的位置。
  • boolean markSupported():判断此输入流是否支持 mark() 和 reset() 方法。
  • long skip(long n):跳过并丢弃此输入流中数据的 n 字节。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值