从zip文件中读取字节数组

时间:2012-07-26 23:03:57

标签: java bytearray

我花了几天时间创建了一个程序,它将从我的专用服务器托管游戏服务器。用户输入哪个WAD / PK3(存储地图信息,音乐等的文件),以及其他几个东西,并且能够托管服务器。

我有一个朋友制作了一个方法,该方法将通过WAD文件并收集信息,然后调用getLevelNames()并返回数组中的级别名称,然后将其添加到服务器主机命令行,添加适当的地图。

以下是我认为重要的代码部分:

public static byte[] getByteArrayFromFile(String filePath) throws IOException {
    return Files.readAllBytes(new File(filePath).toPath());
}

/**
 * Given a path to the file, this will extract the information into a byte array,
 * and then it will read it, index the file locations and pass the appropriate byte
 * data to other objects which will index the data in a useful way that the engine
 * can read/use.
 * Ideally after the data has been passed and indexed, the Wad object should be nullified and
 * set for garbage collection.
 * @param path The full path on the disk to the wad to be read from
 * @throws IOException If the path to the file has an error
 */
public Wad(String path) throws IOException {
    // Load wad data
    wadData = ByteData.getByteArrayFromFile(path);

    // Setup pointers
    headerType = ByteData.bytesToString(Arrays.copyOfRange(wadData, 0, 4));
    headerTotalLumps = ByteData.bytesToInt(wadData[4], wadData[5], wadData[6], wadData[7]);
    headerPointerToDirectory = ByteData.bytesToInt(wadData[8], wadData[9], wadData[10], wadData[11]);
    System.out.println("Wad data: " + headerType + ", " + headerTotalLumps + " total lumps, " + headerPointerToDirectory + " directory offset");

    // Setup offset data
    parseDirectory();
    getLevelNames();
}

public void getLevelNames() {
    String[] temp = new String[lumpName.length]; // Maybe I can divide this by 2, or 5 or something to save space since they all shouldn't be a map...
    Arrays.fill(temp, "");
    int tempIndex = 0;
    List<String> listMapNames = Arrays.asList(lumpMapNames);
    for (int i = 0; i < lumpName.length; i++)
        // Make sure: 1) were not at an end piece, 2) its actually a marker, 3) the next lump contains a map file (like SEGS), 4) The marker itself isn't something like an empty reject table, 5) doesn't contain GL_xyzab
        if (i != lumpName.length - 1 && fileSize[i] == 0 && listMapNames.contains(lumpName[i+1]) && !listMapNames.contains(lumpName[i]) && !lumpName[i].startsWith("GL_")) {
            temp[tempIndex] = lumpName[i];
            tempIndex++;
        }
    // If there's no levels
    if (tempIndex == 0) {
        levelNames = new String[0];
        return;
    }
    levelNames = new String[tempIndex]; // We should be at levels + 1, or at least a proper length
    for (int j = 0; j < tempIndex; j++)
        levelNames[j] = temp[j];
    // Sort the array just to make the server execution cleaner
    Arrays.sort(levelNames);
}

private void parseDirectory() {
    fileOffset = new int[headerTotalLumps];
    fileSize = new int[headerTotalLumps];
    lumpName = new String[headerTotalLumps];
    int c = 0; // Counter for starting at index 0 and going upwards
    System.out.println("Pointer: " + headerPointerToDirectory + ", total length: " + wadData.length + ", difference = " + (wadData.length - headerPointerToDirectory));
    for (int off = headerPointerToDirectory; off < wadData.length; off += 16) {
        fileOffset[c] = ByteData.bytesToInt(wadData[off], wadData[off+1], wadData[off+2], wadData[off+3]);
        fileSize[c] = ByteData.bytesToInt(wadData[off+4], wadData[off+5], wadData[off+6], wadData[off+7]);
        lumpName[c] = new String(Arrays.copyOfRange(wadData, off+8, off+16)).trim();
        c++;
    }
}

但是,我陷入了两难境地。由于PK3文件完全不同,因为它们基本上是.zip文件,它们为maps /目录中的每个地图存储单独的.WAD文件,我不知道我将如何访问它们。

以下是文件结构的示例:

  1. Level.pk3:
    • MUSIC
    • MAPS
      • d2dm01.wad
        • map01
      • d2dm02.wad
        • map02
      • d2dm03.wad
        • map03
    • 附加功能
  2. 我不知道如何在pk3内部的wads中访问文件,而不是逐个提取它们并检查for循环中的级别。不可否认,我也不知道自己在做什么,所以我想知道的是如何读取pk3中的文件并获取地图(map01,map02,map03)。

    此外,如果有人知道读取和解析文件中的字节以获取信息的良好资源,那将非常有用。我现在感觉很无能。

0 个答案:

没有答案