RandomAccessFile
此类的实例支持对随机访问文件的读取和写入。
该类不算是IO体系中子类。
而是直接继承自Object
但是它是IO包中成员。因为它具备读和写的功能。
内部封装了一个数组,而且通过指针对数组的元素进行操作
可以通过getFilePointer获取指针位置。
同时可以通过seek改变指针的位置
其实完成读写的原理就是内部封装了字节输入流和输出流
通过构造函数可以看出,该类只能操作文件
而且操作文件还有模式:只读r,读写rw等
如果模式为只读r,不会创建文件,会去读取一个已存在文件
如果该文件不存在,则会出现异常。
如果模式为rw,操作的文件不存在,会自动创建,如果存在则不会覆盖
例:
import java.io.*;
class RandomAccessFileDemo
{
public static void main(String[] args)throws IOException
{
//writeFile();
//readFile();
writeFile_2();
}
public static void readFile()throws IOException
{
RandomAccessFile raf = new RandomAccessFile("ran.txt", "rw");
//调整对象中指针
//raf.seek(8);
//跳过指定的字节数.只能往下跳,不能往回走
raf.skipBytes(8);
byte[] buf = new byte[4];
raf.read(buf);//读取四个字节
String name = new String(buf);//数组变成字符串
int age = raf.readInt();
System.out.println("name="+name);
System.out.println("age="+age);
raf.close();
}
public static void writeFile_2()throws IOException
{
RandomAccessFile raf = new RandomAccessFile("ran.txt", "rw");//不覆盖源文件
raf.seek(8*3);//指针偏移指定位置写数据
raf.write("周期".getBytes());
raf.writeInt(103);
raf.close();
}
public static void writeFile()throws IOException
{
RandomAccessFile raf = new RandomAccessFile("ran.txt","rw");//读写
raf.write("李四".getBytes());
raf.writeInt(97);//write写出int类型最低8位
//writeInt写出int型的32位
raf.write("王五".getBytes());
raf.writeInt(99);
raf.close();
}
}
---------------------------------------------------------------------------------------------------------------
DataInputStream与DataOutputStream
可以用于操作基本数据类型的数据流对象
例:
import java.io.*;
class DataStreamDemo
{
public static void main(String[] args)throws IOException
{
//writeData();
//readData();
//writeUTFDemo();
//UTF-8是3个字节,GBK是4个字节
//OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("gbk.txt"), " gbk");
//osw.write("你好");
//osw.close();
readUTFDemo();
}
public static void readUTFDemo()throws IOException
{
DataInputStream dis = new DataInputStream(new FileInputStream("utfdata.txt"));
String s = dis.readUTF();//以UTF修改后的编码形式读取
System.out.println(s);
dis.close();
}
public static void writeUTFDemo()throws IOException
{
DataOutputStream dos = new DataOutputStream(new FileOutputStream("utfdata.txt"));
dos.writeUTF("你好");//以UTF修改后的编码形式写入
dos.close();
}
public static void readData()throws IOException //数据读取
{
DataInputStream dis = new DataInputStream(new FileInputStream("data.txt"));
int num = dis.readInt();//读取相应类型数据
boolean b = dis.readBoolean();
double d = dis.readDouble();
System.out.println("num="+num);//输出
System.out.println("b="+b);
System.out.println("d="+d);
dis.close();
}
public static void writeData()throws IOException //存入数据
{
DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.txt"));
dos.writeInt(234);//写入int型数据
dos.writeBoolean(true);//写入boolean型数据
dos.writeDouble(9887.542);//写入double型数据
dos.close();
}
}
----------------------------------------------------------------------------------------------------------------
用于操作字节数组的流对象
ByteArrayInputStream:在构造的时候,需要接收数据源,而且
数据源是一个字节数组。
ByteArrayOutputStream:在构造的时候,不用定义数据目的,因为
该对象中已经内部封装了可变长度的字节数组。这就是数据
目的地。
因为这两个流对象都操作的数组,并没有使用系统资源。
所以,不用进行close关闭
关闭ByteArrayInputStream无效,此类中的方法在关闭此流
后仍可被调用,而不会产生任何IOException
流操作规律:
源设备,
键盘 System.out, 硬盘 FileStream, 内存 ArrayStream
目的设备,
控制台 System.out, 硬盘 FileStream, 内存 ArrayStream
例:
import java.io.*;
class ByteArrayStream
{
public static void main(String[] args)throws IOException
{
//数据源
ByteArrayInputStream bis = new ByteArrayInputStream("ABCDEFD".getBytes());
//数据目的
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int by = 0;
while((by=bis.read()) != -1)
{
bos.write(by);//写入数据
}
System.out.println(bos.size()); //输出缓冲区大小
System.out.println(bos.toString());//变成字符串输出
bos.writeTo(new FileOutputStream("a.txt"));//写入到文件,仅此方法要抛异常
}
}
---------------------------------------------------------------------------------------------------------------
个人总结:随机访问流RandomAccessFile中有只读r和读写rw模式,可以通过seek(int x)
和skipBytes(int x)实现随机访问,注意二者区别。操作基本数据类型使用DataInputStream
和DataOutputStream实现,注意读取和写入的类型以及编码形式。操作字节数据使用
ByteInputStream 和ByteOutputStream,内部封装了可变长度的数组,不调用底层资源,
所以不要抛异常和关闭流。