理想情况下,我只想读取 zip 存档并将每个文件存储在一个 Iterable 中以准备编译。 (假设 zip 仅包含 .java 文件)
这样的东西会很好,但这不起作用,因为我无法获取 zip 中每个文件的路径。
private ArrayList<String> javaFilePaths = new ArrayList<String>();
Iterable<? extends JavaFileObject> = fileManager.getJavaFileObjectsFromStrings(javaFilePaths);
是否可以将
ArrayList
的每个元素作为存档中文件的路径?到目前为止,我只能浏览 zip 存档并获取所有无用的文件名,因为当我调用 getJavaFileObjectsFromStrings(javaFilePaths);
时,它不会是文件的完整路径。也许我需要先将每个文件的内容存储在一个新的JavaFileObject
中?真的不确定解决这个问题的最佳方法...
有人可以帮忙解决这个问题吗,事实证明这非常棘手!
UPDATE:
考虑将 zip 存档中的每个文件存储为
File
类型数组中的 File
对象
然后调用getJavaFileObjectsFromFiles(arrayOfFiles);
方法。解决方案、想法?
引用接口API
此文件管理器创建代表常规文件、在谷歌搜索我发现了以下文章:在“Java 编译:概念和实现”部分中,它对“源文件”进行了以下说明:zip 文件条目或基于类似文件系统的容器中的条目的文件对象
要编译的一个或多个.java源文件。 JavaFileManager 提供了一个抽象文件系统,它将源文件名和输出文件名映射到 JavaFileObject 实例。 (下面的文章也做了同样的事情:两者都使用 CharSequence 作为编译源。 您可以尝试根据上面文章中的说明构建自己的实现,并更改为基于 ZipEntry。否则,您可以将 zip 条目的内容(正如您提到的,您知道它是一个 java 源文件)读取到 StringBuffer 中,然后使用其中一篇文章中的实现来编译它。这里,文件是指唯一名称和字节序列之间的关联。客户端不需要使用实际的文件系统。)
ZipFile.close()
。例如:
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;
public class SO {
static class ZipFileRecord {
final ZipFile zf;
final ZipEntry ze;
public ZipFileRecord(ZipFile zf, ZipEntry ze) {
super();
this.zf = zf;
this.ze = ze;
}
public String content() throws IOException {
InputStream is = zf.getInputStream(ze);
BufferedReader br = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8")));
StringBuilder sb = new StringBuilder();
String line = null;
int count = 5; // limit loop for reduced output
while ((line = br.readLine())!=null) {
sb.append(line);
sb.append("\n");
if (count--<=0) {
sb.append("...\n");
break;
}
}
br.close();
return sb.toString();
}
}
public static class ZipWalker {
final ArrayList<ZipFileRecord> list = new ArrayList<>();
ZipFile zf;
public void scan(String fn) throws ZipException, IOException {
File f = new File(fn);
if (!f.exists()) throw new RuntimeException("File not found: " + f);
zf = new ZipFile(f);
Enumeration<? extends ZipEntry> entries = zf.entries();
for (ZipEntry ze : Collections.list(entries)) {
if (ze.getName().endsWith(".java")) {
list.add(new ZipFileRecord(zf, ze));
}
}
}
public void dump() throws IOException {
int count = 3; // limit loop for reduced output
for (ZipFileRecord fr : list) {
System.out.println("=============> " + fr.ze);
System.out.println(fr.content());
if (count--<=0)
break;
}
zf.close();
}
}
public static void main(String[] args) throws ZipException, IOException {
ZipWalker zw = new ZipWalker();
zw.scan("path/to/your/file.zip");
zw.dump();
}
}
值得注意的事情:
scan
方法执行扫描,
dump
方法代表您想要对文件执行的所有其他操作。完成 ZIP 文件后必须调用
ZipFile.close()
。如果已调用
close()
,则无法从其条目中读取数据。
count
变量是为了输出简洁 - 您需要删除这些变量以及关联的
if
。
Reader
和
UTF-8
。如果您向用户呈现文件内容,您可能必须处理文件的字符集。您可能还需要处理它以进行编译。
btnBrowse.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int returnVal = fileChooser.showOpenDialog(null);
if (returnVal == JFileChooser.APPROVE_OPTION) {
try {
isZip = true;
ZipFile zipFile = new ZipFile(fileChooser.getSelectedFile());
Enumeration<?> enu = zipFile.entries();
while (enu.hasMoreElements()) {
ZipEntry zipEntry = (ZipEntry) enu.nextElement();
File file = new File(zipEntry.getName());
InputStream is = zipFile.getInputStream(zipEntry);
FileOutputStream fos = new FileOutputStream(file);
byte[] bytes = new byte[1024];
int length;
while ((length = is.read(bytes)) >= 0) {
fos.write(bytes, 0, length);
}
is.close();
fos.close();
fileArrayList.add(file);
}
zipFile.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
});