【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();//一定要关闭流
}
运行结果(随便一个文件来测试的):
注意:
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


猜你喜欢
- 在工作中,如果需要跟XML打交道,难免会遇到需要把一个类型集合转换成XML格式的情况。之前的方法比较笨拙,需要给不同的类型,各自写一个转换的
- 在spring Boot中,有些代码是WEB功能,例如API等,但是有些逻辑是非WEB,启动时就要调用并持续运行的,该如何加载自己的非WEB
- MD5加密在我们的程序中,不管是什么,都会有安全问题,今天就说的是MD5加密的方法MD5是哈希算法,也就是 从明文A到密文B很容易,但是从密
- 简单工厂简单工厂模式是属于创建型模式,是工厂模式的一种。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。定义了一个创建对象的类,由
- Wrapper条件构造器updateForSet更新官方文档:https://baomidou.gitee.io/mybatis-plus-
- 一:什么是协变与逆变协变指能够使用比原始指定的派生类型的派生程度更大(更具体的)的类型,逆变指能够使用比原始指定的派生类型的派生程度更小(不
- package com.example.myapi.email;import java.util.ArrayList;import java
- 这篇文章主要介绍了JDK线程池和Spring线程池的使用实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值
- 前言最近,新来的同事写接口,需要知道lua怎么调用C#脚本,趁这个机会也给大家分享一下。道理我也不多少,直接上干货。框架介绍本项目采用lua
- Java8的groupingBy实现集合的分组,类似Mysql的group by分组功能,注意得到的是一个map对集合按照单个属性分组、分组
- JDK1.7以及以前:接口(interface)在JDK7及之前的版本对接口的要求:接口定义:使用 interface 关键字 。接口中的
- 1. 准备工作首先我们创建一个 Spring Boot 工程,引入 Web 和 Redis 依赖,同时考虑到接口限流一般是通过注解来标记,而
- 前言这几天专门研究了下JNI编程,在网上找了好多资料,不过好多都是以前的,没有更新,而且有的还是错误的,让人不得不吐槽一把。所以觉得自己来一
- 一、SpringMVC使用1.工程创建创建maven工程。添加java、resources目录。引入Spring-webmvc 依赖。<
- 前言:仿微信通讯录搜索功能,通过汉字或拼音首字母找到匹配的联系人并显示匹配的位置一:先看效果图字母索引搜索匹配二:功能分析1:汉字转拼音通讯
- 本文实例为大家分享了Java操作qq邮箱发送邮件的具体代码,供大家参考,具体内容如下今天尝试了使用QQ邮箱的POP3/IMAP/SMTP/E
- 对于Android View的测量,我们一句话总结为:
- 一、前沿如果你学习过其他的编程语言,你就会发现 Java 的语法很是哆嗦,可是我们为什么没有放弃 Java 这门编程语言呢?因为 JVM 是
- 如今,企业级应用程序的常见场景是同时支持HTTP和HTTPS两种协议,这篇文章考虑如何让Spring Boot应用程序同时支持HTTP和HT
- 先看看代码再说:package com.b510.note; import java.math.BigInteger;