字节流与字符流(流的操作流程、InputStream & OutputStream、Writer&Reader、转换流、实现文件拷贝)

**

2.字节流与字符流

**

2.1流操作简介

File类不支持文件内容处理,如果要处理文件内容,必须要通过流的操作模式来完成。流分为输入流和输出流。
在java.io包中,流分为两种:字节流与字符流
I.字节(byte)流:InputStream、OutputStream,可以处理文本文件、图像、音乐、视频等资源。
II.字符(char)流:Reader、Writer,只能用于处理中文文本。

字节流与字符流的本质区别只有一个:字节流是原生的操作,而字符流是经过处理后的操作。(处理就是经过转换流操作之后的结果)
在进行网络数据传输、磁盘数据保存所支持的数据类型只有:字节。
而所有磁盘中的数据必须先读取到内存后才能进行操作,而内存会帮助我们把字节变成字符。字符更容易处理中文。

流的操作流程

不管使用的是字节流还是字符流,其基本的操作流程几乎一样,以文件操作为例。
1. 取得终端对象–根据文件路径创建File类对象;
2. 根据终端对象取得输入输出流–根据字节流或者字符流的子类实例化父类对象;
3. 根据输入输出流进行数据的读取或写入操作
4. 关闭流(close())。

对于IO操作属于资源处理,所有的资源处理操作(IO操作、数据库操作、网络)最后必须要进行关闭。

2.2字节输出流(OutputStream)

OutputStream类的定义结构

public abstract class OutputStream implements Closeable, Flushable

只要有一个OutputStream对象,就可以调用OutputStream类中的方法,
I.OutputStream类实现了Closeable和Flushable两个接口,这两个接口中的方法:

1. Closeable: public void close() throws IOException;关闭流方法
2. Flushable: public void flush() throws IOException;刷新缓冲区

II.在OutputStream类中的核心方法
1). 将给定的字节数组内容全部输出:
public void write(byte b[]) throws IOException

2). 将给定的字节数组以off位置开始输出len长度后停止输出内:
public void write(byte b[], int off, int len) throws IOException
3). 输出单个字节:
public abstract void write(int b) throws IOException;

III.由于OutputStream是一个抽象类,所以要想为父类实例化,必须要使用子类FileOutputStream类来处理,使用如下的两种构造方法
1). 接收File类(覆盖):
public FileOutputStream(File file) throws FileNotFoundException
2). 接收File类(追加):
public FileOutputStream(File file, boolean append)

使用OutputStream输出数据时,若指定的文件不存在,FileOutputStream会自动创建文件(不包含创建目录)

IV.AutoCloseable自动关闭支持
从jdk1.7开始追加了一个AutoCloseable自动关闭接口,这个接口的主要没目的是自动进行关闭处理,但是这种处理一般不好用,因为使用它必须结合try…catch。推荐使用显示关闭.

2.3字节输入流InputStream

public abstract class InputStream implements Closeable

将读取的内容放入字节数组中:public int read(byte b[]) throws IOException
返回值有以下三种情况:
I.返回b.length:未读取的数据>存放的缓存区大小,返回字节数组大小;
II.返回大于0的整数,此整数小于b.length:未读取的数据<存放区大小,返回剩余数据大小;
III.返回-1:表示此时数据已经读取完毕。

2.4字符输出流:Writer

字符适合于处理中文数据,Writer是字符输出流的处理类,这个类的定义如下:

public abstract class Writer implements Appendable, Closeable, Flushable

在Writer类中提供write()方法,而且该方法接受的类型都是char型,
Writer类提供了一个直接输出字符串的方法:

public void write(String str) throws IOException

字符流若未关闭,数据在缓存区存放,不会输出到目标终端。要想将数据输出,要么将输出流关闭要么使用flush()强制刷新缓存区

2.5字符输入流Reader

public int read(char cbuf[])throws Exception

Reader依然是一个抽象类。如果要进行文件读取,需要使用FileReader。
Writer类提供了write()方法直接输出字符串,而在Reader类中没有方法可以直接读取字符串类型,此时只能通过字符数组进行读取操作。

3.转换流(单向的 字节流->字符流)

3.1转换流的基本使用

OutputStreamWriter类(字节输出流->字符输出流)是Writer类的子类
继承关系:public class OutputStreamWriter extends Writer
构造方法:public OutputStreamWriter(OutputStream out)

InputStreamReader(字节输入流->字符输入流)是Reader类的子类
继承关系:public class InputStreamReader extends Reader
构造方法:public InputStreamReader(InputStream in)

字符流的具体子类大都是通过转换流将字节流转为字符流(FileWriter继承转换流)

3.2文件拷贝

创建一个CopyFile类,这个类通过初始化参数接收源文件与目标文件路径。

package javaSE.bit.file;

import java.io.*;

/**
 * 文件拷贝
 * @author mayanni
 * @date 2019-05-05 14:20
 */
public class TestCopyFile {
    public static void main(String[] args)throws Exception {
        //源文件路径
        String sourceFilePath="D:"+File.separator+"JavaSE code"+File.separator
                +"test"+File.separator+"4.jpg";
        //目标文件路径
        String destFilePath="D:"+File.separator+"JavaSE code"+File.separator
                +"test"+File.separator+"鸭子.jpg";
        copyFile(sourceFilePath,destFilePath);
    }
    public static void copyFile(String sourceFilePath,
                                String destFilePath) throws Exception{
        //1.取得源文件与目标文件的File对象
        File sourceFile=new File(sourceFilePath);
        File destFile=new File(destFilePath);
        //2.取得输入输出流,
        // 将源文件的内容读取到程序中,再将程序中的内容输出到目标文件中
        InputStream in=new FileInputStream(sourceFile);
        OutputStream out=new FileOutputStream(destFile);
        //3.数据输入输出
        int len =0;
        byte[] data=new byte[1024];//开辟1k的缓存区,一次性读入多个内容
        long start =System.currentTimeMillis();
        while((len=in.read(data))!=-1){
            out.write(data,0,len);
        }
        long end=System.currentTimeMillis();
        System.out.println("共耗时"+(end-start)+"毫秒");
    }
}

你可能感兴趣的:(原创,Java)