Java 保存arraylist以缓存文件并检索它

Java 保存arraylist以缓存文件并检索它,java,android,Java,Android,我想创建两个方法。一个应该将arraylist存储到缓存中,另一个应该从缓存中检索arraylist。我尝试过的代码如下所示: public class ByteConverter<T> { public byte[] write_to_byte_array(ArrayList<T> list,File file){ // write to byte array FileOutputStream fos = null; try {

我想创建两个方法。一个应该将arraylist存储到缓存中,另一个应该从缓存中检索arraylist。我尝试过的代码如下所示:

public class ByteConverter<T> {

public byte[] write_to_byte_array(ArrayList<T> list,File file){

    // write to byte array
    FileOutputStream fos = null;
    try {
        fos = new FileOutputStream(file);
    } catch (FileNotFoundException e1) {
        Log.d("file not found", "file not found", e1);
    }

    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    DataOutputStream out = new DataOutputStream(baos);
    for (T element : list) {
        try {
            out.writeUTF((String) element);
        } catch (IOException e) {
            Log.d("Error converting List to byte array", "Error converting List to byte array", e);
        }
    }

    byte[] bytes = baos.toByteArray();

    int len1 = 0;
    while (len1 < bytes.length) {
        try {
            fos.write(bytes, 0, len1);
            len1++;
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    try {
        fos.close();
    } catch (IOException e) {
        e.printStackTrace();
    }

    return bytes;

}

public String read_to_byte_array(byte[] bytes) throws IOException{

    // read from byte array
    String element = null;
    ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
    DataInputStream in = new DataInputStream(bais);
    while (in.available() > 0) {
        element = in.readUTF();
    }

    return element; 
}

  }

重新读取
ClassCastException
,如果类型为
T
的元素不是
字符串
,您将获得该异常,因为该对象无法强制转换为
字符串
。也许您正在寻找元素的
toString
方法


还要看一看Apache Commons的
FileUtils
类和方法

首先,
ClassCastExcetion
是您没有得到任何输出的原因。在代码写入文件之前引发异常

其次,发生
ClassCastException
是因为元素不是
字符串。理论上,您可以调用
元素.toString()
来获得字符串表示形式,但这种表示形式可能不适合您的目的

那么,正确的方法是什么

这取决于
列表中对象的类型

  • 如果它们实现了
    Serializable
    (或
    Externalizable
    ),那么您应该能够使用Java序列化。有关更多详细信息,请阅读Java教程

  • 另一种选择可能是使用类似JAXP或GSON的东西,它们可以将POJO分别序列化为XML和JSON

  • 最后一种方法是手工编写序列化方法(以及相应的序列化方法)


最后,我应该指出代码中的一些其他错误:

1) 此代码错误:

int len1 = 0;
while (len1 < bytes.length) {
   fos.write(bytes, 0, len1);
   len1++;
}
写入
字节的正确方法是:

fos.write(bytes);

2) 您的异常处理逻辑不正确。在3或4个地方,你捕捉到一个异常,打印或记录一些东西。。。然后继续下去,就好像什么都没发生一样。您可能应该做的是让异常传播,并在更高级别上处理它们

3) 如果
write_to_byte_array
方法出错,则可能会泄漏文件描述符。最佳实践是关闭
finally
块中的资源,或者使用新的Java7try-with-resource语法

4)
read\u to\u byte\u array
write\u to\u byte\u array
方法的名称违反了公认的Java风格准则。它们应该是
readToByteArray
(或者更好的是
readFromByteArray
)和
writeToByteArray

  • 使用Serializable对象,因为ArrayList实现Serializable必须是实现Serializable

  • 您可以自定义数据类型,例如:

    长度|值|长度|值

    4字节|字节| 4字节|字节


  • ArrayList
    String
    都实现了
    Serializable
    ,因此如果您有字符串列表,那么整个代码是多余的。如果将任何其他类对象转换为
    字符串
    ,则肯定会发生类强制转换异常。使用
    ArrayList
    toString()
    或其他一些自定义机制将对象转换为
    String
    表示形式。
    bytes[0]
    bytes[0], bytes[1]
    bytes[0], bytes[1], bytes[2]
    
       and so on.  
    
    fos.write(bytes);
    
    fos.write(bytes, 0 bytes.length);