Java 无法从InputStream读取多个可外部化的对象

Java 无法从InputStream读取多个可外部化的对象,java,inputstream,Java,Inputstream,我在从InputStream(即从文件)读取多个对象时遇到问题。我收到例外情况: java.io.StreamCorruptedException: invalid type code: AC at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1379) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371) at

我在从InputStream(即从文件)读取多个对象时遇到问题。我收到例外情况:

java.io.StreamCorruptedException: invalid type code: AC
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1379)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371)
    at com.socket.Client.readFromFile(Client.java:63)
    at com.socket.Client.main(Client.java:44)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
我只读/写了一个对象,没关系。我可以写很多东西,也可以。但我不能从文件中读取多个对象。为什么会这样

编辑:

注意!似乎我遇到了在Externalazible类中实现List的问题。如何正确实施

我的“主”代码:

public class Client {


public static void main(String[] args) {

    if (args[0] == null || args[1] == null) {
        System.out.println("No arguments entered!");
        System.exit(0);
    }

    try (Socket clientSocket = new Socket("localhost", 3000);
         OutputStream outbound = clientSocket.getOutputStream();
         BufferedReader inbound = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));) {

        outbound.write((args[0] + "\n").getBytes());
        outbound.write("End\n".getBytes());

        List<StockQuote> stockQuotes = new ArrayList<>();
        String quote;
        while (true) {
            quote = inbound.readLine();

            if (quote != null && quote.equals("End"))
                break;

            stockQuotes.add(new StockQuote(args[0], new Double(quote)));
        }

        writeInFile(args[1], stockQuotes);
        stockQuotes.clear();

        stockQuotes = readFromFile(args[1]);
        if (stockQuotes != null)
            for (StockQuote stockQuote : stockQuotes)
                System.out.println("The " + stockQuote.getSymbol() + " price is " + stockQuote.getPrice());

    } catch (UnknownHostException e) {
        System.out.println("No such host available!");
    } catch (IOException e) {
        System.out.println("Server not reachable or down!!");
    }
}

private static List<StockQuote> readFromFile(String filename) {

    File file = new File(filename);

    try (ObjectInputStream readFromFile = new ObjectInputStream(new BufferedInputStream(new FileInputStream(file)));) {
        return (List<StockQuote>) readFromFile.readObject();
    } catch (FileNotFoundException e) {
        System.out.println("'" + filename + "' is not found in " + file.getPath());
    } catch (IOException e) {
        e.printStackTrace();
        System.out.println("Something gone wrong in the process of reading from '" + file + "'");
    } catch (ClassNotFoundException e) {
        System.out.println("Cast to class is wrong!");
    }

    return null;
}

private static void writeInFile(String filename, List<StockQuote> stockQuotes) {

    File file = new File(filename);

    try (ObjectOutputStream writeInFile = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(file, true)));) {
            writeInFile.writeObject(stockQuotes);
    } catch (FileNotFoundException e) {
        System.out.println("'" + filename + "' is not found in " + file.getPath());
    } catch (IOException e) {
        System.out.println("Something gone wrong in the process of writing to '" + file + "'");
    }
}
公共类客户端{
公共静态void main(字符串[]args){
if(args[0]==null | | args[1]==null){
System.out.println(“未输入参数!”);
系统出口(0);
}
try(socketclientsocket=newsocket(“localhost”,3000);
OutputStream outbound=clientSocket.getOutputStream();
BufferedReader inbound=新的BufferedReader(新的InputStreamReader(clientSocket.getInputStream());){
outbound.write((args[0]+“\n”).getBytes();
outbound.write(“End\n”.getBytes());
List stockQuotes=new ArrayList();
字符串引用;
while(true){
quote=inbound.readLine();
如果(quote!=null&"e.equals(“结束”))
打破
添加(新的StockQuote(args[0],新的Double(quote));
}
写文件(参数[1],股票报价);
stockQuotes.clear();
stockQuotes=readFromFile(args[1]);
if(股票报价!=null)
用于(股票报价股票报价:股票报价)
System.out.println(“该“+stockQuote.getSymbol()+”价格为“+stockQuote.getPrice());
}捕获(未知后异常e){
System.out.println(“没有这样的主机可用!”);
}捕获(IOE异常){
System.out.println(“服务器无法访问或关闭!!”;
}
}
私有静态列表readFromFile(字符串文件名){
文件=新文件(文件名);
try(ObjectInputStream readFromFile=newobjectinputstream(newbufferedinputstream(newfileinputstream(file)));){
返回(列表)readFromFile.readObject();
}catch(filenotfounde异常){
System.out.println(“+file.getPath()中找不到“+filename+”);
}捕获(IOE异常){
e、 printStackTrace();
System.out.println(“在读取“+”文件“+”的过程中出错了”);
}catch(classnotfounde异常){
System.out.println(“向类转换是错误的!”);
}
返回null;
}
私有静态无效写文件(字符串文件名,列表股票报价){
文件=新文件(文件名);
try(ObjectOutputStream writeInFile=newobjectoutputstream(newbufferedoutputstream(newfileoutputstream,file,true));){
writeInFile.writeObject(股票报价);
}catch(filenotfounde异常){
System.out.println(“+file.getPath()中找不到“+filename+”);
}捕获(IOE异常){
System.out.println(“写入“+”文件“+”过程中出现错误”);
}
}
}

可外部化的“StockQuote”类:

public class StockQuote implements Externalizable {

private String symbol;
private double price;
private List<StockQuote> stockQuoteList;

public StockQuote() {
}

public StockQuote(String symbol, double price) {
    this.symbol = symbol;
    this.price = price;
}

public String getSymbol() {
    return symbol;
}

public void setSymbol(String symbol) {
    this.symbol = symbol;
}

public double getPrice() {
    return price;
}

public void setPrice(double price) {
    this.price = price;
}

@Override
public void writeExternal(ObjectOutput out) throws IOException {
    out.writeObject(stockQuoteList);
}

@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
    stockQuoteList = (List<StockQuote>) in.readObject();
}
公共类StockQuote实现了外部化{
私有字符串符号;
私人双价;
私人上市股票报价人;
上市公司股票报价(){
}
公开股票报价(字符串符号,双倍价格){
这个符号=符号;
这个价格=价格;
}
公共字符串getSymbol(){
返回符号;
}
公共无效集合符号(字符串符号){
这个符号=符号;
}
公开双价{
退货价格;
}
公共定价(双倍价格){
这个价格=价格;
}
@凌驾
public void writeExternal(ObjectOutput out)引发IOException{
out.writeObject(stockQuoteList);
}
@凌驾
public void readExternal(ObjectInput in)引发IOException、ClassNotFoundException{
.readObject()中的stockQuoteList=(列表);
}
}

结果:

结果,我收到类似“零价格为0.0”的消息。它说我序列化了我的列表,但其中的对象没有序列化,为什么

注意


你能再给我一个提示吗,在可外部化的类中,如何更好地将字符串、列表等写为out.writeObject,或者有更好的方法来完成它?

你的读写是不对称的

要写两份股票报价,你需要

  • 打开新的ObjectOutputStream
  • 写一份股票报价
  • 关闭ObjectOutputStream
  • 打开新的ObjectOutputStream
  • 写一份股票报价
  • 关闭ObjectOutputStream
要阅读这两个股票报价,您需要

  • 打开ObjectInputStream
  • 读股票行情
  • 读股票行情
  • 关闭ObjectInputStream
每次打开新的ObjectOutputStream时,都会将序列化头写入基础流


我的建议是:将所有股票报价存储到一个列表中,完成后将该列表写入ObjectOutputStream。在接收端,阅读列表。

除非您采取特殊措施,否则您不能附加到ObjectOutputStream编写的文件并使用单个ObjectInputStream读取它们。我已编辑了源代码,但我面临列表可序列化的问题。我试图找到任何实现列表序列化的例子,但没有一个关于它的普通例子。你能给我举个小例子说明如何写和读列表吗?oos.writeObject(List)是crite,oos.readObject(List)是read。StockQuote中的readExternal()和writeExternal()方法很好。在原来的程序中,您唯一应该更改的是,您不应该编写两个股票报价,而应该将它们存储在一个列表中,完成后,再编写此列表。