带有多线程的Java IOException(EOFException)

时间:2019-07-16 12:15:37

标签: java multithreading stream java-io

我正在进行一个区块链仿真,矿工可以从内存中的文件读取区块链的当前状态,一旦他们挖掘了一个新的区块,就将更新后的链写入同一文件。然后其他矿工可以开始开采下一个区块,依此类推。我正在使用Java的FileInputStream,FileOutputStream,ObjectInputStream和ObjectOutputStream,但是在尝试读取区块链时,我总是收到IOException,特别是EOFException。

我在此站点上某处读取的内容可能是由于使用不同的FileInputStream,FileOutputStream,ObjectInputStream和ObjectOutputStream对象来写入和读取文件而导致的,所以我尝试在main中构造这些对象,然后将它们传递给构造函数每个矿工,但这不能解决问题。我创建了一个具有相同错误的最小示例,

    package com.company;
    import java.util.concurrent.*;
    import java.io.*;


    public class Main {

        public static void main(String[] args) {
            FileOutputStream outFile = null;
            FileInputStream file = null;
            ObjectOutputStream out = null;
            ObjectInputStream in = null;
            Obj testObj = new Obj();
            testObj.data = 0;

            // Serialization
            try {
                //Saving of object in a file
                outFile = new FileOutputStream("testFile.ser");
                file = new FileInputStream("testFile.ser");
                out = new ObjectOutputStream(outFile);
                in = new ObjectInputStream(file);
                synchronized (file) {

                    // Method for serialization of object
                    out.writeObject(testObj);
                }

            } catch (IOException ex) {
                System.out.println("IOException is caught main 1");
            }

            ExecutorService executor = Executors.newFixedThreadPool(10);

            for (int i = 0; i <10 ; i++) {
                executor.submit(new ObjModifier(file, outFile, in, out));

            }





        }

    }

    package com.company;

    import java.io.*;

    public class ObjModifier implements Runnable {
        private FileInputStream file;

        private FileOutputStream outFile;

        private ObjectInputStream in;

        private ObjectOutputStream out;

        private Obj readObj;
        @Override
        public void run(){
            while(!Thread.interrupted()){
                // Deserialization
                try
                {
                    // Method for deserialization of object
                    synchronized (file) {
                         readObj = (Obj) in.readObject();
                    }

                }

                catch(IOException ex)
                {
                    System.out.println("IOException is caught at ObjModifier " +
                            ex.getCause()+
                            ex.getMessage());
                }

                catch(ClassNotFoundException ex)
                {
                    System.out.println("ClassNotFoundException is caught at ObjModifier");
                }

                //simulate downloading current blockchain
                Obj myCopy = Obj.class.cast(DeepCopy.copy(readObj));

                //simulate mining next block
                for (int i = 0; i <10000 ; i++) {
                    int j = i;

                }
                myCopy.data += 1;

                //write updated object to file
                synchronized (outFile) {
                    // Serialization
                    try {
                        //Saving of object in a file

                        // Method for serialization of object
                        out.writeObject(myCopy);


                    } catch (IOException ex) {
                        System.out.println("IOException is caught at " + Thread.currentThread().getName());
                    }
                }



            }


        }

        public ObjModifier(FileInputStream file, FileOutputStream outFile, ObjectInputStream in, ObjectOutputStream out){
            this.file = file;
            this.outFile = outFile;
            this.in = in;
            this.out = out;

        }
    }



package com.company;

import java.io.IOException;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;

/**
 * Utility for making deep copies (vs. clone()'s shallow copies) of
 * objects. Objects are first serialized and then deserialized. Error
 * checking is fairly minimal in this implementation. If an object is
 * encountered that cannot be serialized (or that references an object
 * that cannot be serialized) an error is printed to System.err and
 * null is returned. Depending on your specific application, it might
 * make more sense to have copy(...) re-throw the exception.
 *
 * A later version of this class includes some minor optimizations.
 */
public class DeepCopy {

    /**
     * Returns a copy of the object, or null if the object cannot
     * be serialized.
     */
    public static Object copy(Object orig) {
        Object obj = null;
        try {
            // Write the object out to a byte array
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ObjectOutputStream out = new ObjectOutputStream(bos);
            out.writeObject(orig);
            out.flush();
            out.close();

            // Make an input stream from the byte array and read
            // a copy of the object back in.
            ObjectInputStream in = new ObjectInputStream(
                    new ByteArrayInputStream(bos.toByteArray()));
            obj = in.readObject();
        }
        catch(IOException e) {
            e.printStackTrace();
        }
        catch(ClassNotFoundException cnfe) {
            cnfe.printStackTrace();
        }
        return obj;
    }

}

package com.company;

import java.io.Serializable;

public class Obj implements Serializable {
    public int data;

    public Obj(){

    }

}

消息

IOException is caught at ObjModifier nullnull

被打印到控制台,使用异常断点,我看到该异常实际上是EOF异常。

请让我知道我是否可以澄清任何事情,或提供更多信息。

0 个答案:

没有答案