1

ItemStackよし、ということで、どちらが と呼ばれるものを取得し、それをシリアル化するかを知る限り、動作するはずの 2 つのメソッドがあります。

  1. 次に、シリアライゼーションが に入力され、 にByteOutputStream変換されbyte[]ます。byte[]その後、特別な区切り文字が間にバイトを設定して、byteに変換されます。
  2. これらの各バイト (元は がありますItemStack[]) が に入力され、byte[]に格納されbyte[][][]ます。
  3. 後で、別のメソッドを呼び出してItemStack[]からを取得しようとしましbyte[]た。このメソッドは、特別な区切り文字セットを使用して を に分離しbyte[]、それをbyteに変換してから に変換します。Map<String, Object>ItemStack

これは私にとって非常に紛らわしいので、現在持っているものを以下に投稿します(2つの方法のみ)。さらに必要な場合はお知らせください。おそらく入手できます。

私の問題は、これが機能しないことです。エラーなどはありませんが、何らかの理由でデータが最後まで到達しません。誰かがこれに対する解決策を持っている場合は、助けてください。多分それは私がデータを分割している方法にあるのかもしれません...または多分私は文字列またはオブジェクトだったものにバイトを切り捨てたり追加したりしています。

private static byte[] contentsToBytes(Block block, ItemStack[] contents) throws IOException {
    byte[] bytes = new byte[] {block.getData()};
    byte[] dataSplitter = ITEMSTACKDATASPLITTER.getBytes("UTF-8");
    for (int i = 0; i < contents.length; i++) {
        Map<String, Object> serialized = contents[i].serialize();
        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
        ObjectOutputStream out = new ObjectOutputStream(byteOut);
        out.writeObject(serialized);
        byte[] serializedByteArray = byteOut.toByteArray();
        byte[] copyBytes = Arrays.copyOf(bytes, bytes.length + dataSplitter.length + serializedByteArray.length);
        for (int j = 0; j < dataSplitter.length; j++) {
            copyBytes[bytes.length + j] = dataSplitter[j];
        }
        for (int k = 0; k < serializedByteArray.length; k++) {
            copyBytes[bytes.length + dataSplitter.length + k - 1] = serializedByteArray[k];
        }
        bytes = copyBytes;
    }
    return bytes;
}    

private static ItemStack[] bytesToContents(byte[] bytes) throws IOException, ClassNotFoundException {
    ArrayList<ItemStack> stacks = new ArrayList<ItemStack>();
    byte[] dataSplitter = ITEMSTACKDATASPLITTER.getBytes("UTF-8");
    byte[] currentByteItemStack = new byte[1];
    boolean decompress = false;
    for (int i = 1; i < bytes.length; i++) {
        byte current = bytes[i];
        if (current == dataSplitter[0]) {
            byte[] dataSplitterTest = Arrays.copyOfRange(bytes, i, i - 1 + dataSplitter.length);
            boolean match = true;
            for (int j = 0; j < dataSplitter.length; j++) {
                if (dataSplitter[j] != dataSplitterTest[j]) {
                    match = false;
                    break;
                }
            }
            if (decompress && match) {
                ByteArrayInputStream byteIn = new ByteArrayInputStream(Arrays.copyOfRange(currentByteItemStack, 0, currentByteItemStack.length - 2));
                ObjectInputStream in = new ObjectInputStream(byteIn);
                @SuppressWarnings("unchecked") Map<String, Object> serialized = (Map<String, Object>) in.readObject();
                stacks.add(ItemStack.deserialize(serialized));
            }
            i += dataSplitter.length - 1;
            decompress = match;
        }
        if (decompress) {
            currentByteItemStack = Arrays.copyOf(currentByteItemStack, currentByteItemStack.length + 1);
            currentByteItemStack[i - 1] = current;
        }
    }
    return stacks.toArray(new ItemStack[stacks.size()]);
}    
4

1 に答える 1

5

そのため、独自のシリアライゼーションを作成するためにかなりの時間を費やしているように聞こえますが、Java にはすでに優れたシリアライゼーションが組み込まれています。

シリアライズしようとしているこれらのオブジェクトがシリアライズ可能を実装していないことが原因である場合は、シリアライズできる一時的なラッパー クラスを作成すると、デフォルトのシリアライゼーションを使用できます。

public class MyItemStack implements Externalizable{
    private static final long serialVersionUID = 1L;
    ItemStack itemStack;
    MyItemStack(ItemStack itemStack){
        this.itemStack = itemStack;
    }
    @Override
    public void readExternal(ObjectInput arg0) throws IOException, ClassNotFoundException {
        ...
    }

    @Override
    public void writeExternal(ObjectOutput arg0) throws IOException {
        ...
    }
}

これらのメソッドをオーバーライドして、ItemStack または Block が実際に意味するものを (通常はプリミティブとして) 格納する必要があります。

その後のシリアル化は、次のようにかなり単純なはずです。

FileOutputStream fos = new FileOutputStream("myfile");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(myHashMap);
oos.close();

FileInputStream fis = new FileInputStream("myfile");
ObjectInputStream ois = new ObjectInputStream(fis);
Map<String,MyItemStack> myMap = (Map<String,MyItemStack>) ois.readObject();
ois.close();
于 2013-05-13T03:18:47.130 に答える