Java面向对象系列[v1.0.0][字节流和字符流]

阅读: 评论:0

Java面向对象系列[v1.0.0][字节流和字符流]

Java面向对象系列[v1.0.0][字节流和字符流]

字节流和字符流

InputStream和Reader

InputStream和Reader是所有输入流的抽象基类,虽然本身并不能创建实例来完成输入,但他们的方法是所有输入流都可以使用的方法
InputStream里包含三个方法:

  • int read(): 从输入流中读取单个字节,返回所读取的字节数据(字节数据可直接转换为int类型)
  • int read(byte[] b):从输入流中最多读取b.length个字节的数据,并将其存储在字节数组b中,返回实际读取的字节数
  • int read(byte[] b, int off, int len):从输入流中最多读取len个字节的数据,并将其存储在数组b中,放入数组b中时,并不是从数组起点开始,而是从off位置开始,返回实际读取的字节数

Reader里包含如下三个方法:

  • int read():从输入流中读取单个字符,返回所读取的字符数据(字符数据可直接转换为int类型)
  • int read(char[] cbuf):从输入流中最多读取cbuf.length个字符的数据,并将其存储在字符数组cbuf中,返回实际读取的字符数
  • int read(char[] cbuf, int off, int len):从输入流中最多读取len个字符的数据,并将其存储在字符数组cbuf中,放入数组cbuf中时,并不是从数组起点开始,而是从off位置开始,返回实际读取的字符数
    不难看出二者非常相似,只是处理的数据类型不一样,虽然本身不能创建实例,但他们分别有一个用于读取文件的输入流:FileInputStream和FileReader,这两个都是节点流直接和指定文件关联
import java.io.*;public class FileInputStreamTest
{public static void main(String[] args) throws IOException{// 创建字节输入流var fis = new FileInputStream("FileInputStreamTest.java");// 创建一个长度为1024的数组var bbuf = new byte[16];// 用于保存实际读取的字节数var hasRead = 0;// 使用循环来完成重复取得过程while ((hasRead = ad(bbuf)) > 0){// 取出字节,将字节数组转换成字符串输入!System.out.print(new String(bbuf, 0, hasRead));}// 程序里打开的文件IO资源不属于内存里的资源,垃圾回收无法回收该资源,必须显示关闭IO资源// 关闭文件输入流,放在finally块里更安全fis.close();}
}

执行结果:

import java.io.*;public class FileInputStreamTest
{public static void main(String[] args) throws IOException{// 创建字节输入流var fis = new FileInputStream("FileInputStreamTest.java");// 创建一个长度为1024的“竹筒”var bbuf = new byte[16];// 用于保存实际?寥〉淖纸谑?var hasRead = 0;// 使用循环来重复“取水”过程while ((hasRead = ad(bbuf)) > 0){// 取出“竹?病敝兴危ㄗ纸冢纸谑樽怀勺址淙耄?System.out.print(new String(bbuf, 0, hasRead));}// ?乇瘴募淙肓鳎旁趂inally块里更安全fis.close();}
}

在执行结果中看到乱码的原因是文件保存的时候采用GBK的编码方式,每个中文字符占两个字节,如果read()方法读取时候,整好读了这两个字节的第一个字节就结束了,那等于读了半个中文字符,就会导致乱码,把数组长度放大即可解决这个问题

import java.io.*;public class FileReaderTest
{public static void main(String[] args){try (// 创建字符输入流var fr = new FileReader("FileReaderTest.java")){// 创建一个长度为32的“竹筒”var cbuf = new char[32];// 用于保存实际读取的字符数var hasRead = 0;// 使用循环来重复“取水”过程while ((hasRead = fr.read(cbuf)) > 0){// 取出“竹筒”中水滴(字符),将字符数组转换成字符串输入!System.out.print(new String(cbuf, 0, hasRead));}}catch (IOException ex){ex.printStackTrace();}}
}

Java7之后改了了所有IO资源类,都实现了AutoCloseable接口,因此都可以通过自动关闭资源的try语句来关闭这些IO流
此外,InputStream和Reader还支持移动记录指针:

  • void mark(int readAheadLimit):在记录指针当前位置记录一个标记(mark)
  • boolean markSupported():判断此输入流是否支持mark()操作,也就是是否支持记录标记
  • boid reset():将此流的记录指针重新定位到上一次记录标记(mark)的位置
  • long skip(long n):记录指针向前移动n个字节/字符

OutputStream和Writer

OutputStream和Writer两个流都提供了如下三个方法:

  • void write(int c): 将指定的字节/字符输出到输出流中,其中c既可以代表字节也可以代表字符
  • void write(byte[]/char[] buf):将字节数组/字符数组中的数据输出到指定的输出流中
  • void write(byte[]/char[] buf, int off, int len):将字节数组/字符数组中从off位置开始长度为len的字节/字符输出到输出流中

字符流以字符作为操作单位,所以Writer可以用字符串来代替字符数组,即以String对象作为参数,它还有两个独有的方法:

  • void write(String str): 将str字符串里包含的字符输出到指定输出流中
  • void write(String str, int off, int len):将str字符串里从off位置开始,长度为len的字符输出到指定输出流中
import java.io.*;public class FileOutputStreamTest
{public static void main(String[] args){try (// 创建字节输入流var fis = new FileInputStream("FileOutputStreamTest.java");// 创建字节输出流var fos = new FileOutputStream(&#")){var bbuf = new byte[32];var hasRead = 0;// 循环从输入流中取出数据while ((hasRead = ad(bbuf)) > 0){// 每读取一次,即写入文件输出流,读了多少,就写多少。fos.write(bbuf, 0, hasRead);}}catch (IOException ioe){ioe.printStackTrace();}}
}
import java.io.*;public class FileWriterTest
{public static void main(String[] args){try (var fw = new FileWriter(&#")){fw.write("锦瑟 - 李商隐rn");fw.write("锦瑟无端五十弦,一弦一柱思华年。rn");fw.write("庄生晓梦迷蝴蝶,望帝春心托杜鹃。rn");fw.write("沧海月明珠有泪,蓝田日暖玉生烟。rn");fw.write("此情可待成追忆,只是当时已惘然。rn");}catch (IOException ioe){ioe.printStackTrace();}}
}

使用Java的IO流执行输出时,不能忘记关闭输出流,关闭输出流可以保证流的物理资源被回收的同时还可以将输出流缓冲区中的数据flush到物理节点里

本文发布于:2024-02-01 23:54:31,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170680838239980.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:字节   面向对象   字符   系列   Java
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23