我有一个巨大的文件,其中包含ObjectOutputStream一个接一个地写入的对象列表.
for (Object obj : currentList){
oos.writeUnshared(obj);
}
Run Code Online (Sandbox Code Playgroud)
现在我想使用ObjectInputStream读取此文件.但是,我需要同时读取多个文件,因此我无法将整个文件读入内存.但是,使用ObjectInputStream会导致堆内存不足错误.从我读到的,这是因为ObjectInputStream有内存泄漏并且即使在返回它们之后也维护对read对象的引用.
我如何要求ObjectInputStream不保持其读取的引用?
我正在使用ObjectOutputStream来创建序列化对象的文件.然后我使用ObjectInputStream与readObject()方法一起从文件中取出对象.
它第一次很棒.这意味着如果文件不存在并且我打开它然后附加任意数量的对象,我可以打开ObjectInputStream对象并访问所有对象.
但是,如果我随后打开相同的文件(使用append选项)并添加更多对象,则ObjectInputStream对象将获取java.io.StreamCorruptedException:"无效的类型代码:AC"错误,其中新对象应该启动.
有没有其他人遇到这个?我甚至回到了Deitel书中的一些基本教科书示例,但仍然得到了同样的错误.
编辑:我发现了这一点 - 一旦关闭并在追加模式下重新打开,您可能不会附加到序列化流的末尾.写入似乎有效,但是当您稍后再读取该文件时,您将获得java.io.StreamCorruptedException.在" http://mindprod.com/jgloss/gotchas.html#SERIALIZATION "
我已经阅读了各种关于序列化和serialVersionUID使用的博客.他们中的大多数都提到使用它来维护可序列化类的状态.
我的情景是;
我知道旧的serialVersionUID和新的serialVersionUID.
在使用旧的serialVersionUID读取对象时,我想操纵数据以使其适合新版本,如果我正在读取的对象是旧类型,我只想打扰这样做.
这似乎应该是非常直接的东西!
有没有办法在读入对象时获取serialVersionUID?
在调用序列化类中的readObject方法之前抛出InvalidClassException,因此我无法在那里访问它.
我发现的唯一提示是覆盖ObjectInputStream,以便readClassDescriptor()可用,虽然这似乎是一个重要的解决方案,必须是一个常见的问题!
感谢所有帮助!
中号
为什么System.out.println(e.getCause());给出null?并且可以像这样存储整个HashSet集合吗?
private void saving() throws IOException, ClassNotFoundException {
ObjectOutputStream out = null;
try {
out = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(dataFile)));
out.writeObject(c);
} catch (java.io.NotSerializableException e) {
System.out.println(e.getCause());
} finally {
out.close();
}
}
Run Code Online (Sandbox Code Playgroud)
用来printStackTrace()代替getCause()
java.io.NotSerializableException: Data$1
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1180)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1528)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1493)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:346)
at java.util.HashSet.writeObject(HashSet.java:284)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:962)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1480)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:346)
at Prozor.saving(Prozor.java:81)
at Prozor.actionPerformed(Prozor.java:57) …Run Code Online (Sandbox Code Playgroud) 我有一个我正在制作的客户端 - 服务器应用程序,在阅读服务器上的对象时遇到了一些麻烦.
在我的服务器连接到客户端套接字后,我构建对象输入和输出流并将它们传递给我的service()方法.在那里,我应该处理来自客户端的不同类型的消息.我可以从客户端(即Message我的设计的一个对象)得到一条消息就好了.但是,当然,我想要做的就是有一个循环,这样我就可以得到一条消息,处理它并回复.
到目前为止,我的代码仅适用于单个消息.当我添加循环时,每次迭代都发生了什么,我的服务器只是一遍又一遍地读取相同的消息,然后我的客户端有机会通过套接字发送新消息(我认为这是正在发生的事情,至少) .
所以我真正需要做的是弄清楚如何使我的service()方法等待新的输入.有任何想法吗?或者我接近这个错误?我是否需要在每次迭代时创建一个新的OIS或......?一些代码:
public void service(ObjectInputStream input, ObjectOutputStream output) throws IOException, Exception {
_shouldService = true;
while (_shouldService) {
// It just keeps reading the same message over and over
// I need it to wait here until the client sends a new message
// Unless I'm just approaching this all wrong!
NetworkMessage message = (NetworkMessage) input.readObject();
NetworkMessageHeader header = message.getHeader();
String headerType = header.getType();
if (headerType.equals(NetworkMessageHeader.NetworkMessageHeaderTypeConnect)) {
doLoginForMessage(message, output); …Run Code Online (Sandbox Code Playgroud) 所以现在,我有一个运行的服务器ObjectInputStream和ObjectOutputStream.
我遇到的问题是我有一个自定义(匿名)类,它扩展java.lang.Date了我试图发送到客户端然后编译.
所以我没有在客户端定义类,但我想以编程方式编译类.我尝试了很多不同的方法,但每次我得到一个ClassNotFoundException因为该类最初不在客户端.
Class<?> dateClass = (Class<?>) in.readObject(); //This is where the CNF Exception occurs
Compiler.compileClass(dateClass);
Run Code Online (Sandbox Code Playgroud) java class objectoutputstream objectinputstream classnotfoundexception
我正在尝试从字符串构造 ObjectInputStream 但出现 java.io.StreamCorruptedException:
我的代码:
public static final String PUBLIC_KEY = "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7bO/38XhXYLJikoEEQ7s\naHKYcrrkD2Q+IWS6P0GOOvoX0rfRI6Hb30ETBE/ySzV6F9tpgtCbjU/w7tE8vmOy\nxQDwToUobbS+uZDi+F72PAY9NRKRogtY7YCwJuvAxNVmsTu9i/P/oA3qO3l0ge61\nZu3lMf4ujh969T9Dj0fjIdXQGewqk+ROB6UqoIEHTYi9wRdPlxDGnKTrORu5I5hH\n1xQfM0l49ME36G4u3Ipg5Y9Tqr1F8EL82GYeRoSX+xG+brQAdbjnQGrmrW/VFRkT\n9uL327vrRjiOit9yoTNtP3HYk1g5+Db7XdSNi+8KHZOQ3T2xcYFseXNnd7nIGj97\nBwIDAQAB\n-----END PUBLIC KEY-----";
public static final String PRIVATE_KEY_FILE = "C:/keys/private.key";
public static void test() {
Log.d("DEBUG","Original Text: ");
try {
final String originalText = "top secret text";
ObjectInputStream inputStream = null;
InputStream is = new ByteArrayInputStream(PUBLIC_KEY.getBytes());
//Log.d("DEBUG","Original Text:3 " + convertStreamToString(is));
// Encrypt the string using the public key
inputStream = new ObjectInputStream(is);
final PublicKey publicKey = (PublicKey) inputStream.readObject();
final byte[] cipherText = encrypt(originalText, publicKey);
// Decrypt …Run Code Online (Sandbox Code Playgroud) 我有这个可序列化的类,我用它来存储一个二进制文件的字符串ArrayList.
public class SaveState implements Serializable{
public static ArrayList <String> favoriteBusStopNumbers = new ArrayList<String>();
public static SaveState instance=new SaveState();
}
Run Code Online (Sandbox Code Playgroud)
我正在使用此方法来存储带有arrayList字符串的实例一旦此数组已满,我必须存储的数据:
public static void saveData(){
ObjectOutput out;
try {
//primero comprobamos si existe el directorio, y si no, lo creamos.
File folder = new File(Environment.getExternalStorageDirectory() + DIRECTORY_NAME);
if(!folder.exists())
folder.mkdirs();
File outFile = new File(Environment.getExternalStorageDirectory(), DIRECTORY_NAME+"appSaveState.data");
out = new ObjectOutputStream(new FileOutputStream(outFile));
out.writeObject(SaveState.instance);
out.close();
} catch (Exception e) {e.printStackTrace();}
}
Run Code Online (Sandbox Code Playgroud)
最后,我在我的应用程序的init上使用此方法来加载文件并使用以前存储的数据填充我的SaveState.instance变量:
public static void loadData(){
ObjectInput in;
try {
File inFile = …Run Code Online (Sandbox Code Playgroud) java serialization android objectoutputstream objectinputstream
我将通过TCP/IP编写一个程序,我应该通过客户端或服务器发送对象,当我想发送或接收字符串但是当我试图读取一个对象时,它是正确的:
private Socket client;
public ThreadedClient(Socket client) {
this.client = client;
}
@Override
public void run() {
try {
ObjectInputStream objIn = new ObjectInputStream(client.getInputStream());
while(true){
try {
Object fromClient = objIn.readObject();
} catch (ClassNotFoundException e) {e.printStackTrace();}
}
} catch (IOException e) {e.printStackTrace();}
}
Run Code Online (Sandbox Code Playgroud)
我收到一个例外:
java.io.StreamCorruptedException: invalid stream header: 306E6165
at java.io.ObjectInputStream.readStreamHeader(Unknown Source)
at java.io.ObjectInputStream.<init>(Unknown Source)
at org.bihe.serverSocket.ThreadedClient.run(Server.java:137)
at java.lang.Thread.run(Unknown Source)
Run Code Online (Sandbox Code Playgroud)
它指的是这一行:
ObjectInputStream objIn = new ObjectInputStream(client.getInputStream());
Run Code Online (Sandbox Code Playgroud)
这是我的服务器代码:
ServerSocket ss = new ServerSocket(8800);
while(true){
Socket newClient = ss.accept();
System.out.println(">>>> Client number …Run Code Online (Sandbox Code Playgroud) 在我的实验中,
如果服务器有这个:
ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
Run Code Online (Sandbox Code Playgroud)
然后客户端必须以相反的顺序执行此操作:
ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
Run Code Online (Sandbox Code Playgroud)
否则服务器和客户端会死锁。
这是什么原因?是否有正式的 API 规范?
java sockets serialization objectoutputstream objectinputstream