【问题标题】:Cannot read multiple externalizable objects from InputStream [duplicate]无法从 InputStream 中读取多个可外部化对象 [重复]
【发布时间】:2014-06-26 12:15:02
【问题描述】:

我在从 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 + "'");
    }
}

}

可外部化的“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();
}

}

结果:

结果,我收到类似“空价格为 0.0”的信息。它说我序列化了我的列表,但里面的对象没有序列化,为什么?

注意!

您能否再给我一个提示,如何在 Externalizable 类中将字符串、列表等写成 out.writeObject 或有更好的方法?

【问题讨论】:

  • 你不能追加到由ObjectOutputStream写入的文件并用单个ObjectInputStream读取它们,除非你采取特殊措施。

标签: java inputstream


【解决方案1】:

您的读取和写入不是对称的。

要写两个股票报价,你

  • 打开一个新的 ObjectOutputStream
  • 写股票报价
  • 关闭 ObjectOutputStream
  • 打开一个新的 ObjectOutputStream
  • 写股票报价
  • 关闭 ObjectOutputStream

要阅读这两个股票行情,您

  • 打开一个 ObjectInputStream
  • 阅读股票报价
  • 阅读股票报价
  • 关闭 ObjectInputStream

每次打开新的 ObjectOutputStream 时,都会将序列化标头写入底层流。

我的建议:将所有 StockQuotes 存储到一个列表中,并在完成后将此列表写入 ObjectOutputStream。在接收端,读取列表。

【讨论】:

  • 我已经编辑了我的源代码,但我遇到了列表可序列化的问题。我试图找到任何如何实现列表序列化的示例,但没有一个关于它的正常示例。你能告诉我一个如何写和读 List 的小例子吗?
  • oos.writeObject(list) 用于 crite, oos.readObject(list) 用于读取。 StockQuote 中的 readExternal() 和 writeExternal() 方法都很好。您在原始程序中唯一应该更改的是,您应该将它们存储在一个列表中,而不是编写 2 个股票报价,然后在完成后编写此列表。
猜你喜欢
  • 2011-10-19
  • 1970-01-01
  • 2018-09-06
  • 2010-12-25
  • 1970-01-01
  • 2018-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多