java I/O基础:字节流与字符流

简介

java IO操作中,对数据的传输主要是字节流和字符流2种方式,下面我们分别了解一下字节流和字符流的操作和优缺点

  • 由于下面4个都是抽象类,所以代码例子都是使用对应的文件类(FileXXXX)实现的

字节流

顾名思义,就是用字节(byte)的方式传输数据,数据传输自然对应着输入(InputStream)和输出(OutputStream),这里输入和输出对应的对象是服务器(平时,也就是你的电脑),拿文件举例:我们代码中的文字存入磁盘的文件中,就称为输出,反之,则为输入。

OutputStream

  • 以字节的方式作为输出
  • 是一个抽象类,不能直接实例化,他有众多子类,比如我们常用的FileOutputStream
  • 继承了2个接口,分别是Closeable(Closeable又继承了AutoCloseable)、另外一个接口Flushable
    • AutoCloseable:可以利用-try()-实现自动关闭资源
    • Flushable中的flush()方法可以将内存中缓存的数据强制刷新,比如将内存中缓存的数据,在未关闭钱,强制刷新到文件中。
常用方法
  • output.write(int b):输出单个字节
  • output.write(byte[] b):输出一组字节数据
  • output.write(byte[] b,int off,int len):输出一组数据中的部分字节数据
  • 下面是FileOutPutString的使用例子,1.7之后,实现了自动关闭
        File file = new File("D:" + File.separator + "file" + File.separator + "out" + File.separator + "bridge.txt");
        if(!file.getParentFile().exists()){
            file.getParentFile().mkdirs();
        }
        //文件不存在,会自动创建
        String str = "  Hello bridge!";
        try(OutputStream out = new FileOutputStream(file,true)){ //追加的方式,添加数据
            out.write(str.getBytes());
        }catch (IOException e){
            e.printStackTrace();
        }

InputStream

  • 以字节的方式读取数据
  • 是一个抽象类,不能直接实例化,他有众多子类,比如我们常用的FileInputStream
  • 同样的,它也继承了Closeable,但他没有继承Flushable
常用方法
  • public int read();返回一个字节,当返回值为-1时,表示结束(输入的实际内容是null)
  • public int read(byte[] data);一块一块的读取,返回的值是读取的字节的个数,小于data.length时,则表示读完了
  • public int read(byre[],int off, int len);返回真实读取的个数,同上面一样
  • public byte[] readAllBytes() throws IOException;:一次性,读取全部数据,当输入数据特别大的时候,谨慎使用
            File file = new File("D:" + File.separator + "file" + File.separator + "out" + File.separator + "bridge.txt");
                if(!file.exists()){ //如果文件或者目录不存在,提醒用户,目录不存在,这里不会报错
                 System.out.println("没有找到文件");
                    return ;
            }
            //文件不存在,会自动创建
            String str = "  Hello bridge!";
            try(FileInputStream in = new FileInputStream(file)){ //追加的方式,添加数据
                byte[] b = new byte[1024];
                int length = in.read(b);
                System.out.println(new String(b,0, length));
            }catch (IOException e){
                e.printStackTrace();
            }

字符流

使用字符(char)的方式传输数据,输入(Reader)和输出(Writer),字符流是JDK1.1之后才加上的。

Writer

  • 实现了4个接口Closeable, Flushable, AutoCloseable,Appendable。前面3个,上面已经介绍过了
  • Appendable:表示追加的意思,是jdk1.5之后提出来的,可以将字符序列和值追加到之前的对象,在多线下,需要注意线程安全问题
常用方法
  • write​(char[] cbuf):基本的方法和OutputSteam一样,只不过换成了char类型
  • write​(String str):这个比较常用,可以直接存String类型,非常方便

代码

		File file = new File("D:" + File.separator + "hello" + File.separator + "bridge.txt");
		if (!file.getParentFile().exists()) {
			file.getParentFile().mkdirs(); // 父目录必须存在
		}
		Writer out = new FileWriter(file) ; 
		String str = "正常的内容\r\n" ;
		out.write(str); 
		out.append("我要追加内容……") ;	// 追加输出内容
		out.close();

Reader

  • 实现了3个接口Closeable, AutoCloseable, Readable。前2个上面已经介绍了,Readable:表示读取的来源可以通过字符读取
常用方法
  • int read​(char[] cbuf):基本的方法和InputSteam一样,只不过换成了char类型
  • public long transferTo​(Writer out):这个jdk10才有的,目前jdk10普及还不高,可以作为了解

代码

  • 如果不写关闭,数据将会在内存中,并不会保存到文件中
		File file = new File("D:" + File.separator + "hello" + File.separator + "bridge.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()处理,但是建议关闭资源
		File file = new File("D:" + File.separator + "hello" + File.separator + "bridge.txt");
		if (!file.getParentFile().exists()) {
			file.getParentFile().mkdirs(); // 父目录必须存在
		}
		Writer out = new FileWriter(file) ; 
		String str = "追加的内容" ;
		out.write(str); 
		out.flush();  // 强制性刷新

总结

  • 理解上面4个抽象类,之后的子类就很简单了
  • 在处理中文时,字符流比字节流更方便,但是,大部分情况,比如图片、视频传输还是二进制的形式,此时就得使用字节流了
  • 接下来,我们可以了解上面4个抽象类的子类了,他们的子类都有父类的特性,针对不同的场景,使用不同的子类。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值