我正在使用由ObjectOutputStream包装的CipherOutputStream在我的Android应用中将数据(当然还有相应的输入流来读取)结构写入磁盘。阅读在几乎100%的时间内都是成功的,但有时阅读失败(根本没有写作错误),但有很多例外情况:
我尝试用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及更高版本的设备才会出现这些错误......
答案 0 :(得分:0)
我想出了一个解决方案,但我仍然不知道这个问题。使用BufferedReader / BufferedWrite替换ObjectOutputStream / ObjectInputStream和对象的JSON序列化时,一切正常。在服务中使用时,似乎正在使用ObjectInputStream ...