Class RegionFile
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 Summary
ConstructorDescriptionRegionFile
(File path) Opens a region file for reading and writing, creating it if it doesn't exist. -
Method Summary
Modifier and TypeMethodDescriptionvoid
close()
getChunkDataInputStream
(int x, int z) Gets an (uncompressed) stream representing the chunk data.getChunkDataOutputStream
(int x, int z) Creates aDataOutputStream
to write a chunk to a byte.long
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
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)
-
Constructor Details
-
RegionFile
Opens a region file for reading and writing, creating it if it doesn't exist.- Parameters:
path
- the file path; must be in an existing folder- Throws:
IOException
- if the file cannot be opened
-
-
Method Details
-
getSizeDelta
public int getSizeDelta()Returns how much the region file has grown since this function was last called.- Returns:
- the growth in bytes
-
getChunkDataInputStream
Gets an (uncompressed) stream representing the chunk data. Returns null if the chunk is not found or an error occurs.- Parameters:
x
- the chunk X coordinate relative to the regionz
- the chunk Z coordinate relative to the region- Returns:
- an input stream with the chunk data, or null if the chunk is missing
- Throws:
IOException
- if the file cannot be read, or the chunk is invalid
-
getChunkDataOutputStream
Creates aDataOutputStream
to write a chunk to a byte.- Parameters:
x
- the chunk X coordinate within the regionz
- the chunk Z coordinate within the region- Returns:
- a
DataOutputStream
, backed by memory, that can prepare the chunk for writing to disk.
-
write
- Throws:
IOException
-
hasChunk
public boolean hasChunk(int x, int z) -
close
- Throws:
IOException
-
getLastModified
public 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. The timestamp is in milliseconds since the Unix epoch (seeFile.lastModified()
).- Returns:
- the modification timestamp
-