【Java IO流】字节流和字符流的实例讲解

作者:云开的立夏 时间:2023-08-08 20:45:58 

字节流和字符流

对于文件必然有读和写的操作,读和写就对应了输入和输出流,流又分成字节和字符流。

1.从对文件的操作来讲,有读和写的操作——也就是输入和输出。

2.从流的流向来讲,有输入和输出之分。

3.从流的内容来讲,有字节和字符之分。

这篇文章先后讲解IO流中的字节流和字符流的输入和输出操作。

一、字节流

1)输入和输出流

首先,字节流要进行读和写,也就是输入和输出,所以它有两个抽象的父类InputStream、OutputStream。

InputStream抽象了应用程序读取数据的方式,即输入流。
OutputStream抽象了应用程序写出数据的方式,即输出流。

2)读写结束

在字节流中当读写结束,达到文件结尾时,称为EOF = End或者读到-1就读到结尾。

3)输入流基本方法

首先我们要清楚输入流是什么。比如通过我们的键盘在文本文件上输入内容,这个过程键盘充当的就是输入流,而不是输出流。因为键盘的功能是将内容输入到系统,系统再写入到文件上。以下是输入流的基本方法read():


int b = in.read(); //读取一个字节无符号填充到int低八位。-1是EOF。
in.read(byte[] buf); //读取数据填充到字节数组buf中。返回的是读到的字节个数。
in.read(byte[] buf,int start, int size)//读取数据到字节数组buf从buf的start位置开始存放size长度分数据

其中in是InputStream抽象类的实例,可以发现这个方法和RandomAccessFile类中的read()方法差不多,因为两者都是通过字节来读取的。

4)输出流基本方法

输出流是进行写的操作,其基本操作方法是write(),可以将此方法与输入read()方法一 一去对应,更好理解。


out.write(int b)//写出一个byte到流,b的低8位
out.write(byte[] buf)//将buf字节数组都写到流
out.write(byte[] buf, int start,int size) //字节数组buf从start位置开始写size长度的字节到流

了解了InputStream、OutputStream的基本操作方法后,再来看看它们两个的“孩子”FileInputStream和FileOutputStream。

这两个子类具体实现了在文件上读取和写入数据的操作,日程编程中更多的是使用这两个类。

二、FileInputStream和FileOutputStream类的使用

-----------------FileInputStream类的使用

1.使用read()方法读取文件


/**
 * 读取指定文件内容,按照16进制输出到控制台
 * 并且每输出10个byte换行
 * @throws FileNotFoundException
 */
public static void printHex(String fileName) throws IOException{
 //把文件作为字节流进行读操作
 FileInputStream in=new FileInputStream(fileName);
 int b;
 int count=0;//计数读到的个数
 while((b=in.read())!=-1){
  if(b<=0xf){
   //单位数前面补0
   System.out.println("0");
  }
  System.out.print(Integer.toHexString(b& 0xff)+" ");
  if(++count%10==0){
   System.out.println();
  }
 }
 in.close();//一定要关闭流
}

运行结果(随便一个文件来测试的):

【Java IO流】字节流和字符流的实例讲解

注意:

FileInputStream()构造函数可以通过文件名(String)也可以通过File对象。上面的案例是使用文件名来构造的。

(b=in.read())!=-1 通过读到-1来判断是否读到文件结尾。

in.close() 使用完IO流的对象一定要关闭流,养成好习惯很重要。

2.使用read(byte[] buf,int start, int size)方法读取文件

上述方法只能一个一个字节读取,对于较大的文件效率太低,推荐使用这个方法来一次性读取文件。


public static void printHexByBytes(String fileName) throws IOException{
 FileInputStream in=new FileInputStream(fileName);
 byte[] buf=new byte[20*1024];//开辟一个20k大小的字节数组
 /*
  * 从in中批量读取字节,放入到buf这个字节数组中
  * 从第0个位置开始放,最多放buf.length个
  * 返回的是读到的字节个数
  */
 //一次性读完的情况
 int count=in.read(buf, 0, buf.length);
 int j=1;
 for(int i=0;i<count;i++){
  if((buf[i]&0xff)<=0xf){
   //单位数前面补0
   System.out.print("0");
  }
  System.out.print(Integer.toHexString(buf[i]&0xff)+ " ");
  if(j++%10==0){
   System.out.println();
  }
 }
   in.close();
}
}

read(byte[] buf,int start, int size)返回的是读到的字节个数,即buf字节数组的有效长度,所以输出buf数组时用的长度是count而不是buf.length,因为我们不知道文件大小和数组大小的关系,上述方法适用于文件大小不超过数组大小的情况下,一次性把文件内容读取到数组里,这里就有一个问题了,如果文件大小超过数组大小,那又该如何读取才能把文件全部读完呢??

我们知道读到-1就是读到文件末,所以还是利用while循环重复读取直到读到-1结束循环,把上述代码修改后如下:


public static void printHexByBytes(String fileName) throws IOException{
 FileInputStream in=new FileInputStream(fileName);
 byte[] buf=new byte[20*1024];//开辟一个20k大小的字节数组
 /*
  * 从in中批量读取字节,放入到buf这个字节数组中
  * 从第0个位置开始放,最多放buf.length个
  * 返回的是读到的字节个数
  */
 int j=1;
 //一个字节数组读不完的情况,用while循环重复利用此数组直到读到文件末=-1
 int b=0;
 while((b=in.read(buf, 0, buf.length))!=-1){
  for(int i=0;i<b;i++){
   if((buf[i]&0xff)<=0xf){
    //单位数前面补0
    System.out.print("0");
   }
   System.out.print(Integer.toHexString(buf[i]&0xff)+ " ");
   if(j++%10==0){
    System.out.println();
   }
  }
 }
 in.close();
}
}

来源:http://www.cnblogs.com/hysum/archive/2017/09/14/7225762.html

标签:字符流,字节流,java
0
投稿

猜你喜欢

  • C#控制台进行文件读写的方法

    2022-02-13 22:03:27
  • C# log4net日志库的用法小结

    2023-12-26 18:50:44
  • Json字符串与Object、List、Map的互转工具类

    2023-04-30 16:08:16
  • Android使用AutoCompleteTextView实现自动填充功能的案例

    2023-03-26 06:56:47
  • SpringBoot整合Elasticsearch并实现CRUD操作

    2021-10-28 07:27:31
  • Unity实现3D循环滚动效果

    2023-04-22 14:05:47
  • 一篇文章让你弄懂Java运算符

    2023-12-02 20:16:41
  • SpringBoot实现过滤器、拦截器与切片的实现和区别

    2023-04-28 22:51:04
  • Android ViewPager实现图片轮播效果

    2023-03-20 17:00:58
  • C#中的程序集和反射介绍

    2021-09-22 12:17:51
  • Java中初始化List集合的八种方式汇总

    2021-09-20 22:31:54
  • Java中的vector类使用示例小结

    2023-09-01 02:46:59
  • Java语言实现数据结构栈代码详解

    2021-12-09 16:15:05
  • C#实现添加多行文本水印到Word文档

    2023-03-22 07:45:33
  • Jetpack Compose图片组件使用实例详细讲解

    2021-06-09 08:15:24
  • Android图像切换器imageSwitcher的实例应用

    2023-10-06 00:30:56
  • Java ArrayDeque使用方法详解

    2022-02-09 08:00:23
  • java简单实现斗地主发牌功能

    2023-06-18 16:22:44
  • C#实现一键清空控件值的示例代码

    2021-11-12 12:10:15
  • C# 站点IP访问频率限制 针对单个站点的实现方法

    2023-09-23 18:35:30
  • asp之家 软件编程 m.aspxhome.com