【问题标题】:Using readObject to get byte[][] giving OptionalDataException使用 readObject 获取 byte[][] 给出 OptionalDataException
【发布时间】:2014-02-09 18:20:08
【问题描述】:

我在阅读我制作的一些文件时遇到了一点问题。我正在制作游戏,并决定为地图制作自己的文件类型。我做了一个特殊的应用程序来制作这些地图文件。实例化地图后,我可以选择调用 readFile(String path) 将地图设置为已保存的地图。我知道我必须以相同的顺序读取和写入流,并且一切都很顺利,直到我添加了关于读取和写入 byte[][] 的语句。我无法弄清楚为什么会出现此异常以及如何仍然读取字节 [] []。这是我的课。

public class Map implements Serializable{

    String savePath;
    int boxWidth;
    int boxHeight;
    int mapWidth;
    int mapHeight;
    BufferedImage map;
    byte[][] encoded;
    LinkedList<BufferedImage> tileSet = new LinkedList<BufferedImage>();

    Map(int boxWidth, int boxHeight, int mapWidth, int mapHeight){
        map = new BufferedImage(boxWidth * mapWidth, boxHeight * mapHeight, BufferedImage.TYPE_INT_RGB);
        Graphics g = map.createGraphics();
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, map.getWidth(), map.getHeight());
        g.dispose();
        this.boxHeight = boxHeight;
        this.boxWidth = boxWidth;
        this.mapHeight = mapHeight;
        this.mapWidth = mapWidth;
        initEncode();
    }

    Map(){
        map = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
        this.boxHeight = 0;
        this.boxWidth = 0;
        this.mapHeight = 0;
        this.mapWidth = 0;
        initEncode();
    }

    void initEncode(){
        int width = 2 * mapWidth + 1;
        int height = 2 * mapHeight + 1;
        encoded = new byte[width][height];
        for(int i = 0; i < width; i++){
            for(int j = 0; j < height; j++){
                encoded[i][j] = 0;
            }
        }
    }

    void setMapTile(int i, int j, byte index){
        encoded[2 * i + 1][2 * j + 1] = index;
    }

    void setMapWall(int i, int j, byte index){
        encoded[2 * i][2 * i] = index;
    }

    void addToTileset(Tile tile){
        tileSet.add(tile.tile);
        writeFile(savePath);
    }

    //writing to file with path - boolean is for whether it went successfully or not
    boolean writeFile(String path){
        savePath = path;
        try{
            OutputStream file = new FileOutputStream(path);
            OutputStream buffer = new BufferedOutputStream(file);
            ObjectOutputStream output = new ObjectOutputStream(buffer);

            writeObject(output);

            output.close();
            buffer.close();
            file.close();
        }catch(IOException ex){
            System.err.println("Could not Write to file: " + path + "\nError caused by: " + ex);
            return false;
        }
        return true;
    }

    //reading from file with path - boolean is for whether it went successfully or not
    boolean readFile(String path){
        savePath = path;
        try{
            InputStream file = new FileInputStream(path);
            InputStream buffer = new BufferedInputStream(file);
            ObjectInputStream in = new ObjectInputStream(buffer);

            readObject(in);
            initEncode();

            file.close();
            buffer.close();
            in.close();
        }catch(IOException ex){
            System.err.println("Could not read from file: " + path + "\nError caused by: " + ex + "\n");
            ex.printStackTrace();
            return false;
        }catch(ClassNotFoundException e){
            System.err.println("Could not read from file: " + path + "\nError caused by: " + e + "\n");
            e.printStackTrace();
        }
        return true;
    }

    private void writeObject(ObjectOutputStream out) throws IOException {
        out.writeInt(boxHeight);
        out.writeInt(boxWidth);
        out.writeInt(mapHeight);
        out.writeInt(mapWidth);

        ImageIO.write(map, "png", out);
        out.writeObject(encoded);

        out.writeInt(tileSet.size());
        for(BufferedImage b: tileSet){
            ImageIO.write(b, "png", out);
         }
    }

    public void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException{
        boxHeight = in.readInt();
        boxWidth = in.readInt();
        mapHeight = in.readInt();
        mapWidth = in.readInt();

        map = ImageIO.read(in);
        encoded = (byte[][]) in.readObject();

        int tileSetSize = in.readInt();
        for(int i = 0; i < tileSetSize; i++){
            tileSet.add(ImageIO.read(in));
        }
    }
}

我的 (byte[][]) readObject() 行抛出 OptionalDataException 有什么原因吗?我该如何读/写我的 byte[][]。

编辑:感谢您的回答 Abhinav Kumar。我忽略了这一点,但是当我修复代码时,它仍然在同一行给我同样的错误。 (该类现已修复)。

【问题讨论】:

  • 检查OptionalDataExceptionjavadoc。 eoflength 设置了吗?

标签: java optionaldataexception


【解决方案1】:

你必须按照你在流中写入的相同顺序和相同格式读取 InputStream 否则你会得到 OptionalDataException

您已经按顺序将数据写入OutputStream:-

        ImageIO.write(map, "png", out);
        out.writeInt(2 * mapWidth + 1);
        out.writeObject(encoded);

您正在按顺序读取流:-

        map = ImageIO.read(in);
        encoded = (byte[][]) in.readObject();

读完地图后就读int。正确的代码是:-

 public void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException{
        boxHeight = in.readInt();
        boxWidth = in.readInt();
        mapHeight = in.readInt();
        mapWidth = in.readInt();
        map = ImageIO.read(in);
        in.readInt();// you read this int and assign it to the object as you wish
        encoded = (byte[][]) in.readObject();
        int tileSetSize = in.readInt();
        for(int i = 0; i < tileSetSize; i++){
            tileSet.add(ImageIO.read(in));
        }
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-29
    • 1970-01-01
    • 2014-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多