export/zip 通过 java 程序 Windows 和 MAC 的 eclipse 项目

export/zip eclipse project via java program for Windows and MAC

我需要在不使用 eclipse 的情况下导出一个 (java) eclipse 项目。我试图复制所有相关文件并用 ZipOutputStream 打包它们。到目前为止一切顺利,我可以在 Windows 中加载此 zip 文件。但是 MAC 用户 遇到了问题,即 文件结构不会被自动检测到 并创建名称类似于 "vorlage\src\de\tuberlin..." 的文件在 src 目录旁边。 (example picture)

有没有办法使用 java 程序正确导出 eclipse 项目?

原因是我为一个讲座创建了编程练习,并用特殊注释标记了解决方案。在复制文件的过程中,这些注释和解决方案被遗漏了。

一种解决方案是在 Windows 中导入 zip 文件,然后在 eclipse 的帮助下再次导出。但是每次练习都要花很多时间。

虽然我看不出这两个 zip 文件之间有什么不同,但似乎有些不同。

这里是我复制文件的代码:

public static void copyDir(File source, File target, ArrayList<String> exclude)
throws FileNotFoundException, IOException {

    File[] files = source.listFiles();
    File newFile = null;
    target.mkdirs();
    if (files != null) {
        for (int i = 0; i < files.length; i++) {
            newFile = new File(target.getAbsolutePath() + System.getProperty("file.separator") + files[i].getName());
            if (files[i].isDirectory()) {
                copyDir(files[i], newFile, exclude);
            }
            else if ( !exclude.contains(files[i].getName()) ) {
                copyFile(files[i], newFile);
            }
        }
    }
}

public static void copyFile(File file, File target) throws FileNotFoundException, IOException {

    if (file.getName().endsWith(".java")) {
        copyJavaFile(file, target);
        return;
    }

    BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
    BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(target, true));
    int bytes = 0;
    while ((bytes = in.read()) != -1) {
        out.write(bytes);
    }
    in.close();
    out.close();
}


private static void copyJavaFile(File file, File target) throws IOException {

    BufferedReader in = new BufferedReader(new FileReader(file));
    PrintWriter out = new PrintWriter(target);
    boolean stopped = false;
    String line = null;
    while ( (line = in.readLine() ) != null) {
        stopped |= line.contains("IF EXCLUDE");
        if (!stopped && !line.contains("ENDIF"))
            out.println(line);
        stopped &= !line.contains("ELSE");
    }
    in.close();
    out.close();
}

我复制以下(子)directories/files:

我创建了 zip 文件:

public Zip(final File projDir, final File outFile) {
    ZipOutputStream output = null;
    try {
        output = new ZipOutputStream(
                    new BufferedOutputStream(
                        new FileOutputStream(outFile)));
        for (File file : projDir.listFiles()) {
            writeFiles(file, output, "");
        }
        output.finish();
    } catch (IOException ex) {
        System.err.println("IO Error: " + ex.getMessage());
    } finally {
        try {output.close();} catch (IOException ex) {}
    }
}

private void writeFiles(File f, ZipOutputStream output, String dir) throws IOException {
    if (f.isDirectory()) {
        // recursively write files in directory
        for (File file : f.listFiles()) {
            writeFiles(file, output, dir + f.getName() + File.separator);
        }
    } else {
        // write this file to archive
        FileInputStream fis = new FileInputStream(f);
        ZipEntry entry = new ZipEntry(dir + f.getName());
        entry.setTime(f.lastModified());
        output.putNextEntry(entry);
        copy(fis, output);
        output.closeEntry();
        fis.close();
    }
}

private void copy(InputStream is, OutputStream os) throws IOException {
    byte[] buffer = new byte[1024];
    int bytes;
    while ((bytes = is.read(buffer)) > 0) {
        os.write(buffer, 0, bytes);
    }
}

是路径分隔符的问题。使用“/”代替 "File.separator" 可以解决问题。 在上面的示例中,方法 writeFiles(...) 中的 for 循环必须是:

for (File file : f.listFiles()) {
    writeFiles(file, output, dir + f.getName() + "/");
}

另见 this answer