public class RegionFile extends Object
Region File Format
Concept: The minimum unit of storage on hard drives is 4KB. 90% of Minecraft chunks are smaller than 4KB. 99% are smaller than 8KB. Write a simple container to store chunks in single files in runs of 4KB sectors.
Each region file represents a 32x32 group of chunks. The conversion from chunk number to region number is floor(coord / 32): a chunk at (30, -3) would be in region (0, -1), and one at (70, -30) would be at (3, -1). Region files are named "r.x.z.data", where x and z are the region coordinates.
A region file begins with a 4KB header that describes where chunks are stored in the file. A 4-byte big-endian integer represents sector offsets and sector counts. The chunk offset for a chunk (x, z) begins at byte 4*(x+z*32) in the file. The bottom byte of the chunk offset indicates the number of sectors the chunk takes up, and the top 3 bytes represent the sector number of the chunk. Given a chunk offset o, the chunk data begins at byte 4096*(o/256) and takes up at most 4096*(o%256) bytes. A chunk cannot exceed 1MB in size. If a chunk offset is 0, the corresponding chunk is not stored in the region file.
Chunk data begins with a 4-byte big-endian integer representing the chunk data length in bytes, not counting the length field. The length must be smaller than 4096 times the number of sectors. The next byte is a version field, to allow backwards-compatible updates to how chunks are encoded.
A version of 1 represents a gzipped NBT file. The gzipped data is the chunk length - 1.
A version of 2 represents a deflated (zlib compressed) NBT file. The deflated data is the chunk length - 1.
Constructor and Description |
---|
RegionFile(File path)
Opens a region file for reading and writing, creating it if it doesn't exist.
|
Modifier and Type | Method and Description |
---|---|
void |
close() |
DataInputStream |
getChunkDataInputStream(int x,
int z)
Gets an (uncompressed) stream representing the chunk data.
|
DataOutputStream |
getChunkDataOutputStream(int x,
int z)
Creates a
DataOutputStream to write a chunk to a byte. |
long |
getLastModified()
Returns the modification timestamp of the region file when it was first opened by this
instance, or zero if this instance created the file.
|
int |
getSizeDelta()
Returns how much the region file has grown since this function was last called.
|
boolean |
hasChunk(int x,
int z) |
protected void |
write(int x,
int z,
byte[] data,
int length) |
public RegionFile(File path) throws IOException
path
- the file path; must be in an existing folderIOException
- if the file cannot be openedpublic int getSizeDelta()
public DataInputStream getChunkDataInputStream(int x, int z) throws IOException
x
- the chunk X coordinate relative to the regionz
- the chunk Z coordinate relative to the regionIOException
- if the file cannot be read, or the chunk is invalidpublic DataOutputStream getChunkDataOutputStream(int x, int z)
DataOutputStream
to write a chunk to a byte.x
- the chunk X coordinate within the regionz
- the chunk Z coordinate within the regionDataOutputStream
, backed by memory, that can prepare the chunk for writing
to disk.protected void write(int x, int z, byte[] data, int length) throws IOException
IOException
public boolean hasChunk(int x, int z)
public void close() throws IOException
IOException
public long getLastModified()
File.lastModified()
).Copyright © 2021. All rights reserved.