重写readObject()正确读取对象,然后使所有成员变量为null /默认值

我有一个类,我将该类序列化到文件中,然后在需要时从文件中反序列化。我在同一类的构造函数中的函数中进行反序列化:

try (ObjectInputStream objectInputStream = 
     new ObjectInputStream(new FileInputStream(comdict_file));)
{
  objectInputStream.readObject();
}
catch (ClassnotFoundException e)
{
  // TODO Auto-generated catch block
  System.out.println(e.getMessage());
  e.printStackTrace();
}

使用的readObject是这样的:

private void readObject(ObjectInputStream in)
  throws IOException,ClassnotFoundException
{
  //read default properties
  in.defaultReadObject();
  String file = path + "meanings_info.bin";
  readBuffer(file);
}

运行调试器时,我意识到它可以正确读取所有内容并将其加载到实例中,但是一旦退出readObject(不是defaultReadObject)函数,我将回到所有成员变量为null或它们的默认值是什么。

我的问题是,如何“保留”序列化的值?

这是课程和测试,尽管我不认为这是问题所在

public class CompactDictionary implements Serializable
{
  private static final int BUFFER_SIZE_STEP = 10 * 1024 * 1024;
  private TObjectIntHashMap<String> meanings_index = new TObjectIntHashMap<>( 1000 );
  transient private ByteBuffer meanings_info = ByteBuffer.allocate(BUFFER_SIZE_STEP);
  //private int meanings_position = 0;
  private final static long serialVersionUID = 1L;
  //private final static Logger log = LogManager.getLogger();
  private transient Charset charset;
  //private boolean truncate;
  private String path;

  public CompactDictionary(String path,Charset cs,boolean trun)
    throws IOException
  {
    charset = cs;
    this.path = Objects.requireNonNull(path,"path must not be null");
    fileInitiation(trun);
  }

  private void fileInitiation(boolean trun) throws IOException
  {
    String meanings_file = path + "meanings_info.bin";
    String comdict_file = path + "comdict.bin";
    if (!trun) {
      File f = new File(meanings_file);
      File f2 = new File(comdict_file);
      if (!f.exists() || !f.isFile() || !f2.exists() || !f2.isFile()) {
        throw new FileNotFoundException("You chose to not truncate but the saved files are not in the specified directory or they don't have permissions.");
      }
      try (ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(comdict_file));){
        objectInputStream.readObject();
      } catch (ClassnotFoundException e) {
        // TODO Auto-generated catch block
        System.out.println(e.getMessage());
        e.printStackTrace();
      }
    } else {
      try (FileWriter fwOb = new FileWriter(meanings_file,false);
           PrintWriter pwOb = new PrintWriter(fwOb,false);
           FileWriter fwOb2 = new FileWriter(comdict_file,false);
           PrintWriter pwOb2 = new PrintWriter(fwOb,false);)
      {
        pwOb.flush();
        pwOb2.flush();
      }
    }
  }

  public void setCharset(Charset c) {
    charset = c;
  }

  public int size() {
    return meanings_index.size();
  }

  //TODO
  public boolean contains(String form,char pos)
  {
    return false;
  }

  public boolean contains(String meaning)
  {
    assert StringUtils.isnotBlank(meaning);
    return meanings_index.containsKey(meaning);
  }

  public List<String> getMeanings(String key)
  {
    assert StringUtils.isnotBlank(key);

    int position = getMeaningPosition(key);
    if (position == -1)
     return new ArrayList<>();

    final int old_pos = meanings_info.position();
    meanings_info.position(position);

    final int num_meanings = meanings_info.getShort();

    final List<String> meanings = IntStream.range(0,num_meanings)
        .mapToObj(i ->
    {
       final int num_bytes = meanings_info.getShort();
       byte[] bytes = new byte[num_bytes];
       meanings_info.get(bytes);
       return new String(bytes,charset);
    }).collect(toList());

      meanings_info.position(old_pos);
      return meanings;
  }

  @SuppressWarnings("UnusedReturnValue")
  public boolean addEntry(final String key,List<String> values)
  {
      //assert StringUtils.isnotBlank(meaning) && StringUtils.isnotBlank(label) && glosses != null;

      values.removeIf(String::isEmpty);
      if (contains(key))
            return false;

      final List<byte[]> bytes_list = new ArrayList<>(values.size());

      values.forEach(m ->
      { 
        final byte[] bytes_string = m.getBytes(charset);

        ByteBuffer buffer = ByteBuffer.allocate(2);
        buffer.putShort((short) bytes_string.length);
        final byte[] bytes_count = buffer.array();
        byte[] bytes = ArrayUtils.addAll(bytes_count,bytes_string);
        bytes_list.add(bytes);
      });

      //increase buffer size if necessary
      int num_bytes = Short.BYTES + bytes_list.stream()
        .mapToInt(a -> a.length)
        .sum();
      if (meanings_info.remaining() < num_bytes)
      {
        final ByteBuffer newBuf = ByteBuffer.allocate(meanings_info.capacity() + BUFFER_SIZE_STEP);
        meanings_info.flip();
        newBuf.put(meanings_info);
        meanings_info = newBuf;
      }

      final int position = meanings_info.position();


      meanings_info.putShort((short) values.size()); // a short with max value 32767 should suffice

      // store the bytes for each gloss
      for (final byte[] bytes : bytes_list)
      {
        meanings_info.put(bytes);
      }

      updateMeaningsIndex(key,position);
      return true;
  }

  private int getMeaningPosition(String m)
  {
    if (meanings_index.containsKey(m))
        return meanings_index.get(m);
    return -1;
  }

  private void updateMeaningsIndex(String meaning,int position)
  {
    meanings_index.put(meaning,position);
  }

  private void readBuffer(String filename)
    throws IOException
  {
    FileInputStream fileIn = new FileInputStream(filename);
    ObjectInputStream in = new ObjectInputStream(fileIn);
    int bufferSize = in.readInt();
    byte[] buffer = new byte[bufferSize];
    in.readFully(buffer,bufferSize);
    meanings_info = ByteBuffer.wrap(buffer,bufferSize);
    //meanings_info.position(meanings_position);
    in.close();
    //pasar a try
  }

  private void readObject(ObjectInputStream in)
    throws IOException,ClassnotFoundException
  {
    //final StopWatch timer = new StopWatch(); timer.start();

    //read default properties
    in.defaultReadObject();
    String file = path + "meanings_info.bin"; //pasar luego a join Path
    readBuffer(file);
  }

  public void save()
  {
    String comdict_file = path + "comdict.bin";
    try(FileOutputStream fos = new FileOutputStream(comdict_file);
        ObjectOutputStream oos = new ObjectOutputStream(fos);)
    {
      oos.writeObject(this);
    } catch (Exception e) {
      System.out.println(e.getMessage());
    }
    String meanings_file = path + "meanings_info.bin";

    try(FileOutputStream fos = new FileOutputStream(meanings_file);
        ObjectOutputStream oos = new ObjectOutputStream(fos);)
    {
        oos.writeInt(meanings_info.position());
        oos.write(meanings_info.array());
    }
    catch (Exception e) {
      System.out.println(e.getMessage());
    }
  }
}


@Test
public void testSave() throws Exception
{
  List<String> value2 = new ArrayList<>();
  List<String> value3 = Arrays.asList(new String[]{"first","second"});

  index.addEntry("testKey2",value2);
  index.addEntry("testKey3",value3);
  index.save();

  index = new CompactDictionary("src/test/resources/indexes/",StandardCharsets.UTF_8,false);

  List<String> actual;

  actual = index.getMeanings("testKey2");
  assertEquals("Seems that your index is messed up...",value2,actual);

  actual = index.getMeanings("testKey3");
  assertEquals("Seems that your index is messed up...",value3,actual);
}
syxiaoyongqq 回答:重写readObject()正确读取对象,然后使所有成员变量为null /默认值

您先读取一个对象,然后丢弃它(返回值)。

        objectInputStream.readObject();

从同一个类的构造函数中调用该方法,但实例不同的事实既没有听到也没有。

仅应将值序列化(可能使用Java序列化以外的方法)。使用不同类的方法来处理所有文件I / O业务。

本文链接:https://www.f2er.com/2984158.html

大家都在问