如何序列化和反序列化哈希表?
How to serialize and deserialize a Hashtable?
我正在尝试 Serialize
和 Deserialize
和 Hashtable
但没有成功。
代码如下:
反序列化
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();
}
序列化
public static void write(String s) throws FileNotFoundException, IOException
{
FileOutputStream fos = new FileOutputStream(s);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(list);
}
我写了 Class
日期,它不是 Java 的,但我写了 implemet Serializable
。
在我 Deserialize
Hashtable
并打印它之后,我只得到 {}
.
我做错了什么?
编辑
主要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:
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("");
}
}
}
}
日期Class:有日、月、年3个String
字段。我确实实现了 Serializable 并覆盖了 equals
和 HashCode
.
DateGUI Class: 有 GUI
"stuff" 和:
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()));
}
}
}
我相信你应该写完就冲水。
oos.writeObject(list);
oos.close();
您是否正在向文件写入任何内容,因为 write 方法将 String 作为参数,但您尚未指定要写入哪个文件。尝试:
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);
}
这是代码示例:
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);
}
}
}
After I deserialize the Hashtable
and print it I am getting just {}
.
What am I doing wrong?
此代码是从您的 MCVE 代码复制而来的。您已经将其编辑掉了,但我相信这个或类似的东西是您问题的真正原因。
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);
}
您应该在 oos
上调用 close()
,但这不是真正的问题。
(缺失的close()
可能导致序列化文件为空或不完整/损坏,但这不会导致你读回一个空的Hashtable
。你会得到一个异常。注意 new FileOutputStream(s)
将截断文件 ...)
真正的问题是方法的第一条语句。您正在无条件 分配一个新的空 Hashtable
给 list
。然后你在写它。所以(自然地)当你读回你写入文件的内容时,你会再次得到一个空的 Hashtable
。这就是您看到的 {}
的意思。
简而言之,您的代码正在写出一个空 table 并再次读回。 Hashtable
序列化工作正常。
我正在尝试 Serialize
和 Deserialize
和 Hashtable
但没有成功。
代码如下:
反序列化
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();
}
序列化
public static void write(String s) throws FileNotFoundException, IOException
{
FileOutputStream fos = new FileOutputStream(s);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(list);
}
我写了 Class
日期,它不是 Java 的,但我写了 implemet Serializable
。
在我 Deserialize
Hashtable
并打印它之后,我只得到 {}
.
我做错了什么?
编辑
主要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:
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("");
}
}
}
}
日期Class:有日、月、年3个String
字段。我确实实现了 Serializable 并覆盖了 equals
和 HashCode
.
DateGUI Class: 有 GUI
"stuff" 和:
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()));
}
}
}
我相信你应该写完就冲水。
oos.writeObject(list); oos.close();
您是否正在向文件写入任何内容,因为 write 方法将 String 作为参数,但您尚未指定要写入哪个文件。尝试:
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);
}
这是代码示例:
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);
}
}
}
After I deserialize the
Hashtable
and print it I am getting just{}
.What am I doing wrong?
此代码是从您的 MCVE 代码复制而来的。您已经将其编辑掉了,但我相信这个或类似的东西是您问题的真正原因。
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);
}
您应该在 oos
上调用 close()
,但这不是真正的问题。
(缺失的close()
可能导致序列化文件为空或不完整/损坏,但这不会导致你读回一个空的Hashtable
。你会得到一个异常。注意 new FileOutputStream(s)
将截断文件 ...)
真正的问题是方法的第一条语句。您正在无条件 分配一个新的空 Hashtable
给 list
。然后你在写它。所以(自然地)当你读回你写入文件的内容时,你会再次得到一个空的 Hashtable
。这就是您看到的 {}
的意思。
简而言之,您的代码正在写出一个空 table 并再次读回。 Hashtable
序列化工作正常。