3 NBT stream API
Jesse Boyd edited this page 2017-04-12 21:46:46 +10:00

With FAWE you can stream a schematic, or any NBT without having to store the whole thing into memory.

  • You have to do this if a file is too large to fit in memory
  • If you just want to obtain some information from the stream
// Let's stream some info from a schematic file without having to load the whole thing into memory
// Schematics are compressed, so we need to use a GZIPInputStream before the NBTInputStream
File file = new File("blah.schematic");
NBTInputStream is = new NBTInputStream(new GZIPInputStream(new FileInputStream(file)));
NBTStreamer streamer = new NBTStreamer(is);

// Get the height,width,length
final Map<String, Short> dimensions = new HashMap<>();
// You need to know the structure of the NBT file, these specific values are all shorts
streamer.addReader(new NBTStreamer.NBTStreamReader<Integer, Short>() {
    @Override
    public void run(Integer index, Short value) {
        // The index is unimportant for this, but for Lists, or Arrays it might be useful
        dimensions.put(getNode(), value); // Put e.g. Schematic.Width -> 53
    }
}, "Schematic.Width", "Schematic.Height", "Schematic.Length");

// Let's get the Entities, I know that they will be of type CompoundTag
streamer.addReader("Schematic.Entities.#", new NBTStreamer.NBTStreamReader<Integer, CompoundTag>() {
    @Override
    public void run(Integer index, CompoundTag entity) {
        // For the .# and normal readers, it will always be Index, Value
        // Here we can do something with each entitiy
    }
});

// Get some info about the Blocks section (which contains the ids) (there's also AddBlocks, and Data)
streamer.addReader("Schematic.Blocks.?", new NBTStreamer.NBTStreamReader<Integer, Integer>() {
    @Override
    public void run(Integer length, Integer type) {
        Class<? extends Tag> clazz = NBTConstants.getClassFromType(type);
        // Here we can do something knowing the length of the section and its type
    }
});

// Now that we have the readers we want, we can read through the file
streamer.readFully();
// Or if you want FAWE to stop reading as soon as it finds what you want:
// streamer.readQuick();

System.out.println("Dimensions are: " + dimensions);

Classes using this API: