web-dev-qa-db-ja.com

Java 7NIOを使用してクラスパスからファイルを読み取ります

私はこれについてかなり長い間グーグルで検索しましたが、すべての結果はJava 7以前のNIOソリューションを示しています。 NIO stuff を使用して、ファイルシステムの特定の場所からファイルを読み込みましたが、以前よりもはるかに簡単でした(Files.readAllBytes(path))。ここで、WARとクラスパスにパッケージ化されているファイルを読み込みたいと思います。現在、次のようなコードでこれを行っています。

Input inputStream = this.getClass().getClassLoader().getResourceAsStream(fileName);
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();

/* iterate through the input stream to get all the bytes (no way to reliably find the size of the 
 *     file behind the inputStream (see http://docs.Oracle.com/javase/6/docs/api/Java/io/InputStream.html#available()))
 */
int byteInt = -1;
try
{
    byteInt = inputStream.read();
    while (byteInt != -1)
    {
        byteStream.write(byteInt);
        byteInt = inputStream.read();
    }

    byteArray = byteStream.toByteArray();
    inputStream.close();
    return byteArray;
}
catch (IOException e)
{
    //...
}

これは機能しますが、Java 7のNIOのものを使用して、これを行うためのより簡単でより良い方法があることを望んでいました。 パス)を取得する必要があると思います。 クラスパスでこのパスを表すオブジェクトですが、その方法がわかりません。

これが非常に簡単なことである場合は、お詫び申し上げます。私はそれを理解することができません。助けてくれてありがとう。

13
dnc253

パスは、ファイルシステム上のファイルを表します。クラスパスからリソースを読み取ることは役に立ちません。あなたが世話をしているのは、ストリームからすべてを読み取り(あなたがしている方法よりも効率的に)、それをバイト配列に書き込むヘルパーメソッドです。 Apachecommons-ioまたはGuavaがそれを支援します。たとえば、グアバの場合:

byte[] array = 
    ByteStreams.toByteArray(this.getClass().getClassLoader().getResourceAsStream(resourceName));

そのためだけにGuavaまたはcommons-ioを依存関係に追加したくない場合は、いつでもそれらのソースコードを読み取って、独自のヘルパーメソッドに複製できます。

7
JB Nizet

これは私にとってはうまくいきます。

import Java.nio.file.Files;
import Java.nio.file.Paths;

// fileName: foo.txt which lives under src/main/resources
public String readFileFromClasspath(final String fileName) throws IOException, URISyntaxException {
    return new String(Files.readAllBytes(
                Paths.get(getClass().getClassLoader()
                        .getResource(fileName)
                        .toURI())));
}
28
shreyas

私が理解している限り、必要なのはリソースに対してReadableByteChannelを開くことです。これにより、NIOを使用してリソースを読み取ることができます。

これは良いスタートになるはずです、

// Opens a resource from the current class' defining class loader
InputStream istream = getClass().getResourceAsStream("/filename.txt");

// Create a NIO ReadableByteChannel from the stream
ReadableByteChannel channel = Java.nio.channels.Channels.newChannel(istream);
2

ClassLoader.getResource()を確認する必要があります。これは、リソースを表すURLを返します。ファイルシステムに対してローカルである場合は、file://URLになります。その時点で、スキームなどを取り除くことができ、それからあなたはあなたがやりたいことを何でもすることができるファイル名を持っています。

ただし、file://パスでない場合は、通常のInputStreamにフォールバックできます。

1
Will Hartung