简体   繁体   English

我应该如何将POJO表示形式写入RandomAccessFile?

[英]How should I write a POJO representation to a RandomAccessFile?

I have a POJO which has a number of String fields. 我有一个POJO ,其中包含许多String字段。 I want to write instances of this object (sorted to natural ordering) to a RandomAccessFile and then eventually search this file for the objects I need. 我想将此对象的实例(按自然顺序排序)写入RandomAccessFile ,然后最终在此文件中搜索所需的对象。

The problem is I'm not too sure how to go about this - for example, in a plain text file I would delimit a new object instance with, say, a new line. 问题是我不太确定如何执行此操作-例如,在纯文本文件中,我将使用新行来分隔新的对象实例。 With RandomAccessFile should I be using the the size of the object in bytes to indicate a new object in the file - and if I know I want the second object, I would look at 2 object's worth of bytes into the file? 使用RandomAccessFile ,我是否应该使用对象的大小(以字节为单位)来指示文件中的新对象-如果我知道我想要第二个对象,那么我将查看文件中2个对象的字节值吗?

I've followed tutorials that write sorted integers to file - and if I want to find the second occurrence I would look 8 bytes into the file. 我遵循了将排序的integers写入文件的教程-如果我想查找第二个integers ,我会在文件中查找8个字节。 Should I be applying the same logic with my POJO - or could I just delimit using a new line ? 我应该对POJO应用相同的逻辑-还是可以使用new line定界?

Edit* these are my object's fields: 编辑*这些是我对象的字段:

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
}

You have several general approaches to implementing this: 您可以通过几种通用方法来实现此目的:

  • Use fixed-length strings - decide that your strings have a certain maximum length, and pad all strings that you write to that length with some unused character (say, zero). 使用固定长度的字符串 -确定您的字符串具有一定的最大长度,并使用一些未使用的字符(例如零)填充所有写入该长度的字符串。 You will need to deal with encoding of your strings if you are to allow Unicode code points past 127. 如果要允许Unicode代码点超过127,则需要处理字符串的编码。
  • Write an index at the top of the file or in a separate file - Add a separate block of data at the top of the file to help you navigate to the correct item. 在文件顶部或单独的文件中写入索引-在文件顶部添加单独的数据块,以帮助您导航到正确的项目。 This approach makes it difficult to grow the file beyond a certain limit, because the content needs to get copied or read into memory for expansion. 这种方法使文件增长到一定限制之外变得困难,因为需要复制内容或将其读入内存以进行扩展。
  • Do not use RandomAccessFile if you always get the whole file at once - this is the simplest approach to implement, and you get a human-viewable/editable text file. 如果您总是一次获取整个文件,请不要使用RandomAccessFile这是最简单的实现方法,并且您可以获取可查看/可编辑的文本文件。 The drawback to this approach is that you can no longer navigate to a specific item without reading the rest of the items. 这种方法的缺点是您不能在不阅读其余项目的情况下导航到特定项目。

There are two main strategies for putting variable-length records into random-access files. 将可变长度记录放入随机访问文件的主要策略有两种。

  1. Choose a fixed maximum length for all records and multiply by that value to locate the string you want. 为所有记录选择一个固定的最大长度,然后乘以该值以找到所需的字符串。 You will need to choose a null character to fill the unused section of each record, remove it on read and add it as padding on write. 您将需要选择一个null字符来填充每个记录的未使用部分,在读取时将其删除,并在写入时将其添加为填充。
  2. Maintain an index to the start and length of each string (either in the file or in memory) and pass every file access through that index. 维护每个字符串(在文件或内存中)的开始和长度的索引,并通过该索引传递每个文件访问权限。 Maintaining the index in the file can be tricky, especially when you need to add more records. 在文件中维护索引可能很棘手,尤其是当您需要添加更多记录时。 You may prefer using a second file as an index or rebuilding it every time you open the file. 您可能希望每次打开文件时都将第二个文件用作索引或重建它。

Each has it's advantages. 每个都有其优点。 (1) requires no index but can significantly increase the file size. (1)不需要索引,但可以大大增加文件大小。 (2) does not inflate the file size but requires maintenance of the index. (2)不会增加文件大小,但需要维护索引。

You could give your POJO a one-line csv-formatted toString() method and always write it as a single line to your random access file. 您可以为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();
    }
}

Doing so would write a csv file (where you could provide a header row). 这样做将编写一个csv文件(您可以在其中提供标题行)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM