java中基本I/O流之字节流和字符流

java中I/O流之字节流和字符流学习总结

基本内容

  • 如果使用数据流来进行文件内容的操作,基本分为2种:
    字符流: Reader(字符输入流)、Writer(字符输出流);
    字节流: InputStream(字节输入流)、OutputStream(字节输出流);

字节流与字符流操作的本质区别只有一个:字节流是原生的操作,而字符流是经过处理后的操作。

在进行网络数据传输、磁盘数据保存所保存所支持的数据类型只有:字节。
而所有磁盘中的数据必须先读取到内存后才能进行操作,而内存中会帮助我们把字节变为字符。字符更加适合处理中文。

不管使用的是字节流还是字符流,其基本的操作流程几乎是一样的,以文件操作为例。

基本为以下4步:

  1. 创建File类对象 ,主要是指明要操作的文件路径;
  2. 根据字节流或字符流的子类实例化父类对象 ;
  3. 进行数据的读取或写入操作;
  4. 关闭流(close());

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

基本用法用Java举例

1.字节输出流:(OutputStream)(重点)

public class Demo {
    public static void main(String[] args) throws IOException {
        //第一步:定义要输出的文件的File类对象
        File file = new File("e:"+File.separator+"hello"+File.separator+"my.txt");
        //输出信息的时候文件可以不存在,但是目录必须存在
        if(!file.getParentFile().exists()) {//父路径不存在
            file.getParentFile().mkdirs();//创建父路径
        }
        //第二步:利用OutputStream的子类为父类进行实例化
        OutputStream output = new FileOutputStream(file);
        //第三步:输出文字信息
        String msg = "富则达济天下,穷则独善其身";//字符串
        //为了方便输出需要将字符串变为字节数组
        byte data[] = msg.getBytes();//变为字节数组
        output.write(data);//输出数据
        output.close();//关闭流
    }
}

OutputStream类定义有三个重要的输出操作方法:

1. 将给定的字节数组内容全部输出:public void write(byte b[]) throws IOException
2. 将部分字节数组内容输出:public void write(byte b[], int off, int len) throws IOException(重点)
3. 输出单个字节:public abstract void write(int b) throws IOException

OutputStream是一个抽象类,按照抽象类的基本原则来讲,如果想要取得OutputStream类的实例化对象那么一定需要子类,如果要进行文件的操作,可以使用FileOutputStream类来处理,

这个类的构造方法如下:

1. 接收File类(覆盖):public FileOutputStream(File file) throws FileNotFoundException
2. 接收File类(追加):public FileOutputStream(File file, boolean append)

输出文件的部分内容 (一个字符两个字节)

output.write(data,0,10);//输出部分数据

使用循环方式进行单个字节的信息输出

for(int x = 0;x < data.length; x++) {
        output.write(data[x]);//单个字节输出数据
        }

2.字节输入流:(InputStream)(重点)

读取数据到字节数组中:public int read(byte b[]) throws IOException.最常用方法
  每次讲数据读取到数组之中,那么会返回一个读取长度的数据,如果没有数据则返回的长度为-1,可是要考虑两种情况:
  要读取的内容大于开辟的数组内容:长度就是整个数组的长度。
  要读取的内容小于开辟数组的内容,
长度就是全部最后的内容长度,数组装不满。

读取部分内容到字节数组中:public int read(byte b[], int off,int len) throws IOException
  每次读取内容到部分字节数组,只允许读取满限制的数组的字节个数。此方法依然会返回读取的长度。
  
整个操作跟输出的形式几乎是相同的,参数的类型及作用也几乎是相同的。

数据读取实例:

public class Demo {
    public static void main(String[] args) throws IOException {
        //第一步:定义要输出的文件的File类对象
        File file = new File("e:"+File.separator+"hello"+File.separator+"my.txt");
        //第二步:实例化InputStream
        InputStream input = new FileInputStream(file);
        //实现数据的读取操作
        byte data[] = new byte[1024];
        int len = input.read(data);//将数据读取到数组之中
        System.out.println("读取的内容【" +new String(data,0,len)+"】");
        //第四步关闭输入流
        input.close();
    }
}

读取单个字节

public class Demo {
    public static void main(String[] args) throws IOException {
        //第一步:定义要输出的文件的File类对象
        File file = new File("e:"+File.separator+"hello"+File.separator+"my.txt");//你的路径
        //第二步:实例化InputStream
        InputStream input = new FileInputStream(file);
        //实现数据的读取操作
        byte data[] = new byte[1024];
        int foot = 0;//控制保存的脚标索引
        int temp = 0;//接收每次保存的字节数据
        //while循环实际上按照由里向外的原则执行,它的执行分为两步:
        //第一步:“temp = input.read()”,表示读取一个字节保存到temp变量之中。
        //第二步:“(temp = input.read()) != -1”判断读取出来的temp内容是否为-1,
        //如果不是-1则表示还有数据,则进行保存。
        while((temp = input.read()) != -1);{
            data[foot ++] = (byte) temp;
        }
        System.out.println("读取的内容【" +new String(data,0,foot)+"】");
        //第四步关闭输入流
        input.close();
    }
}

3.字符输出流:(Writer)

这个Writer类可以直接输出字符串:public void write(String str) throws IOException

public class Demo {
    public static void main(String[] args) throws IOException {
        //第一步:定义要输出的文件的File类对象
        File file = new File("e:"+File.separator+"hello"+File.separator+"my.txt");//你的路径
        if(!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        Writer out = new FileWriter(file);
        String str = "一定要好好学习,天天向上。。。";
        out.write(str);
        out.close();
    }
}

虽然Writer类提供有字符数组的输出操作能力,但是从本质上来讲使用Writer类就意味着要执行字符串的直接输出。

字符流最适合操作中文,但并不意味着字节流就无法操作中文

4.字符输入流:(Reader)

在Reader类中也提供有一系列的read()方法。

数据的读取:public int read(char[] cbuf) throws IOException

public class Demo {
    public static void main(String[] args) throws IOException {
        //第一步:定义要输出的文件的File类对象
        File file = new File("e:"+File.separator+"hello"+File.separator+"my.txt");//你的路径
        if(file.exists()) {
            Reader in = new FileReader(file);
            char data[] = new char[1024];
            int len = in.read(data);//向字符数组保存数据,返回长度。
            System.out.println(new String(data,0,len));
            in.close();
        }
    }
}

字节流和字符流的区别

首先必须要明确一点,通过任何终端(网络、文件)读取或者输出的数据都一定是字节,但是字符是经过内存处理后的数据。

  • 字符输入:字节(磁盘)–> 自动转换为 –>字符(内存);
  • 字符输出:字符(内存)–> 自动转换为–>字节(磁盘);
    在利用字符流输出的时候,所有的内容实际上都只是输出到了缓冲区中(内存)。在使用close()方法关闭的时候会将我们缓冲区的数据进行输出,如果没有关闭,那么就将无法进行输出,此时可以利用flush()方法进行强制的输出。

字符使用到了缓冲区,而字节流没有使用到缓冲区。

如果处理中文使用字符流,其他的任何数据都使用字节流。

参考

https://blog.csdn.net/qq_41112517/article/details/80304014

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值