问题很简单,无论何时我添加GZipInputStream和GZipOutputStream,我的数据都会损坏。没有它们,一切正常。
我有以下代码:
public boolean loadAll() {
FileHandle file = Gdx.files.external("TinyVoxel/world_comp.lvl");
if (!file.exists())
return false;
InputStream in = file.read();
try {
in = new GZIPInputStream(in);
int count = in.read();
ErrorHandler.log("Count loading grids: " + count);
int it = 0;
while(in.available() > 0) {
int x = in.read();
int y = in.read();
int z = in.read();
Grid grid = createGrid(x, y, z);
grid.loadGrid(in);
it++;
if (it % 10 == 0) {
System.out.println("Loading: " + ((float)it * 100f / (float)count));
}
}
in.close();
} catch (IOException ex) {
ErrorHandler.log("Failure saving!");
}
return true;
}
如果我删除了GZIPInputStream并且没有用GZIPOutputStream压缩原始数据(见下文,我删除了GZIPOutputStream),那么一切都很好。
public void saveAll() {
Iterator<ObjectMap.Entry<List<Integer>, Grid>> it = terrainMap.entries().iterator();
int count = 0;
OutputStream out = Gdx.files.external("TinyVoxel/world_comp.lvl").write(false);
try {
out = new GZIPOutputStream(out);
out.write(terrainMap.size);
ErrorHandler.log("Count writing grids: " + terrainMap.size);
while (it.hasNext()) {
ObjectMap.Entry<List<Integer>, Grid> entry = it.next();
List<Integer> pos = entry.key;
final Grid grid = entry.value;
grid.saveGrid(out);
if (count % 10 == 0)
System.out.println("Saving: " + ((float)count * 100f / (float) terrainMap.size));
count++;
}
out.close();
} catch (IOException ex) {
ErrorHandler.log("Failure saving!");
}
ErrorHandler.log("Complete saving!");
}
值得注意的是,我在grid.loadGrid和grid.saveGrid中进行字节保存和加载。它可能是由这些操作引起的,但为什么它与常规Out和Inputstream一起工作正常?
此外还有grid.loadGrid和grid.saveGrid函数的代码 - 至少重要的部分。
public boolean loadGrid(InputStream in) throws IOException {
int count = in.read();
palettesTotal = 0;
for (int gx = 0; gx < Config.GRID_SIZE_X; gx++)
for (int gy = 0; gy < Config.GRID_SIZE_Y; gy++)
for (int gz = 0; gz < Config.GRID_SIZE_Z; gz++) {
grids[gx][gy][gz] = (byte)0xff;
}
for (int i = 0; i < count; i++) {
int gx = in.read();
int gy = in.read();
int gz = in.read();
grids[gx][gy][gz] = (byte) (palettesTotal & 0xff);
palettesTotal++;
byte[] buff = new byte[Config.TINY_GRID_SIZE * 2];
TinyGridContainer tinyGrid = bytePool.obtain();
for (int ty = 0; ty < Config.TINY_GRID_SIZE; ty++)
for (int tz = 0; tz < Config.TINY_GRID_SIZE; tz++) {
in.read(buff, 0, buff.length);
for (int tx = 0; tx < Config.TINY_GRID_SIZE; tx++) {
tinyGrid.grid[tx][ty][tz] = (short) ((buff[tx * 2] >> 2) & 0xff + buff[tx * 2 + 1] & 0xff);
}
}
tinyGrids.put(Position.create(gx, gy, gz), tinyGrid);
}
....
}
public void saveGrid(OutputStream out) throws IOException {
out.write(x);
out.write(y);
out.write(z);
out.write(palettesTotal);
for (int gx = 0; gx < Config.GRID_SIZE_X; gx++)
for (int gy = 0; gy < Config.GRID_SIZE_Y; gy++)
for (int gz = 0; gz < Config.GRID_SIZE_Z; gz++) {
if (grids[gx][gy][gz] != (byte) 0xff) {
// add tiny grid to pixmap
List<Integer> pos = Position.create(gx, gy, gz);
TinyGridContainer tinyGrid = tinyGrids.get(pos);
out.write(gx);
out.write(gy);
out.write(gz);
Position.free(pos);
byte[] buff = new byte[Config.TINY_GRID_SIZE * 2];
for (int ty = 0; ty < Config.TINY_GRID_SIZE; ty++)
for (int tz = 0; tz < Config.TINY_GRID_SIZE; tz++) {
for (int tx = 0; tx < Config.TINY_GRID_SIZE; tx++) {
buff[tx*2] = (byte)((tinyGrid.grid[tx][ty][tz] >> 2) & 0xff);
buff[tx*2+1] = (byte)(tinyGrid.grid[tx][ty][tz] & 0xff);
}
out.write(buff, 0, buff.length);
}
}
}
}
答案 0 :(得分:1)
史密斯先生的评论让我朝着正确的方向前进。
byte[] buff = new byte[Config.TINY_GRID_SIZE * 2];
TinyGridContainer tinyGrid = bytePool.obtain();
for (int ty = 0; ty < Config.TINY_GRID_SIZE; ty++)
for (int tz = 0; tz < Config.TINY_GRID_SIZE; tz++) {
int cnt = 0;
for (int tx = 0; tx < Config.TINY_GRID_SIZE; tx++) {
int id = tx * 2;
if (cnt <= id) {
cnt += in.read(buff, cnt, buff.length - cnt);
}
tinyGrid.grid[tx][ty][tz] = (short) ((buff[id] >> 2) & 0xff);
id++;
if (cnt <= id) {
cnt += in.read(buff, cnt, buff.length - cnt);
}
tinyGrid.grid[tx][ty][tz] += (short) (buff[id] & 0xff);
}
}