Android随机IOExceptions与CipherInputStream和ObjectInputStream

时间:2016-08-10 20:26:04

标签: java android objectinputstream objectoutputstream

我正在使用由ObjectOutputStream包装的CipherOutputStream在我的Android应用中将数据(当然还有相应的输入流来读取)结构写入磁盘。阅读在几乎100%的时间内都是成功的,但有时阅读失败(根本没有写作错误),但有很多例外情况:

  • java.io.StreamCorruptedException
  • android.util.Base64DataException:bad base-64
  • java.io.EOFException的
  • java.lang.IllegalArgumentException:NULL不是货币
  • 中的常量
  • java.io.IOException:最终确定密码时出错
  • ...

我尝试用SealedObject替换CipherOuputStream,但异常保持不变。我还使用ReadWriteLock同步对文件的访问。

这是被序列化的类之一。每个文件只保存一个类的对象的一个​​ArrayList(因此只有一个对writeObject()的调用)。

public class SdTransaction implements Serializable {

    public static final long serialVersionUID =-784295048753453223L;
    private int mAmount;
    private SdCurrency mCurrency;
    private Date mCreatedAt;
    private Source mSource;
    @Nullable
    private String mAccountId;
    private boolean mIsVirtual;

}

我的代码锁定基本上就像这样(没有错误处理,没有同步):

OutputStream os = mContext.openFileOutput("test.bin", Context.MODE_PRIVATE);
os = new Base64OutputStream(os, Base64.NO_PADDING);
os = new CipherOutputStream(os, mCipher);
ObjectOutputStream oos = new ObjectOutputStream(os);

oos.writeObject(mSerializable);
oos.flush();
oos.close();


InputStream is = mContext.openFileInput("test.bin", Context.MODE_PRIVATE);
is = new Base64InputStream(is, Base64.NO_PADDING);
is = new CipherInputStream(is, mCipher);
ObjectInputStream ois = new ObjectInputStream(is);

Object o = ois.readObject();
ois.close();

以下是一些堆栈跟踪:

java.io.StreamCorruptedException
    at java.io.ObjectInputStream.readStreamHeader (ObjectInputStream.java:2068)
    at java.io.ObjectInputStream.<init> (ObjectInputStream.java:371)
    at com.xyz.model.pin.SdPinRepositoryPersister.load (SdPinRepositoryPersister.java:72)
    at com.xyz.dagger.SdComponentHolder$Initializer.init (SdComponentHolder.java:293)
    at com.xyz.dagger.SdComponentHolder.init (SdComponentHolder.java:109)
    at com.xyz.dagger.SdComponentHolder.init (SdComponentHolder.java:120)
    at com.xyz.model.smoove.execution.SdSmooveExecutorService.onDataSetChanged0 (SdSmooveExecutorService.java:106)
    at com.xyz.model.smoove.execution.SdSmooveExecutorService.access$000 (SdSmooveExecutorService.java:35)
    at com.xyz.model.smoove.execution.SdSmooveExecutorService$1.run (SdSmooveExecutorService.java:98)
    at java.util.concurrent.Executors$RunnableAdapter.call (Executors.java:422)
    at java.util.concurrent.FutureTask.run (FutureTask.java:237)
    at java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1112)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:587)
    at java.lang.Thread.run (Thread.java:818)

java.io.StreamCorruptedException: Wrong format: d2
    at java.io.ObjectInputStream.corruptStream (ObjectInputStream.java:675)
    at java.io.ObjectInputStream.readNonPrimitiveContent (ObjectInputStream.java:788)
    at java.io.ObjectInputStream.readObject (ObjectInputStream.java:1983)
    at java.io.ObjectInputStream.readObject (ObjectInputStream.java:1940)
    at java.io.ObjectInputStream.readFieldValues (ObjectInputStream.java:1113)
    at java.io.ObjectInputStream.defaultReadObject (ObjectInputStream.java:454)
    at java.io.ObjectInputStream.readObjectForClass (ObjectInputStream.java:1345)
    at java.io.ObjectInputStream.readHierarchy (ObjectInputStream.java:1242)
    at java.io.ObjectInputStream.readNewObject (ObjectInputStream.java:1835)
    at java.io.ObjectInputStream.readNonPrimitiveContent (ObjectInputStream.java:761)
    at java.io.ObjectInputStream.readObject (ObjectInputStream.java:1983)
    at java.io.ObjectInputStream.readObject (ObjectInputStream.java:1940)
    at java.util.ArrayList.readObject (ArrayList.java:661)
    at java.lang.reflect.Method.invoke (Native Method)
    at java.io.ObjectInputStream.readObjectForClass (ObjectInputStream.java:1330)
    at java.io.ObjectInputStream.readHierarchy (ObjectInputStream.java:1242)
    at java.io.ObjectInputStream.readNewObject (ObjectInputStream.java:1835)
    at java.io.ObjectInputStream.readNonPrimitiveContent (ObjectInputStream.java:761)
    at java.io.ObjectInputStream.readObject (ObjectInputStream.java:1983)
    at java.io.ObjectInputStream.readObject (ObjectInputStream.java:1940)
    at com.xyz.model.persistance.SdDiskPersister.load (SdDiskPersister.java:80)
    at com.xyz.model.persistance.SdPersisterComposite.load (SdPersisterComposite.java:67)
    at com.xyz.dagger.SdComponentHolder$Initializer.init (SdComponentHolder.java:390)
    at com.xyz.dagger.SdComponentHolder.init (SdComponentHolder.java:109)
    at com.xyz.dagger.SdComponentHolder.init (SdComponentHolder.java:120)
    at com.xyz.model.data.SdDataService.onDataSetChanged0 (SdSmooveExecutorService.java:106)
    at com.xyz.model.data.SdDataService.access$000 (SdSmooveExecutorService.java:35)
    at com.xyz.model.data.SdDataService$1.run (SdSmooveExecutorService.java:98)
    at java.util.concurrent.Executors$RunnableAdapter.call (Executors.java:423)
    at java.util.concurrent.FutureTask.run (FutureTask.java:237)
    at java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1113)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:588)
    at java.lang.Thread.run (Thread.java:818)

java.io.UTFDataFormatException: bad byte at 2
    at java.nio.charset.ModifiedUtf8.decode (ModifiedUtf8.java:60)
    at java.io.DataInputStream.decodeUTF (DataInputStream.java:179)
    at java.io.DataInputStream.decodeUTF (DataInputStream.java:173)
    at java.io.DataInputStream.readUTF (DataInputStream.java:169)
    at java.io.ObjectInputStream.readClassDescriptor (ObjectInputStream.java:1704)
    at java.io.ObjectInputStream.readNewClassDesc (ObjectInputStream.java:1634)
    at java.io.ObjectInputStream.readClassDesc (ObjectInputStream.java:657)
    at java.io.ObjectInputStream.readNewClassDesc (ObjectInputStream.java:1663)
    at java.io.ObjectInputStream.readClassDesc (ObjectInputStream.java:657)
    at java.io.ObjectInputStream.readNewObject (ObjectInputStream.java:1782)
    at java.io.ObjectInputStream.readNonPrimitiveContent (ObjectInputStream.java:761)
    at java.io.ObjectInputStream.readObject (ObjectInputStream.java:1983)
    at java.io.ObjectInputStream.readObject (ObjectInputStream.java:1940)
    at java.util.ArrayList.readObject (ArrayList.java:661)
    at java.lang.reflect.Method.invoke (Native Method)
    at java.io.ObjectInputStream.readObjectForClass (ObjectInputStream.java:1330)
    at java.io.ObjectInputStream.readHierarchy (ObjectInputStream.java:1242)
    at java.io.ObjectInputStream.readNewObject (ObjectInputStream.java:1835)
    at java.io.ObjectInputStream.readNonPrimitiveContent (ObjectInputStream.java:761)
    at java.io.ObjectInputStream.readObject (ObjectInputStream.java:1983)
    at java.io.ObjectInputStream.readObject (ObjectInputStream.java:1940)
    at java.io.ObjectInputStream.readFieldValues (ObjectInputStream.java:1113)
    at java.io.ObjectInputStream.defaultReadObject (ObjectInputStream.java:454)
    at java.io.ObjectInputStream.readObjectForClass (ObjectInputStream.java:1345)
    at java.io.ObjectInputStream.readHierarchy (ObjectInputStream.java:1242)
    at java.io.ObjectInputStream.readNewObject (ObjectInputStream.java:1835)
    at java.io.ObjectInputStream.readNonPrimitiveContent (ObjectInputStream.java:761)
    at java.io.ObjectInputStream.readObject (ObjectInputStream.java:1983)
    at java.io.ObjectInputStream.readObject (ObjectInputStream.java:1940)
    at java.io.ObjectInputStream.readFieldValues (ObjectInputStream.java:1113)
    at java.io.ObjectInputStream.defaultReadObject (ObjectInputStream.java:454)
    at java.io.ObjectInputStream.readObjectForClass (ObjectInputStream.java:1345)
    at java.io.ObjectInputStream.readHierarchy (ObjectInputStream.java:1242)
    at java.io.ObjectInputStream.readNewObject (ObjectInputStream.java:1835)
    at java.io.ObjectInputStream.readNonPrimitiveContent (ObjectInputStream.java:761)
    at java.io.ObjectInputStream.readObject (ObjectInputStream.java:1983)
    at java.io.ObjectInputStream.readObject (ObjectInputStream.java:1940)
    at java.util.ArrayList.readObject (ArrayList.java:661)
    at java.lang.reflect.Method.invoke (Native Method)
    at java.io.ObjectInputStream.readObjectForClass (ObjectInputStream.java:1330)
    at java.io.ObjectInputStream.readHierarchy (ObjectInputStream.java:1242)
    at java.io.ObjectInputStream.readNewObject (ObjectInputStream.java:1835)
    at java.io.ObjectInputStream.readNonPrimitiveContent (ObjectInputStream.java:761)
    at java.io.ObjectInputStream.readObject (ObjectInputStream.java:1983)
    at java.io.ObjectInputStream.readObject (ObjectInputStream.java:1940)
    at java.io.ObjectInputStream.readFieldValues (ObjectInputStream.java:1113)
    at java.io.ObjectInputStream.defaultReadObject (ObjectInputStream.java:454)
    at java.io.ObjectInputStream.readObjectForClass (ObjectInputStream.java:1345)
    at java.io.ObjectInputStream.readHierarchy (ObjectInputStream.java:1242)
    at java.io.ObjectInputStream.readNewObject (ObjectInputStream.java:1835)
    at java.io.ObjectInputStream.readNonPrimitiveContent (ObjectInputStream.java:761)
    at java.io.ObjectInputStream.readObject (ObjectInputStream.java:1983)
    at java.io.ObjectInputStream.readObject (ObjectInputStream.java:1940)
    at java.util.ArrayList.readObject (ArrayList.java:661)
    at java.lang.reflect.Method.invoke (Native Method)
    at java.io.ObjectInputStream.readObjectForClass (ObjectInputStream.java:1330)
    at java.io.ObjectInputStream.readHierarchy (ObjectInputStream.java:1242)
    at java.io.ObjectInputStream.readNewObject (ObjectInputStream.java:1835)
    at java.io.ObjectInputStream.readNonPrimitiveContent (ObjectInputStream.java:761)
    at java.io.ObjectInputStream.readObject (ObjectInputStream.java:1983)
    at java.io.ObjectInputStream.readObject (ObjectInputStream.java:1940)
    at com.xyz.model.persistance.SdDiskPersister.load (SdDiskPersister.java:80)
    at com.xyz.model.persistance.SdPersisterComposite.load (SdPersisterComposite.java:67)
    at com.xyz.dagger.SdComponentHolder$Initializer.init (SdComponentHolder.java:385)
    at com.xyz.dagger.SdComponentHolder.init (SdComponentHolder.java:109)
    at com.xyz.dagger.SdComponentHolder.init (SdComponentHolder.java:120)
    at com.xyz.model.smoove.execution.SdService.onDataSetChanged0 (SdSmooveExecutorService.java:106)
    at com.xyz.model.smoove.execution.SdService.access$000 (SdSmooveExecutorService.java:35)
    at com.xyz.model.smoove.execution.SdService$1.run (SdSmooveExecutorService.java:98)
    at java.util.concurrent.Executors$RunnableAdapter.call (Executors.java:423)
    at java.util.concurrent.FutureTask.run (FutureTask.java:237)
    at java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1113)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:588)
    at java.lang.Thread.run (Thread.java:818)

android.util.Base64DataException: bad base-64
    at android.util.Base64InputStream.refill (Base64InputStream.java:148)
    at android.util.Base64InputStream.read (Base64InputStream.java:121)
    at java.io.InputStream.read (InputStream.java:162)
    at javax.crypto.CipherInputStream.fillBuffer (CipherInputStream.java:99)
    at javax.crypto.CipherInputStream.read (CipherInputStream.java:155)
    at com.xyz.model.streams.sync.SdSupervisedInputStream.read (SdSupervisedInputStream.java:80)
    at libcore.io.Streams.readFully (Streams.java:81)
    at java.io.DataInputStream.readShort (DataInputStream.java:152)
    at java.io.ObjectInputStream.readStreamHeader (ObjectInputStream.java:2061)
    at java.io.ObjectInputStream.<init> (ObjectInputStream.java:371)
    at com.xyz.model.persistance.SdDiskPersister.load (SdDiskPersister.java:77)
    at com.xyz.model.persistance.SdPersisterComposite.load (SdPersisterComposite.java:67)
    at com.xyz.dagger.SdComponentHolder$Initializer.init (SdComponentHolder.java:389)
    at com.xyz.dagger.SdComponentHolder.init (SdComponentHolder.java:109)
    at com.xyz.dagger.SdComponentHolder.init (SdComponentHolder.java:120)
    at com.xyz.model.smoove.execution.SdService.onDataSetChanged0 (SdSmooveExecutorService.java:106)
    at com.xyz.model.smoove.execution.SdService.access$000 (SdSmooveExecutorService.java:35)
    at com.xyz.model.smoove.execution.SdService$1.run (SdSmooveExecutorService.java:98)
    at java.util.concurrent.Executors$RunnableAdapter.call (Executors.java:423)
    at java.util.concurrent.FutureTask.run (FutureTask.java:237)
    at java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1113)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:588)
    at java.lang.Thread.run (Thread.java:818)

有没有人经历过类似的事情,或者可以给我一些如何本地化错误的提示?只有具有API 21及更高版本的设备才会出现这些错误......

1 个答案:

答案 0 :(得分:0)

我想出了一个解决方案,但我仍然不知道这个问题。使用BufferedReader / BufferedWrite替换ObjectOutputStream / ObjectInputStream和对象的JSON序列化时,一切正常。在服务中使用时,似乎正在使用ObjectInputStream ...