随机文件RandomAccessFile类
Java提供的RandomAccessFile类可进行随机形式的输入输出。
RandomAccessFile类直接继承于Object,但由于实现了DataInput和DataOutput接口而与同样实现该接口的DataInputStream和DataOutputStream类方法很类似。
1.建立随机访问文件流对象
建立RandomAccessFile类对象类似于建立其他流对象,RandomAccessFile类的构造方法如下:
RandomAccessFile(File file, String mode)
RandomAccessFile(String name, String mode)
其中,name为文件名字符串,file为File类的对象,mode为访问文件的方式,有“r”或“rw”两种形式。若mode为“r”,则文件只能读出,对这个对象的任何写操作将抛出IOException异常;若mode为“rw”并且文件不存在,则该文件将被创建。若name为目录名,也将抛出IOException异常。
例如,打开一个数据库后更新数据:
RandomAccessFile rf =new RandomAccessFile ("/usr/db/stock.dbf", "rw");
2.访问随机访问文件
RandomAccessFile对象的读写操作和DataInput/DataOutput对象的操作方式一样。可以使用在DataInputStream和DataOutputStream里出现的所有read()和write()方法。
3.移动文件指针
随机访问文件的任意位置的数据记录读写是通过移动文件指针指定文件读写位置来实现的。与文件指针有关的常用方法有:
public long getFilePointer()throws IOException返回文件指针的当前字节位置。
public void seek(long pos) throws IOException 将文件指针定位到一个绝对地址pos。pos参数指明相对于文件头的偏移量,地址0表示文件的开头。例如,将文件rf的文件指针移到文件尾,可用语句: rf.seek(rf.length());
其中:public long length()throws IOException返回文件的长度。地址"length()"表示文件的结尾。
public int skipBytes(int n)throws IOException将文件指针向文件尾方向移动n个字节。
4.向随机访问文件增加信息
可以用访问方式"rw"打开随机访问文件后,向随机访问文件增加信息。例如:
rf = new RandomAccessFile("c:/config.sys","rw");
rf.seek(rf.length());
例1、 使用随机访问文件读写数据。
import java.io.*; public class RandomIODemo { public static void main(String args[]) throws IOException { RandomAccessFile rf = new RandomAccessFile("random.txt","rw"); rf.writeBoolean(true); rf.writeInt(123456); rf.writeChar('j'); rf.writeDouble(1234.56); rf.seek(1); System.out.println(rf.readInt()); System.out.println(rf.readChar()); System.out.println(rf.readDouble()); rf.seek(0); System.out.println(rf.readBoolean()); rf.close(); } } 程序的输出结果如下: 123456 j 1234.56 true
|
例2、 显示指定文本文件最后n个字符。文本文件名和数字n用命令行参数的方式提供。
import java.io.*; class RandomIODemo2{ public static void main(String args[]) { try { RandomAccessFile rf = new RandomAccessFile(args[0], "r"); long count = Long.valueOf(args[1]).longValue(); long position = rf.length(); position -= count; if(position < 0) position = 0; rf.seek(position); while(true) { try { byte b = rf.readByte(); System.out.print((char)b); }catch(EOFException eofe) { break; } } }catch(Exception e) { e.printStackTrace(); } } } 若程序正确编译后,执行命令为: java RandomIODemo2 RandomIODemo2.java 50 这个命令表示显示程序RandomIODemo2.java的最后50个字符。 |
import java.io.File ; import java.io.RandomAccessFile ; public class RandomAccessFileDemo01{ // 所有的异常直接抛出,程序中不再进行处理 public static void main(String args[]) throws Exception{ File f = new File("d:" + File.separator + "test.txt") ; // 指定要操作的文件 RandomAccessFile rdf = null ; // 声明RandomAccessFile类的对象 rdf = new RandomAccessFile(f,"rw") ;// 读写模式,如果文件不存在,会自动创建 String name = null ; int age = 0 ; name = "zhangsan" ; // 字符串长度为8 age = 30 ; // 数字的长度为4 rdf.writeBytes(name) ; // 将姓名写入文件之中 rdf.writeInt(age) ; // 将年龄写入文件之中 name = "lisi " ; // 字符串长度为8 age = 31 ; // 数字的长度为4 rdf.writeBytes(name) ; // 将姓名写入文件之中 rdf.writeInt(age) ; // 将年龄写入文件之中 name = "wangwu " ; // 字符串长度为8 age = 32 ; // 数字的长度为4 rdf.writeBytes(name) ; // 将姓名写入文件之中 rdf.writeInt(age) ; // 将年龄写入文件之中 rdf.close() ; // 关闭 } }; |
import java.io.File ; import java.io.RandomAccessFile ; public class RandomAccessFileDemo02{ // 所有的异常直接抛出,程序中不再进行处理 public static void main(String args[]) throws Exception{ File f = new File("d:" + File.separator + "test.txt") ; // 指定要操作的文件 RandomAccessFile rdf = null ; // 声明RandomAccessFile类的对象 rdf = new RandomAccessFile(f,"r") ;// 以只读的方式打开文件 String name = null ; int age = 0 ; byte b[] = new byte[8] ; // 开辟byte数组 // 读取第二个人的信息,意味着要空出第一个人的信息 rdf.skipBytes(12) ; // 跳过第一个人的信息 for(int i=0;i<b.length;i++){ b[i] = rdf.readByte() ; // 读取一个字节 } name = new String(b) ; // 将读取出来的byte数组变为字符串 age = rdf.readInt() ; // 读取数字 System.out.println("第二个人的信息 --> 姓名:" + name + ";年龄:" + age) ; // 读取第一个人的信息 rdf.seek(0) ; // 指针回到文件的开头 for(int i=0;i<b.length;i++){ b[i] = rdf.readByte() ; // 读取一个字节 } name = new String(b) ; // 将读取出来的byte数组变为字符串 age = rdf.readInt() ; // 读取数字 System.out.println("第一个人的信息 --> 姓名:" + name + ";年龄:" + age) ; rdf.skipBytes(12) ; // 指针向后移12个字节,空出第二个人的信息 for(int i=0;i<b.length;i++){ b[i] = rdf.readByte() ; // 读取一个字节 } name = new String(b) ; // 将读取出来的byte数组变为字符串 age = rdf.readInt() ; // 读取数字 System.out.println("第三个人的信息 --> 姓名:" + name + ";年龄:" + age) ; rdf.close() ; // 关闭 } }; |
标准输入和输出
所谓标准输入输出是指对计算机系统默认的标准输入设备和标准输出设备进行读写操作,默认的输入设备通常是键盘,默认的输出设备通常是显示器。
Java程序与外部设备进行数据交换时使用的是流方式,而使用流需要创建一个相对应的流对象来实现与外部设备的连接。
由于程序的标准输入输出比较频繁,如果每次进行标准输入输出时都要创建相应的流对象就显得很不方便。为此,Java系统事先定义了两个流对象分别与系统的标准输入和标准输出相连接。这就是System.in和System.out。
1 System.in对象
System类是java.lang包中的一个很重要的类,它的所有方法和属性都是静态的,因此在使用它的属性和方法时不用创建对象,只要使用类名做前缀。
System.in是InputStream类的对象,调用System.in.read()方法就可以实现标准输入的读操作。
与大多数输入输出方法一样,System.in.read()方法可能引发IOException异常,因此必须使用异常处理的try{…}catch(IOException e){..}语句块来捕获异常并进行异常处理。
2 System.out对象
System.out是PrintStream类的对象,PrintStream类是FilterOutputStream类的子类,
其中定义了可输出多种不同类型数据的方法print()和println()方法。
System.out.print (s);
System.out.println(s);
print()方法在向屏幕输出数据完毕时光标停在最后一个字符后,
而println()方法在向屏幕输出数据完毕时自动换行,光标停留在下一行的第一个字符位置。
练习:标准输入输出示例import java.io.*;class system1{public static void main(String args[])throws IOException,Exception{ int ch;System.out.println("请输入内容");while((ch=System.in.read())!='\r')System.out.write(ch);System.out.write('\n');}} |
二、字符串和其他数据类型的相互转换
前面学习的输入输出类都是以字节或字符串类型作为参数。 实际上,各个输入输出类都定义了可以把数值字符串转换为对应的基本数据类型的静态方法,可以直接使用。 格式: parse××(String str)。以下代码实现了字符串到基本数据类型的转换: int i=Integer.parseInt("123"); long l=Long.parseLong("123"); float f=Float.parseFloat("123.45"); double d=Double.parseDouble("123.4567d"); |