我应该如何将一个POJO表示写入RandomAccessFile?

时间:2018-06-18 10:44:55

标签: java randomaccessfile

我有POJO,其中包含多个String字段。我想将此对象的实例(按自然排序排序)写入RandomAccessFile,然后最终在此文件中搜索我需要的对象。

问题是我不太确定如何解决这个问题 - 例如,在纯文本文件中,我会用一个新行来划分一个新的对象实例。使用RandomAccessFile我应该使用对象的大小(以字节为单位)来表示文件中的新对象 - 如果我知道我想要第二个对象,我会查看2个对象的字节值进入文件?

我已经按照将已排序integers写入文件的教程 - 如果我想找到第二次出现,我会在文件中看到8个字节。我应该在POJO中使用相同的逻辑 - 或者我可以使用new line分隔吗?

编辑*这些是我的对象的字段:

import java.io.FileWriter;
import java.io.IOException;
import java.io.Serializable;

/**
 * A RegradeRule is an individual rule found in the Regrade .dat file (one
 * line).
 * 
 * @author E Rowlands
 */
public class RegradeRule implements Serializable,  Comparable<RegradeRule> { 

    private String privateData;
    private String privateData;
    private String privateData;
    private String privateData;
    private String privateData;
    private String privateData;
    private String privateData;
    private String privateData;
    private String privateData;
    private String privateData;
    private String privateData;
    private String privateData;

    // getters & setters
}

3 个答案:

答案 0 :(得分:2)

您可以采用以下几种方法来实现此目的:

  • 使用固定长度字符串 - 确定您的字符串具有特定的最大长度,并使用一些未使用的字符(例如,零)填充您写入该长度的所有字符串。如果要允许Unicode代码点超过127,则需要处理字符串的编码。
  • 在文件顶部或单独的文件中编写索引 - 在文件顶部添加单独的数据块,以帮助您导航到正确的项目。这种方法使文件难以超出一定的限制,因为内容需要被复制或读入内存以进行扩展。
  • 如果您始终立即获取整个文件,请不要使用RandomAccessFile - 这是最简单的实施方法,您可以获得人工可视/可编辑的文本文件。这种方法的缺点是,如果不阅读其余项目,就无法再导航到特定项目。

答案 1 :(得分:1)

将可变长度记录放入随机访问文件有两种主要策略。

  1. 为所有记录选择固定的最大长度,然后乘以该值以找到所需的字符串。 您需要选择一个null字符来填充每条记录的未使用部分,在读取时将其删除并在写入时将其添加为填充。
  2. 维护每个字符串的开头和长度的索引(在文件或内存中),并通过该索引传递每个文件访问权限。 维护文件中的索引可能很棘手,尤其是当您需要添加更多记录时。您可能更喜欢使用第二个文件作为索引,或者每次打开文件时重建它。
  3. 每个人都有它的优点。 (1)不需要索引但可以显着增加文件大小。 (2)不会夸大文件大小,但需要维护索引。

答案 2 :(得分:1)

您可以为POJO提供单行csv格式的toString()方法,并始终将其作为单行写入随机访问文件。

public class RegradeRule implements Serializable,  Comparable<RegradeRule> { 

    private String privateData;
    private String privateData;
    private String privateData;
    private String privateData;
    private String privateData;
    private String privateData;
    private String privateData;
    private String privateData;
    private String privateData;
    private String privateData;
    private String privateData;
    private String privateData;

    // getters & setters

    @override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(privateData);
        sb.append(";");
        sb.append(privateData);
        sb.append(";");
        // do that until your last String attribute and then the last one without a semicolon
        sb.append(privateData);
        return sb.toString();
    }
}

这样做会编写一个csv文件(您可以在其中提供标题行)。