如何复制 Java 中的 MIDI 序列?

How to copy a midi sequence in Java?

我用下面的代码复制一个javax.sound.midi.Sequence:

private Object copyObject(Object objSource)
{
  Object objDest=null;

  try
  {
    ByteArrayOutputStream bos=new ByteArrayOutputStream();
    ObjectOutputStream oos=new ObjectOutputStream(bos);
    oos.writeObject(objSource);
    oos.flush();
    oos.close();
    bos.close();
    byte[] byteData=bos.toByteArray();
    ByteArrayInputStream bais=new ByteArrayInputStream(byteData);
    try { objDest=new ObjectInputStream(bais).readObject(); }
    catch (ClassNotFoundException e) { e.printStackTrace(); }
  }
  catch (IOException e) { e.printStackTrace(); }
  return objDest;
}

javax.sound.midi.Sequence sequence;
...
javax.sound.midi.Sequence newSequence=(Sequence)copyObject(sequence);

我收到以下错误:

java.io.NotSerializableException: javax.sound.midi.Sequence

执行此操作的正确方法是什么?

如异常所示,Sequence 不是可序列化的 class,因此您无法对其进行序列化。

使用 MidiSystem.write and MidiSystem.getSequence 代替 ObjectOutputStream 和 ObjectInputStream:

if (objSource instanceof Sequence) {
    Sequence sequence = (Sequence) objSource;
    int[] types = MidiSystem.getMidiFileTypes(sequence);

    MidiSystem.write(sequence, types[0], bos);

    byte[] byteData = bos.toByteArray();
    ByteArrayInputStream bais = new ByteArrayInputStream(byteData);

    try {
        return MidiSystem.getSequence(bais);
    } catch (InvalidMidiDataException e) {
        throw new IOException(e);
    }
}

另一种方法是创建一个新序列,并复制每个原始序列的轨道,这意味着使用克隆的 MidiMessages 复制每个轨道的 MidiEvents。

如果你希望有一个可以通用复制任何对象的方法,恐怕根本不可能。不可序列化的对象将始终需要手动复制。