Java基础之IO— 字节流与字符流4月打卡day24

举报
java厂长 发表于 2022/04/13 09:30:08 2022/04/13
【摘要】 Java基础之IO— 字节流与字符流4月打卡day24关于作者作者介绍🍓 博客主页:作者主页🍓 简介:JAVA领域优质创作者🥇、一名在校大三学生🎓、在校期间参加各种省赛、国赛,斩获一系列荣誉🏆。🍓 关注我:关注我学习资料、文档下载统统都有,每日定时更新文章,励志做一名JAVA资深程序猿👨‍💻。IO— 字节流与字符流字符流和字节流最本质的区别就是只有一个字节流是原生的操作,二字...

Java基础之IO— 字节流与字符流4月打卡day24

关于作者

  • 作者介绍


🍓 博客主页:作者主页

🍓 简介:JAVA领域优质创作者🥇、一名在校大三学生🎓、在校期间参加各种省赛、国赛,斩获一系列荣誉🏆。

🍓 关注我:关注我学习资料、文档下载统统都有,每日定时更新文章,励志做一名JAVA资深程序猿👨‍💻。

IO— 字节流与字符流

image-20210818173800455

字符流和字节流最本质的区别就是只有一个字节流是原生的操作,二字符流是经过处理后的操作。经过磁盘数据保存所保存的支持的数据类型只有:字节,所有磁盘中的数据必须先读到内存后才可以操作,内存里面会帮助我们把字节变为字符。字符更加适合处理中文。

字节操作流:OutputStream,InputStream;

字符操作流:Writer,Reader。

但是不管是字节流还是字符流的操作,本身都表示资源操作,而执行所有的资源都会按照如下几个步骤进行,下面以文件操作为例(对文件进行读,写操作):

  1. 要根据文件创建File对象

  2. 根据字节流或字符流的子类实例化我们的父类对象

  3. 进行数据的读取、写入操作

  4. 关闭流(clone())

对于IO操作属于资源处理,所有的对于资源的处理进行处理完成后必须进行关闭,否则资源就再也无法执行。

1、字节输出流:OutputStream

Java.io.OutputStream主要的功能是进行字节数据的输出的,而这个类的定义如下:

public abstract class OutputStream 
extends Object 
implements Closeable, Flushable

发现OutputStream类定义的时候实现了两个接口:Closeable,Flushable,这两个接口定义如下:

Closeable: Flushable:
public interface Closeable extends AutoCloseable{ public void close() throws IOException; } public interface Closeable{ public void flush() throws IOException; }

当取得了OutputStream类实例化对象之后,下面肯定要进行输出操作,在OutputStream类之中定义了三个方法:

输出单个字节数组数据:public abstract void write(int b) throws IOException

输出一组字节数组数据:public void write(byte[] b) throws IOException

输出部分字节数组数据:public void write(byte[] b,int off,int len) throws IOException

提示:对于Closeable继承的AutoCloseable接口

AuotCloseable实在JDK1.7的时候又增加了一个新的接口,但是这个接口的定义和Closeable定义是完全一样的,我个人认为:有可能在一些其他的类上出现了自动的关闭功能,Closeable是手工关闭,AutoCloseable属于自动关闭。

但是对于Closeable和Flushable这两个接口实话而言不需要关注,因为从最早的习惯对于flush()和close()连个方法都是直接在OutputStream类之中定义的,所以很少去关心这些父接口问题。

对于OutputStream类而言发现其本身定义的是一个抽象类(abstract class),按照抽象类的使用原则来讲,如果要想为父类实例化,那么就需要使用子类,就需要定义抽象的子类,而现在如果要执行的是文件操作,则可以使用FileOutputStream子类完成。如果按照面向对象的开发原则,子类要为抽象类进行对象的实例化,而后调用的方法以父类中定义的方法为主,而具体的实现找实例化这个父类的子类完成,也就是说在整个的操作之中,用户最关心的只有子类的构造方法:

实例化FileOutputStream(新建数据):public FileOutputStream([File file) throws FileNotFoundException

实例化FileOutputStream(追加数据):public FileOutputStream(File file,boolean append) throws FileNotFoundException

image-20210818181217500

实现文件内容的输出

package com.day14.demo;
​
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
​
public class OutputDemo {
    public static void main(String[] args) throws Exception {
        //1.定义文件路径
        File file = new File("f:" + File.separator + "test" + File.separator + "hello.txt");
        if(!file.getParentFile().exists()){//父路径不存在
            file.getParentFile().mkdirs();//创建父目录
        }
        //2.要输出的数据
        String str = "Hello,zsr!!!!";
        //3.实例化对象
        FileOutputStream stream = new FileOutputStream(file);
        //4.将内容写进stream
        stream.write(str.getBytes());//输出数据,要将输出的数据变为字节数组输出
        //5.关闭流
        stream.close();
    }
}

这里默认执行时进行文档内容的覆写,如果不希望进行文档内容的覆写可以直接将FileOutputStream改为

FileOutputStream stream = new FileOutputStream(file,true);

如果对写入的内容需要换行操作必须使用\r\n进行换行操作。

2、字节输入流:InputStream

如果现在要从指定的数据源之中读取数据,使用InputStream,而这个类的定义如下:

public abstract class InputStream
extends Object
implements Closeable

发现InputStream只实现了Closeable接口

在InputStream之中定义了三个读取数据的方法:

读取单个字节:public abstract int read() throws IOException

说明:每次执行read()方法都会读取一个数据源的指定数据,如果现在发现已经读取到了结尾则返回-1.

读取多个字节:public int read(byte[] b) throws IOException

说明:如果现在要读取的数据小于开辟的字节数组,这个时候read()方法的返回值int返回的是数据个数;如果现在开辟的字节数组小于读取的长度,则这个时候返回就是长度;如果数据已经读完了,则这个时候的int返回的是-1.

读取指定多个字节:public int read(byte[] b,int off,int len) throws IOException

说明:每次只读取传递数组的部分内容,如果读取满了,返回就是长度;如果没有读取满,返回的就是读取的个数;如果读取到最后没有数据了,就返回-1

image-20210818192150209

既然InputStream为抽象类,那么这个抽象类要使用就必须有子类,现在是通过文件读取内容,肯定使用FileInputStream子类进行操作,与OutputStream类的使用一样,对于FileInputStream也只关心构造方法:

FileInputStream**类构造方法:public FileInputStream(File file) throws FileNotFoundException

文件信息的读取

package com.day14.demo;
​
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
​
​
public class InputDemo {
    public static void main(String[] args) throws Exception {
        File file = new File("f:" + File.separator + "test" + File.separator + "hello.txt");
        if(!file.exists()){
            System.out.println("指定文件不存在!!");
        }else{
            FileInputStream is = new FileInputStream(file);
            byte[] result = new byte[1024];
            int length = is.read(result);
            System.out.println("读取的内容为:" + new String(result,0,length));
        }
    }
}
3、字符输出流:Writer

Writer类也是一个专门用来数据输出的操作类,对于中文数据来说是比较友好的,这个类定义:

public abstract class Writer
extends Object
implements Appendable, Closeable, Flushable

在Writer类之中定义的writer()方法都是以字符数据为主,但是在这些方法之中,只关心一个:

输出一个字符串:public void write(String str) throws IOException

如果要操作文件肯定使用FileWriter子类。

package com.day14.demo;
​
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
​
public class WriterDemo {
    public static void main(String[] args) throws IOException {
        //1.定义文件路径
        File file = new File("f:" + File.separator + "test" + File.separator + "hello.txt");
        if(!file.getParentFile().exists()){//父路径不存在
            file.getParentFile().mkdirs();//创建父目录
        }
        //2.要输出的数据
        String str = "我正在学java这门课程!!!!\r\n";
        //如果想要进行内容不覆盖的直接使用true就可以了
        //FileWriter out = new FileWriter(file,true);
        FileWriter out = new FileWriter(file);
        out.write(str);
        out.close();
    }
}
4、字符输入流:Reader

Reader是进行字符数据读取的一个操作类,其定义:

public abstract class Reader
extends Object
implements Readable, Closeable

在Writer类之中存在了直接输出一个字符串数据的方法,可是在Reader类之中并没有定义这样的方法,只是定义了三个按照字符串读取的方法?为什么会这样?

因为在使用OutputStream输出数据的时候,其程序可以输出的大小一定是程序可以承受的数据的大小,那么如果说使用InputStream读取的时候,可能被读取的数据非常大,那么如果一次性全读进来,就会出现问题,所以只能一个一个的进行读取。

Reader依然是抽象类,那么如果从文件读取,依然使用FileReader类

package com.day14.demo;
​
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
​
public class ReadDemo {
    public static void main(String[] args) throws IOException {
        File file = new File("f:" + File.separator + "test" + File.separator + "hello.txt");
        if(!file.exists()){
            System.out.println("指定文件不存在!!");
        }else{
            FileReader reader = new FileReader(file);
            char[] result = new char[1024];
            int length = reader.read(result);
            System.out.println("读取的内容为:" + new String(result,0,length));
        }
    }
}

字符比字节的好处就是在于字符串数据的支持上,而这个好处还只是在Writer()类中体现,所以与字节流相比,字符流的操作并不是对等的关系。

5、字节流与字符流区别

通过我们一系统的分析,可以发现字节流和字符流的代码操作区别不大,如果从我们实际的使用,我们字节流是优先考虑,只有再我们使用中文的时候才考虑使用字符流,因为所有的字符都需要通过内存缓冲来进行处理。

image-20210819114608877

既然读数据需要缓存的处理,那么写数据也同样需要。如果使用字符流没有进行刷新,那么我们的内容可能再缓存之中,所以必须进行强制刷新才能得到完整的数据内容。

package com.day14.demo;
​
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
​
public class WriterDemo {
    public static void main(String[] args) throws IOException {
        //1.定义文件路径
        File file = new File("f:" + File.separator + "test" + File.separator + "hello.txt");
        if(!file.getParentFile().exists()){//父路径不存在
            file.getParentFile().mkdirs();//创建父目录
        }
        //2.要输出的数据
        String str = "我正在学java这门课程!!!!\r\n";
        //如果想要进行内容不覆盖的直接使用true就可以了
        //FileWriter out = new FileWriter(file,true);
        FileWriter out = new FileWriter(file);
        out.write(str);
        out.flush();
    }
}

在以后的IO处理的时候,如果处理的是图片、音乐、文字都可以使用字节流,只有再处理中文的时候才会使用字符流。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。