Подтвердить что ты не робот

Чтение файла из classpath с помощью Java 7 NIO

Я довольно долго искал эту проблему, но все результаты указывают на решения до 7 Java NIO. Я использовал материал NIO для чтения в файлах из определенного места в файловой системе, и это было намного проще, чем раньше (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)
{
    //...
}

В то время как это работает, я надеялся, что есть более простой/лучший способ сделать это с материалами NIO в Java 7. Я предполагаю, что мне нужно получить Path, который представляет этот путь в пути к классам, но я не уверен, как это сделать.

Прошу прощения, если это очень простая вещь. Я просто не могу этого понять. Спасибо за помощь.

4b9b3361

Ответ 1

Путь представляет файл в файловой системе. Это не помогает читать ресурс из пути к классам. То, что вы заботитесь, - это вспомогательный метод, который читает все для потока (более эффективно, чем то, как вы это делаете), и записывает его в массив байтов. Apache commons-io или Guava могут помочь вам в этом. Например, с помощью Guava:

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

Если вы не хотите добавлять Guava или commons-io к своим зависимостям только для этого, вы всегда можете прочитать их исходный код и дублировать его на свой собственный вспомогательный метод.

Ответ 2

Это работает для меня.

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

Ответ 3

Насколько я понимаю, вы хотите открыть 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);

Ответ 4

Вы должны посмотреть ClassLoader.getResource(). Это возвращает URL-адрес, который представляет ресурс. Если он локален для файловой системы, это будет URL file://. В этот момент вы можете отключить схему и т.д., А затем у вас есть имя файла, с которым вы можете делать все, что хотите.

Однако, если это не путь к файлу://, вы можете вернуться к нормальному InputStream.