目录
代码: FileWriter类的测试: write('a'),write(cArr,1,3), write(cArr), flush, close
代码: FileReader类的测试: res = fr.read(), fr.read(cArr,1,3), fr.read(cArr)
代码: FileReader和FileWriter实现文本文件的拷贝:
代码: FileInputStream和FileOutputStream实现图片视频文件的拷贝, available
17.4.5 BufferedOutputStream类(重点)
17.4.6 BufferedInputStream类(重点)
代码: 缓冲字节流BufferedInputStream和BufferedOutputStream的使用:
代码: 缓冲字符流BufferedReader和BufferedWriter的使用
代码: 打印字符流PrintStream,PrintWriter,和转换流InputStreamReader, OutputStreamWriter的使用
17.4.16 ObjectOutputStream类(重点)
17.4.17 ObjectInputStream类(重点)
代码: ObjectOutputStream, ObjectInputStream的测试,transient关键字
&&&&&总结&&&&&
1, IO流
概念, 分类, 体系结构, 相关类的详解
第十七章 IO流
17.1 IO流的概念
IO就是Input和Output的简写,也就是输入和输出的含义。
IO流就是指读写数据时像流水一样从一端流到另外一端,因此得名为“流"。
17.2 基本分类
按照读写数据的基本单位不同,分为 字节流 和 字符流。 其中字节流主要指以字节为单位进行数据读写的流,可以读写任意类型的文件。 其中字符流主要指以字符(2个字节)为单位进行数据读写的流,只能读写文本文件。
按照读写数据的方向不同,分为 输入流 和 输出流(站在程序的角度)。 其中输入流主要指从文件中读取数据内容输入到程序中,也就是读文件。 其中输出流主要指将程序中的数据内容输出到文件中,也就是写文件。
按照流的角色不同分为节点流和处理流。 其中节点流主要指直接和输入输出源对接的流。 其中处理流主要指需要建立在节点流的基础之上的流。
17.3 体系结构
17.4 相关流的详解
17.4.1 FileWriter类(重点)
(1)基本概念
java.io.FileWriter类主要用于将文本内容写入到文本文件。
(2)常用的方法
代码: FileWriter类的测试: write('a'),write(cArr,1,3), write(cArr), flush, close
package com.lagou.task17;
import java.io.FileWriter;
import java.io.IOException;
/**
* @author CH
* @date 2020/10/11 14:29
*/
public class FileWriterTest {
public static void main(String[] args) {
//选中代码后, 可以使用ctrl+alt+t来生成异常的捕获代码等
FileWriter fw = null;
try {
//1.//构造FileWrite类型的对象与d:/a.txt文件关联
//若问价不存在, 该流会自动创建新文件
//若文件存在, 则该流会清空文件中的原有内容
fw = new FileWriter("d:/a.txt");
//下面以追加的方式创建对象去关联文件
//若文件不存在则自动创建新文件
//若文件存在,则保留原有数据内容
//fw = new FileWriter("d:/a.txt",true);
//2.//通过流对象写入数据内容 每当写入一个字符后, 则文件中的读写位置, 向后移动一位
fw.write('a');
//准备一个字符数组,
char[] cArr = new char[]{'h', 'e', 'l', 'l', 'o'};
//将字符数组中的一部分内容写入进去
fw.write(cArr,1,3); //ell
//将整个字符数组写进去
fw.write(cArr); //hello
fw.flush();
System.out.println("写入数据成功!");
} catch (IOException e) {
e.printStackTrace();
} finally {
//close代码放到finally里面
//3.//关闭流对象, 并释放有关的资源
if(null != fw) {
try {
fw.close(); //fw可能是空指针,因此要处理
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
17.4.2 FileReader类(重点)
(1)基本概念
java.io.FileReader类主要用于从文本文件读取文本数据内容。
(2)常用的方法
代码: FileReader类的测试: res = fr.read(), fr.read(cArr,1,3), fr.read(cArr)
package com.lagou.task17;
import java.io.FileReader;
import java.io.IOException;
/**
* @author CH
* @date 2020/10/11 16:01
*/
public class FileReaderTest {
public static void main(String[] args) {
FileReader fr = null;
try {
//1.//构造FileReader类型的对象与d:/a.txt文件关联
//fr = new FileReader("d:/a.txt");
fr = new FileReader("d:/b.txt"); //测试行分隔符用
//2.//读取数据内容并打印
/*
int res = fr.read();
System.out.println("读取到的单个字符是: " + (char)res); // 'a'
*/
int res = 0;
while(-1 != (res=fr.read())) {
System.out.println("读取到的单个字符是: " + (char)res + "对应的ASCII码是: " + res);
}
//4.//准备一个字符数组, 保存读取到的数据内容
// char[] cArr = new char[5];
//期望读满字符中的一部分空间, 也就是读取3个字符放入数组cArr中下标从1开始的位置上
/*int res = fr.read(cArr,1,3); //3
System.out.println("实际读取到的字符个数是: " + res);
for (char cv : cArr) {
System.out.println("读取到的单个字符是: " + cv); // 啥也没有 a e l 啥也没有
}*/
//期望读满整个字符数组
/*int res = fr.read(cArr); //5
System.out.println("实际读取到的字符个数是: " + res); //5
for (char cv : cArr) {
System.out.println("读取到的单个字符是: " + cv); // a e l l h
}*/
} catch (IOException e) {
e.printStackTrace();
} finally {
//3.//关闭流对象并释放有关的资源
if(null != fr) {
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
代码: FileReader和FileWriter实现文本文件的拷贝:
package com.lagou.task17;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
/**
* @author CH
* @date 2020/10/11 16:35
*/
public class FileCharCopyTest {
public static void main(String[] args) {
long g1 = System.currentTimeMillis();
FileReader fr = null;
FileWriter fw = null;
try {
//1.//创建FileReader类型的对象, 与d:/a.txt文件关联
fr = new FileReader("d:/a.txt");
//fr = new FileReader("d:/03 IO流的框架图.png");
//2.//创建FileWriter类型的对象, 与d:/b.txt文件关联
fw = new FileWriter("d:/b.txt");
//fw = new FileWriter("d:/IO流的框架图.png"); //拷贝图片文件失败!!!
//3.//不断地从输入流中读取数据内容写入到输出流中
System.out.println("正在玩命拷贝...");
int res = 0;
while(-1 != (res = fr.read())) {
fw.write(res);
}
System.out.println("拷贝文件成功!");
} catch (IOException e) {
e.printStackTrace();
} finally {
//4.//关闭流对象并释放有关的资源 先开的后关,后开的先关
if(null != fw) {
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(null != fr) {
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
long g2 = System.currentTimeMillis();
System.out.println("共花费时间: " + (g2 - g1));
}
}
17.4.3 FileOutputStream类(重点)
(1)基本概念
java.io.FileOutputStream类主要用于将图像数据之类的原始字节流写入到输出流中。
(2)常用的方法
17.4.4 FileInputStream类(重点)
(1)基本概念
java.io.FileInputStream类主要用于从输入流中以字节流的方式读取图像数据等。
(2)常用的方法
案例题目 编程实现两个文件之间的拷贝功能。
代码: FileInputStream和FileOutputStream实现图片视频文件的拷贝, available
package com.lagou.task17;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* @author CH
* @date 2020/10/11 17:03
*/
public class FileByteCopyTest {
public static void main(String[] args) {
//获取当前系统时间距离1970 1 1 00 00 00 的毫秒数
long g1 = System.currentTimeMillis();
FileInputStream fis = null;
FileOutputStream fos = null;
try {
//1.//创建FileInputStream类型的对象, 与 d:/03 IO流的框架图.png 文件关联
//fis = new FileInputStream("d:/03 IO流的框架图.png");
fis = new FileInputStream("d:/演示视频.mp4");
//2.//创建FileOutputStream类型的对象与 d:/IO流的框架图.png 文件关联
//fos = new FileOutputStream("d:/IO流的框架图.png");
fos = new FileOutputStream("d:/演示视频(副本).mp4");
//3.//不断地从输入流中读取数据内容并写入到输出流中'
System.out.println("正在玩命地拷贝...");
//方式一: 以单个字节为单位进行拷贝, 也就是每次读取一个字节后, 再写入一个字节
//缺点: 文件稍大时, 拷贝的效率很低
/*int res = 0;
while((res = fis.read()) != -1) {
fos.write(res);
}*/
//方式二: 准备一个和文件一样大小的缓冲区, 一次性将文件中的所有内容取出放到缓冲区然后一次性写入
//缺点: 占用内存
/*int len = fis.available();
System.out.println("获取到的文件大小是: " + len);
byte[] bArr = new byte[len];
int res = fis.read(bArr);
System.out.println("实际读取到的文件大小是: " + res);
fos.write(bArr);*/
//方式三: 准备一个相对适当的缓冲区, 分多次将文件拷贝完成
byte[] bArr = new byte[1024];
int res = 0;
while ((res = fis.read(bArr)) != -1) { //这边字节数组读取的返回值是读取到多少个字节
fos.write(bArr,0, res); //这边是指从下标0到读取到字节数的数据写进fos对象文件
}
System.out.println("拷贝文件成功!");
} catch (IOException e) {
e.printStackTrace();
} finally {
//4.//关闭流对象并释放有关的资源
if(null != fos) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (null != fis) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
long g2 = System.currentTimeMillis();
System.out.println("使用文件流拷贝视频文件消耗的时间为: " + (g2 - g1)); //83
}
}
17.4.5 BufferedOutputStream类(重点)
(1)基本概念
java.io.BufferedOutputStream类主要用于描述缓冲输出流,此时不用为写入的每个字节调用底层 系统。
(2)常用的方法
17.4.6 BufferedInputStream类(重点)
(1)基本概念
java.io.BufferedInputStream类主要用于描述缓冲输入流。
(2)常用的方法
代码: 缓冲字节流BufferedInputStream和BufferedOutputStream的使用:
package com.lagou.task17;
import java.io.*;
/**
* @author CH
* @date 2020/10/12 11:45
*/
public class BufferedByteTest {
public static void main(String[] args) {
//获取当前系统时间距离1970 1 1 00 00 00 的毫秒数
long g1 = System.currentTimeMillis();
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
//1.//创建BufferedInputStream类型的对象与d:/演示视频.mp4文件关联
bis = new BufferedInputStream(new FileInputStream("d:/演示视频.mp4"));
//2.//创建BufferedOutputStream类型的对象与d:/演示视频(副本).mp4关联
bos = new BufferedOutputStream(new FileOutputStream("d:/演示视频(副本).mp4"));
//3.//不断地从输入流中读取数据并写入到输出流中
System.out.println("正在玩命地拷贝...");
byte[] bArr = new byte[1024];
int res = 0;
while ((res = bis.read(bArr)) != -1) { //这边字节数组读取的返回值是读取到多少个字节
bos.write(bArr,0, res); //这边是指从下标0到读取到字节数的数据写进fos对象文件
}
System.out.println("拷贝文件成功!");
} catch (IOException e) {
e.printStackTrace();
} finally {
//4.//关闭流对象并释放有关的资源
if(null != bos) {
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(null != bis) {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
long g2 = System.currentTimeMillis();
System.out.println("使用缓冲区拷贝视频文件消耗的时间为: " + (g2 - g1)); //25
}
}
17.4.7 BufferedWriter类(重点)
(1)基本概念
java.io.BufferedWriter类主要用于写入单个字符、字符数组以及字符串到输出流中。
(2)常用的方法
17.4.8 BufferedReader类(重点)
(1)基本概念
java.io.BufferedReader类用于从输入流中读取单个字符、字符数组以及字符串。
(2)常用的方法
代码: 缓冲字符流BufferedReader和BufferedWriter的使用
package com.lagou.task17;
import java.io.*;
/**
* @author CH
* @date 2020/10/12 16:19
*/
public class BufferedCharCopyTest {
public static void main(String[] args) {
long g1 = System.currentTimeMillis();
BufferedReader br = null;
BufferedWriter bw = null;
try {
//1.//创建BufferedReader类型的对象,与d:/a.txt文件关联
br = new BufferedReader(new FileReader("d:/a.txt"));
//2.//创建BufferedWriter类型的对象,与d:/b.txt文件关联
bw = new BufferedWriter(new FileWriter("d:/b.txt"));
//3.//不断地读取一行字符串并写入到输入流中
System.out.println("正在玩命地拷贝...");
String str = null;
while((str = br.readLine()) != null) {
bw.write(str);
bw.newLine(); //当前系统中的行分割符是\n\r
}
System.out.println("拷贝文件成功!");
} catch (IOException e) {
e.printStackTrace();
} finally {
//4.//关闭流对象并释放有关的资源
try {
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
long g2 = System.currentTimeMillis();
System.out.println("共花费时间: " + (g2 - g1));
}
}
17.4.9 PrintStream类
(1)基本概念
java.io.PrintStream类主要用于更加方便地打印各种数据内容。
(2)常用的方法
17.4.10 PrintWriter类
(1)基本概念
java.io.PrintWriter类主要用于将对象的格式化形式打印到文本输出流。
(2)常用的方法
案例题目
不断地提示用户输入要发送的内容,若发送的内容是"bye"则聊天结束,否则将用户输入的内容写 入到文件d:/a.txt中。 要求使用BufferedReader类来读取键盘的输入 System.in代表键盘输入 要求使用PrintStream类负责将数据写入文件
17.4.11 OutputStreamWriter类
(1)基本概念
java.io.OutputStreamWriter类主要用于实现从字符流到字节流的转换。
(2)常用的方法
17.4.12 InputStreamReader类
(1)基本概念
java.io.InputStreamReader类主要用于实现从字节流到字符流的转换。
(2)常用的方法
代码: 打印字符流PrintStream,PrintWriter,和转换流InputStreamReader, OutputStreamWriter的使用
package com.lagou.task17;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @author CH
* @date 2020/10/12 16:43
*/
public class PrintStreamChatTest {
public static void main(String[] args) {
BufferedReader br = null;
PrintStream ps = null;
try {
//由手册可知: 构造方法需要的是Reader类型的引用, 但Reader类是个抽象类, 实参只能传递子类的对象 字符流
//由手册可知: System.in代表键盘输入, 而且是InputStream类型的 字节流
br = new BufferedReader(new InputStreamReader(System.in));
ps = new PrintStream(new FileOutputStream("d:/a.txt",true));
//ps = new PrintStream(new FileOutputStream("d:/a.txt"));
Date d1 = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//声明一个boolean类型的变量作为发送方的代表
boolean flag = true;
while(true) {
//1.//提示用户输入要发送的内容并使用变量记录
System.out.println("请"+ (flag? "张三" : "李四") + "输入要发送的聊天内容: ");
String str = br.readLine();
//2.//判断用户输入的内容是否为"bye",是, 则聊天结束
if ("bye".equals(str)) {
System.out.println("聊天结束!");
break;
}
//3.//若不是则将用户输入的内容写入到文件d:/a.txt中
//else {
//获取当前系统的时间并调整格式
ps.println( sdf.format(d1) + (flag? " 张三说: " : " 李四说: ") + str);
//}
flag = !flag;
}
ps.println(); //写入空行 与之前的聊天记录隔开
ps.println();
ps.println(sdf.format(d1)+ "开始的聊天记录 ↓");
} catch (IOException e) {
e.printStackTrace();
} finally {
//4.//关闭流对象并释放有关的资源
if (null != ps) {
ps.close();
}
if(null != br) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
17.4.13 字符编码
(1)编码表的由来
计算机只能识别二进制数据,早期就是电信号。为了方便计算机可以识别各个国家的文字,就需要 将各个国家的文字采用数字编号的方式进行描述并建立对应的关系表,该表就叫做编码表。
(2)常见的编码表
ASCII:美国标准信息交换码, 使用一个字节的低7位二位进制进行表示。
ISO8859-1:拉丁码表,欧洲码表,使用一个字节的8位二进制进行表示。
GB2312:中国的中文编码表,最多使用两个字节16位二进制为进行表示。
GBK:中国的中文编码表升级,融合了更多的中文文字符号,最多使用两个字节16位二进制位表 示。
Unicode:国际标准码,融合了目前人类使用的所有字符,为每个字符分配唯一的字符码。所有的 文字都用两个字节16位二进制位来表示。
(3)编码的发展
面向传输的众多 UTF(UCS Transfer Format)标准出现了,UTF-8就是每次8个位传输数据,而 UTF-16就是每次16个位。这是为传输而设计的编码并使编码无国界,这样就可以显示全世界上所 有文化的字符了。
Unicode只是定义了一个庞大的、全球通用的字符集,并为每个字符规定了唯一确定的编号,具体 存储成什么样的字节流,取决于字符编码方案。推荐的Unicode编码是UTF-8和UTF-16。
UTF-8:变长的编码方式,可用1-4个字节来表示一个字符。
17.4.14 DataOutputStream类(了解)
(1)基本概念
java.io.DataOutputStream类主要用于以适当的方式将基本数据类型写入输出流中。
(2)常用的方法
代码: DataOutputStream的测试:
package com.lagou.task17;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* @author CH
* @date 2020/10/12 18:02
*/
public class DataOutputStreamTest {
public static void main(String[] args) {
DataOutputStream dos = null;
try {
//1.//创建DataOutputStream类型的对象与d:/a.txt文件关联
dos = new DataOutputStream(new FileOutputStream("d:/a.txt"));
//2.//准备一个整数数据66并写入输入流
// 66: 0000 0000 ... 0100 0010 => B
int num = 66;
//dos.writeInt(num); //写入4个字节
dos.write(num); //写入1个字节
System.out.println("写入数据成功!");
} catch (IOException e) {
e.printStackTrace();
} finally {
//3.//关闭流对象并释放有关的资源
if(null != dos) {
try {
dos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
17.4.15 DataInputStream类(了解)
(1)基本概念
java.io.DataInputStream类主要用于从输入流中读取基本数据类型的数据。
(2)常用的方法
代码: DataInputStream的测试:
package com.lagou.task17;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;
/**
* @author CH
* @date 2020/10/12 18:13
*/
public class DataInputStreamTest {
public static void main(String[] args) {
DataInputStream dis = null;
try {
//1.//创建DataInputStream类型的对象与d:/a.txt文件关联
dis = new DataInputStream(new FileInputStream("d:/a.txt"));
//2.//从输入流中读取一个整数并打印
//int res = dis.readInt(); //读取4个字节
int res = dis.read(); //读取1个字节
System.out.println("读取到的数据是: " + res);
} catch (IOException e) {
e.printStackTrace();
} finally {
//3.//关闭流对象并释放有关的资源
if(null != dis) {
try {
dis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
17.4.16 ObjectOutputStream类(重点)
(1)基本概念
java.io.ObjectOutputStream类主要用于将一个对象的所有内容整体写入到输出流中。
只能将支持 java.io.Serializable 接口的对象写入流中。
类通过实现 java.io.Serializable 接口以启用其序列化功能。
所谓序列化主要指将一个对象需要存储的相关信息有效组织成字节序列的转化过程。
(2)常用的方法
17.4.17 ObjectInputStream类(重点)
(1)基本概念
java.io.ObjectInputStream类主要用于从输入流中一次性将对象整体读取出来。
所谓反序列化主要指将有效组织的字节序列恢复为一个对象及相关信息的转化过程。
(2)常用的方法
(3)序列化版本号
序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的。在进行反序列化时, JVM会把传来的字节流中的serialVersionUID与本地相应实体类的serialVersionUID进行比较,如 果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常 (InvalidCastException)。
(4)transient关键字
transient是Java语言的关键字,用来表示一个域不是该对象串行化的一部分。当一个对象被串行 化的时候,transient型变量的值不包括在串行化的表示中,然而非transient型的变量是被包括进 去的。
(5)经验的分享
当希望将多个对象写入文件时,通常建议将多个对象放入一个集合中,然后将集合这个整体看做一 个对象写入输出流中,此时只需要调用一次readObject方法就可以将整个集合的数据读取出来, 从而避免了通过返回值进行是否达到文件末尾的判断。
代码: ObjectOutputStream, ObjectInputStream的测试,transient关键字
package com.lagou.task17;
/**
* @author CH
* @date 2020/10/12 18:50
*/
public class User implements java.io.Serializable {
private static final long serialVersionUID = -3543126975751553657L;
private String userName;
private String password;
private transient String phoneNum; //该成员变量不参与序列化操作
public User(String userName, String password, String phoneNum) {
this.userName = userName;
this.password = password;
this.phoneNum = phoneNum;
}
public User() {
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getPhoneNum() {
return phoneNum;
}
public void setPhoneNum(String phoneNum) {
this.phoneNum = phoneNum;
}
@Override
public String toString() {
return "User{" +
"userName='" + userName + '\'' +
", password='" + password + '\'' +
", phoneNum='" + phoneNum + '\'' +
'}';
}
}
package com.lagou.task17;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
/**
* @author CH
* @date 2020/10/12 18:51
*/
public class ObjectOutputStreamTest {
public static void main(String[] args) {
ObjectOutputStream oos = null;
try {
//1.//创建ObjectOutputStream类型的对象与d:/a.txt文件关联
oos = new ObjectOutputStream(new FileOutputStream("d:/a.txt"));
//2.//准备一个User类型的对象并初始化
User user = new User("qidian", "123456", "13511823876");
//3.//将整个User类型的对象写入输入流
oos.writeObject(user);
System.out.println("写入对象成功!");
} catch (IOException e) {
e.printStackTrace();
} finally {
//4.//关闭流对象并释放有关的资源
if(null != oos) {
try {
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
package com.lagou.task17;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
/**
* @author CH
* @date 2020/10/12 19:10
*/
public class ObjectInputStreamTest {
public static void main(String[] args) {
ObjectInputStream ois = null;
try {
//1.//创建ObjectInputStream类型的对象与d:/a.txt文件关联
ois = new ObjectInputStream(new FileInputStream("d:/a.txt"));
//2.//从输入流中读取一个对象并打印
Object o = ois.readObject();
System.out.println("读取到的对象是: " + o); //手机号取消序列化 qidian 123456 null
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
//3.//关闭流对象并释放有关的资源
if (null != ois) {
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
17.4.18 RandomAccessFile类
(1)基本概念
java.io.RandomAccessFile类主要支持对随机访问文件的读写操作。
(2)常用的方法
代码: RandomAccessFile类的测试:
package com.lagou.task17;
import java.io.IOException;
import java.io.RandomAccessFile;
/**
* @author CH
* @date 2020/10/12 19:33
*/
public class RandomAccessFileTest {
public static void main(String[] args) {
RandomAccessFile raf = null;
try {
//1.//创建RandomAccessFile类型的对象与d:/a.txt文件关联
raf = new RandomAccessFile("d:/a.txt", "rw");
//2.//对文件内容进行随机读写操作
//设置距离文件开头位置的偏移量, 从文件开头位置向后偏移3个字节 aellhello
int res = raf.read();
System.out.println("读取到的单个字符是: " + (char)res); // a
raf.seek(3);
res = raf.read();
System.out.println("读取到的单个字符是: " + (char)res); // l 之后指向了h
res = raf.read();
System.out.println("读取到的单个字符是: " + (char)res); // h 之后指向了e
raf.write('2'); //执行该行代码覆盖了 'e'
System.out.println("写入数据成功!");
} catch (IOException e) {
e.printStackTrace();
} finally {
}
//3.//关闭流对象并释放有关的资源
if (null != raf) {
try {
raf.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}