简体   繁体   English

如何序列化和反序列化哈希表?

[英]How to serialize and deserialize a Hashtable?

I am trying to Serialize and Deserialize a Hashtable but without success. 我正在尝试对Hashtable进行SerializeDeserialize Serialize ,但是没有成功。

Here's the code: 这是代码:

Deserialize 反序列化

    public static void read(File f) throws IOException, ClassNotFoundException
    {
        FileInputStream fos = new FileInputStream(f);
        ObjectInputStream oos = new ObjectInputStream(fos);

        list = new Hashtable<Date,String>((Hashtable<Date,String>)oos.readObject());
        oos.close();
    }

Serialize 连载

    public static void write(String s) throws FileNotFoundException, IOException
    {
        FileOutputStream fos = new FileOutputStream(s);
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        oos.writeObject(list);
    }

I wrote the Class Date, it's not Java's, but i did implemet Serializable there. 我写了Class Date,不是Java的,但是我在那implemet Serializable

After I Deserialize the Hashtable and print it I am getting just {} . 在将Hashtable Deserialize并打印后,我得到的只是{}

What am I doing wrong? 我究竟做错了什么?

EDIT 编辑

Main Class: 主类:

public class Main implements Serializable
{
    public static void main(String[] args) throws ClassNotFoundException, IOException
    {
        String[] options = {"Existing file","New file"};

        int choice = JOptionPane.showOptionDialog(null,
                "Whould you like to use an existing file or make a new file?",
                "Reminders", JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, null);

        System.out.println(choice);

        if(choice == 0)  //existing file
        {
            JFileChooser fc = new JFileChooser();

            try
            {
                Thread.sleep(1);
            }
            catch(InterruptedException ex)
            {
                Thread.currentThread().interrupt();
            }

            int returnVal = fc.showOpenDialog(null);

            GUI.read(fc.getSelectedFile());
        }
        else if(choice == 1) //new file
        {
            String name;
            do { name = JOptionPane.showInputDialog("Please enter the name of the new file: "); }
            while((name == null) || (name.length() == 0));

            GUI.write(name);
        }
        else if(choice == -1)
        {
            JOptionPane.showMessageDialog(null, "Good Bye!");
            System.exit(0);
        }

GUI Class: GUI类:

public class GUI extends JPanel implements Serializable
{
    private DateGUI date;
    private JButton save;
    private static JTextArea text;
    private JScrollPane scroll;

    private static Hashtable<Date,String> list = new Hashtable<Date,String>;

    public static void read(File f) throws IOException, ClassNotFoundException
    {
        FileInputStream fos = new FileInputStream(f);
        ObjectInputStream oos = new ObjectInputStream(fos);

        list = ((Hashtable<Date,String>)oos.readObject());
        oos.close();
    }

    public static void write(String s) throws FileNotFoundException, IOException
    {
        FileOutputStream fos = new FileOutputStream(s);
        ObjectOutputStream oos = new ObjectOutputStream(fos);

        oos.writeObject(list);
    }
    private class SaveListener implements ActionListener
    {
        @Override
        public void actionPerformed(ActionEvent e) 
        {
            if(e.getSource() == save)
            {
                list.put(new Date(DateGUI.getDay(),DateGUI.getMonth(),DateGUI.getYear()), text.getText());
                text.setText("");
            }

        }
    }
}

Date Class: has 3 String fields of day,month,year. 日期类:具有3个String字段,分别是日,月,年。 I did impelement Serializable and override equals and HashCode . 我没有实现Serializable并覆盖了equalsHashCode

DateGUI Class: has GUI "stuff" and: DateGUI类:具有GUI “东西”和:

    public static String getDay()
    {
        return (String)day.getSelectedItem();
    }

    public static String getMonth()
    {
        return (String)month.getSelectedItem();
    }

    public static String getYear()
    {
        return (String)year.getSelectedItem();
    }

   private class ShowListener implements ActionListener
   {
       @Override
       public void actionPerformed(ActionEvent e) 
       {
           if(e.getSource() == show)
           {
               GUI.set(GUI.get(getDay(), getMonth(), getYear()));
           }
       }
   }

After I deserialize the Hashtable and print it I am getting just {} . 在对Hashtable反序列化并将其打印后,我得到的只是{}

What am I doing wrong? 我究竟做错了什么?

This code is copied from your MCVE code. 此代码是从您的MCVE代码复制而来的。 You have since edited it out, but I am convinced that this or something like it was the real cause of your problem. 从那以后,您已经将它编辑掉了,但是我坚信这是您问题的真正原因。

public static void write(String s) throws FileNotFoundException, IOException
{
    list = new Hashtable<Date,String>();
    FileOutputStream fos = new FileOutputStream(s);
    ObjectOutputStream oos = new ObjectOutputStream(fos);

    oos.writeObject(list);
}

You should call close() on oos , but that's not the real problem. 您应该在oos上调用close() ,但这不是真正的问题。

(The missing close() may cause the serialized file to be empty or incomplete / corrupt, but that would NOT lead to you reading back an empty Hashtable . You wold get an exception instead. Note that the new FileOutputStream(s) will truncate the file ...) (缺少的close() 可能会导致序列化文件为空或不完整/损坏,但这不会导致您回读一个空的Hashtable 。相反,您会得到一个异常。请注意, new FileOutputStream(s)将截断该文件...)

The real problem is the first statement of the method. 真正的问题是该方法的第一个陈述。 You are unconditionally assigning a new empty Hashtable to list . 无条件地将新的空Hashtable分配给list Then you are writing it. 然后,您正在编写它。 So (naturally) when you read back what you wrote to the file you will get an empty Hashtable again. 因此,(自然地)当您读回写入文件的内容时,您将再次获得一个空的Hashtable That's what the {} you were seeing means. 这就是您所看到的{}意思。

In short, your code is writing out an empty table and reading it back again. 简而言之,您的代码正在写出一个空表并再次读回。 Hashtable serialization is working as it is supposed to work. Hashtable序列化正在按预期工作。

I believe you should flush after writing. 我相信您应该在写完之后刷新。

oos.writeObject(list); oos.writeObject(列表); oos.close(); oos.close();

Are you even writing anything to the file, because the write method is taking in a String as a parameter, but you haven't specified which file you are writing to. 您是否还在向文件中写入任何内容,因为write方法使用String作为参数,但是您尚未指定要写入哪个文件。 Try: 尝试:

public static void write(File f) throws FileNotFoundException, IOException
{
    FileOutputStream fos = new FileOutputStream(f);
    ObjectOutputStream oos = new ObjectOutputStream(fos);

    Hashtable<Date, String> list = new Hashtable<>();
    list.put(YourDateObject, "String");

    oos.writeObject(list);
}

Here is code example: 这是代码示例:

public class Main {

/**
 * File name
 */
private final static String FILENAME = "test.bin";

/**
 * Entry point
 * 
 * @param args
 * @throws Exception 
 */
public static void main(String[] args) throws Exception {

    Hashtable<Date, String> original = new Hashtable<>();

    // write some data to hashtable
    for (int i = 0; i < 3; i ++) {
        original.put(new Date(), String.valueOf(i));
        TimeUnit.MILLISECONDS.sleep(100);
    }

    // serialize
    write(FILENAME, original);

    // deserialize
    Hashtable<Date, String> restored = read(FILENAME);

    // compare results
    System.out.println(restored);
    System.out.println(restored);
}

/**
 * Deserialization
 * 
 * @param filename
 * @return
 * @throws IOException
 * @throws ClassNotFoundException 
 */
public static Hashtable<Date, String> read(String filename) throws IOException, ClassNotFoundException {
    try (ObjectInputStream oos = new ObjectInputStream(new FileInputStream(filename))) {
        return (Hashtable<Date, String>) oos.readObject();
    }
}

/**
 * Serialization
 * 
 * @param filename
 * @param list
 * @throws FileNotFoundException
 * @throws IOException 
 */
public static void write(String filename, Hashtable<Date, String> list) throws FileNotFoundException, IOException {
    try(ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filename))) {
        oos.writeObject(list);
    }
}

} }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM