我有一个在Java程序中创建的二进制文件。二进制文件包含一个User对象数组。
它是这样创建的:
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class Main {
public static void main(String[] args) {
User[] arrayOfUsers = new User[50];
for (int i = 0; i < 50; i++){
arrayOfUsers[i] = new User("Mr. ", i + "owitz");
}
try {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("users.dat"));
oos.writeObject(arrayOfUsers);
oos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
这是User
类:
import java.io.Serializable;
public class User implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private String firstname;
private String lastname;
public User(String firstname, String lastname) {
this.firstname = firstname;
this.lastname = lastname;
}
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getLastname() {
return lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
}
截至目前,我只知道如何一次读取整个数组。但是,我通常只需要从数组中检索一个或两个User
对象,我知道它们的位置。
有没有办法读取只是我想读的索引,而不读取所有内容?
答案 0 :(得分:2)
您没有构建直接文件,而只是一个恰好包含Java ArrayList的可序列化版本的顺序文件。因此,您只能回读内存中的整个ArrayList以再次处理它并访问单个元素。
如果您希望能够直接访问元素而只知道其索引,则必须构建真实的直接文件或索引文件。直接文件具有常量大小的记录,例如s
,因此记录n
的偏移量为n * s
。您可以通过Java类RandomAccessFile
使用它。但是你不应该直接使用readUTF
或writeUTF
作为直接文件,因为字符串的长度取决于字符的数量和类型:
因此,您最好用byte[]
明确地将它们转换为String.getBytes()
,至少现在可以更容易地控制大小,并手动将大小写入字节。或者,您可以编写跳过转换为字节的转换,在Char
中写入大小,然后编写单个字符。
如果您几乎从不修改值或添加值,则可以使用索引文件。基础是首先要有一个包含记录偏移的数组。这允许记录不具有相同的大小。可能的设计是:
int n
)要编写文件,您需要计算数据区域的开头:(1 + n)* 4,创建一个用于存储偏移量的int数组。然后你将n + 1 0
写入文件以正确定位,并编写你的字符串,始终保存第一个记录的写入位置。最后,您回到0,写下记录数和偏移量。
要阅读,只需读取记录数和偏移量。然后,您可以导航该文件。这主要用于未知和可变大小的大型记录
如果您发现上述内容过于复杂,请使用数据库。 Derby或H2可以用作嵌入式数据库,这将更加简单。