一、今天半个小时复习JavaIO的第二部分,RandomAccessFile类和字节字符流的基本操作。
因为File类只是针对文件本身的操作,没法对内容操作,所以我们用RandomAccessFile类,此类属于随机读取,可以随机读取指定位置的数据。
此类的常用方法有
1、使用RandomAccessFile类写入数据。
1 import java.io.File ; 2 import java.io.RandomAccessFile ; 3 public class RandomAccessFileDemo01{ 4 // 所有的异常直接抛出,程序中不再进行处理 5 public static void main(String args[]) throws Exception{ 6 File f = new File("d:" + File.separator + "test.txt") ; // 指定要操作的文件 7 RandomAccessFile rdf = null ; // 声明RandomAccessFile类的对象 8 rdf = new RandomAccessFile(f,"rw") ;// 读写模式,如果文件不存在,会自动创建 9 String name = null ; 10 int age = 0 ; 11 name = "zhangsan" ; // 字符串长度为8 12 age = 30 ; // 数字的长度为4 13 rdf.writeBytes(name) ; // 将姓名写入文件之中 14 rdf.writeInt(age) ; // 将年龄写入文件之中 15 name = "lisi " ; // 字符串长度为8 16 age = 31 ; // 数字的长度为4 17 rdf.writeBytes(name) ; // 将姓名写入文件之中 18 rdf.writeInt(age) ; // 将年龄写入文件之中 19 name = "wangwu " ; // 字符串长度为8 20 age = 32 ; // 数字的长度为4 21 rdf.writeBytes(name) ; // 将姓名写入文件之中 22 rdf.writeInt(age) ; // 将年龄写入文件之中 23 rdf.close() ; // 关闭 24 } 25 };
此例时注意,使用时使每个数据的长度应该保持一致,即分配的空间是一致的。例如给zhangsan八位字符串,那么lisi虽然有四位,但是也要占八位。
2、使用RandomAccessFile读取数据:
1 import java.io.File ; 2 import java.io.RandomAccessFile ; 3 public class RandomAccessFileDemo02{ 4 // 所有的异常直接抛出,程序中不再进行处理 5 public static void main(String args[]) throws Exception{ 6 File f = new File("d:" + File.separator + "test.txt") ; // 指定要操作的文件 7 RandomAccessFile rdf = null ; // 声明RandomAccessFile类的对象 8 rdf = new RandomAccessFile(f,"r") ;// 以只读的方式打开文件 9 String name = null ; 10 int age = 0 ; 11 byte b[] = new byte[8] ; // 开辟byte数组 12 // 读取第二个人的信息,意味着要空出第一个人的信息 13 rdf.skipBytes(12) ; // 跳过第一个人的信息 14 for(int i=0;i<b.length;i++){ 15 b[i] = rdf.readByte() ; // 读取一个字节 16 } 17 name = new String(b) ; // 将读取出来的byte数组变为字符串 18 age = rdf.readInt() ; // 读取数字 19 System.out.println("第二个人的信息 --> 姓名:" + name + ";年龄:" + age) ; 20 // 读取第一个人的信息 21 rdf.seek(0) ; // 指针回到文件的开头 22 for(int i=0;i<b.length;i++){ 23 b[i] = rdf.readByte() ; // 读取一个字节 24 } 25 name = new String(b) ; // 将读取出来的byte数组变为字符串 26 age = rdf.readInt() ; // 读取数字 27 System.out.println("第一个人的信息 --> 姓名:" + name + ";年龄:" + age) ; 28 rdf.skipBytes(12) ; // 空出第二个人的信息 29 for(int i=0;i<b.length;i++){ 30 b[i] = rdf.readByte() ; // 读取一个字节 31 } 32 name = new String(b) ; // 将读取出来的byte数组变为字符串 33 age = rdf.readInt() ; // 读取数字 34 System.out.println("第三个人的信息 --> 姓名:" + name + ";年龄:" + age) ; 35 rdf.close() ; // 关闭 36 } 37 };
从这里看出,程序虽然可以成功完成任务,但是过于复杂,一般情况下,我们操作文件时会使用字节或者字符流。
二、字节流字符流
在程序中所有的数据主要是字节流和字符流两大类,两类都有输入输出操作。在字节流输出数据主要使用OutputStream,输入使用InputStream类。在字符流中输出主要用Writer,输入用Reader类完成。
在java中IO的操作也是有步骤的,以文件的操作为例,主要的流程是
(1)、使用File类打开一个文件。
(2)、通过字节流和字符流的子类指定输出的位置。
(3)、进行读写操作。
(4)、关闭输入输出。
1、字节流
字节输出流,OutputStream 是整个IO包中输出流的最大父类,下面是向文件中写入字符串
1 import java.io.File ; 2 import java.io.InputStream ; 3 import java.io.FileInputStream ; 4 public class InputStreamDemo01{ 5 public static void main(String args[]) throws Exception{ // 异常抛出,不处理 6 // 第1步、使用File类找到一个文件 7 File f= new File("d:" + File.separator + "test.txt") ; // 声明File对象 8 // 第2步、通过子类实例化父类对象 9 InputStream input = null ; // 准备好一个输入的对象 10 input = new FileInputStream(f) ; // 通过对象多态性,进行实例化 11 // 第3步、进行读操作 12 byte b[] = new byte[1024] ; // 所有的内容都读到此数组之中 13 input.read(b) ; // 读取内容 14 // 第4步、关闭输出流 15 input.close() ; // 关闭输出流 16 System.out.println("内容为:" + new String(b)) ; // 把byte数组变为字符串输出 17 } 18 };
还可以追加新内容,不过要使用FileOutputStream(File file, boolean append)
1 import java.io.File ; 2 import java.io.OutputStream ; 3 import java.io.FileOutputStream ; 4 public class OutputStreamDemo04{ 5 public static void main(String args[]) throws Exception{ // 异常抛出,不处理 6 // 第1步、使用File类找到一个文件 7 File f= new File("d:" + File.separator + "test.txt") ; // 声明File对象 8 // 第2步、通过子类实例化父类对象 9 OutputStream out = null ; // 准备好一个输出的对象 10 out = new FileOutputStream(f,true) ; // 此处表示在文件末尾追加内容 11 // 第3步、进行写操作 12 String str = "\r\nHello World!!!" ; // 准备一个字符串 13 byte b[] = str.getBytes() ; // 只能输出byte数组,所以将字符串变为byte数组 14 for(int i=0;i<b.length;i++){ // 采用循环方式写入 15 out.write(b[i]) ; // 每次只写入一个内容 16 } 17 // 第4步、关闭输出流 18 out.close() ; // 关闭输出流 19 } 20 };
字节输入流InputStream
1 import java.io.File ; 2 import java.io.InputStream ; 3 import java.io.FileInputStream ; 4 public class InputStreamDemo01{ 5 public static void main(String args[]) throws Exception{ // 异常抛出,不处理 6 // 第1步、使用File类找到一个文件 7 File f= new File("d:" + File.separator + "test.txt") ; // 声明File对象 8 // 第2步、通过子类实例化父类对象 9 InputStream input = null ; // 准备好一个输入的对象 10 input = new FileInputStream(f) ; // 通过对象多态性,进行实例化 11 // 第3步、进行读操作 12 byte b[] = new byte[1024] ; // 所有的内容都读到此数组之中 13 input.read(b) ; // 读取内容 14 // 第4步、关闭输出流 15 input.close() ; // 关闭输出流 16 System.out.println("内容为:" + new String(b)) ; // 把byte数组变为字符串输出 17 } 18 };
但是运行结果中发现后面太多空格,所以需要改进
1 import java.io.File ; 2 import java.io.InputStream ; 3 import java.io.FileInputStream ; 4 public class InputStreamDemo02{ 5 public static void main(String args[]) throws Exception{ // 异常抛出,不处理 6 // 第1步、使用File类找到一个文件 7 File f= new File("d:" + File.separator + "test.txt") ; // 声明File对象 8 // 第2步、通过子类实例化父类对象 9 InputStream input = null ; // 准备好一个输入的对象 10 input = new FileInputStream(f) ; // 通过对象多态性,进行实例化 11 // 第3步、进行读操作 12 byte b[] = new byte[1024] ; // 所有的内容都读到此数组之中 13 int len = input.read(b) ; // 读取内容 14 // 第4步、关闭输出流 15 input.close() ; // 关闭输出流\ 16 System.out.println("读入数据的长度:" + len) ; 17 System.out.println("内容为:" + new String(b,0,len)) ; // 把byte数组变为字符串输出 18 } 19 };
然后有没有种根据文件大小来决定空间的呢,当然有,因为我们有的方法叫length()
1 import java.io.File ; 2 import java.io.InputStream ; 3 import java.io.FileInputStream ; 4 public class InputStreamDemo03{ 5 public static void main(String args[]) throws Exception{ // 异常抛出,不处理 6 // 第1步、使用File类找到一个文件 7 File f= new File("d:" + File.separator + "test.txt") ; // 声明File对象 8 // 第2步、通过子类实例化父类对象 9 InputStream input = null ; // 准备好一个输入的对象 10 input = new FileInputStream(f) ; // 通过对象多态性,进行实例化 11 // 第3步、进行读操作 12 byte b[] = new byte[(int)f.length()] ; // 数组大小由文件决定 13 int len = input.read(b) ; // 读取内容 14 // 第4步、关闭输出流 15 input.close() ; // 关闭输出流\ 16 System.out.println("读入数据的长度:" + len) ; 17 System.out.println("内容为:" + new String(b)) ; // 把byte数组变为字符串输出 18 } 19 };