1

理想的には、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);ます。

ソリューション、アイデア?

4

3 に答える 3

2

あなたが要求したように私はあなたの答えにコメントしたでしょうが、コメントの長さは限られています. ファイル システム上の物理ファイルに実際にソースを抽出せずに、ソースをコンパイルするという目的を達成することは可能です。

インターフェースStandardJavaFileManagerの API からの引用

このファイル マネージャは、通常のファイル、zip ファイル エントリ、または同様のファイル システム ベースのコンテナ内のエントリを表すファイル オブジェクトを作成します。

Google で検索すると、次の記事が見つかりました: javax.tools を使用して動的アプリケーションを作成する

「Java コンパイル: 概念と実装」セクションでは、「ソース ファイル」について次のように述べています。

コンパイルする 1 つ以上の .java ソース ファイル。JavaFileManager は、ソースおよび出力ファイル名を JavaFileObject インスタンスにマップする抽象ファイル システムを提供します。(ここで、ファイルは一意の名前と一連のバイトとの関連付けを意味します。クライアントは実際のファイル システムを使用する必要はありません。)

次の記事でも同じことが行われています:動的インメモリ コンパイル

どちらもコンパイルするソースとして CharSequence を使用します。上記の記事の説明に基づいて、ZipEntry に基づく変更を加えて、独自の実装を構築することができます。それ以外の場合は、zip エントリの内容 (前述のように、Java ソース ファイルであることがわかっています) を StringBuffer に読み込み、いずれかの記事の実装を使用してコンパイルすることができます。

于 2013-04-03T00:53:07.490 に答える
0

ZIP ファイルをスキャンして、そのエントリへの参照を保持できます。次に、リストからエントリを選択し、ファイルを抽出して、必要な操作を行います。最初にすべてのファイルを完全に読み取る必要はありません。ZipFile.close()1 つの欠点: ZIP アーカイブの処理が完了するまで呼び出してはなりません。

例えば:

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();
    }
}

特筆すべきこと:

  1. scanメソッドはスキャンを行い、メソッドdumpはファイルに対して実行したい他のすべてのことを表します。
  2. ZipFile.close()ZIP ファイルの処理が終了した後に呼び出す必要があります。close()が呼び出された場合、そのエントリからデータを読み取ることはできません。
  3. コード内のcount変数は、出力を簡潔にするためのものです。それらと関連する を削除する必要がありますif
  4. 簡単にするために、 と を使用ReaderUTF-8ました。ファイルの内容をユーザーに提示する場合、ファイルの文字セットを処理する必要がある場合があります。また、コンパイルのためにそれを処理する必要がある場合もあります。
于 2013-04-02T20:18:21.343 に答える