Загрузка файла в ресурсы с помощью FileInputStream

Я знаю безопасный способ открыть файл в ресурсах:

  InputStream is = this.getClass().getResourceAsStream("/path/in/jar/file.name");  

теперь проблема в том, что мой файл является моделью для решающего устройства в пакете Weka Wrapper и the вершитель класс имеет только метод:

  public void load(File file) throws Exception 

load берет файл и открывает его как FileInputStream. Ты видишь путь? Я бы очень хотел ... например, отправить модель, поместив ее в ресурсы. Я думал создать временный файл, написать содержимое модели в temp файл, а затем передать временный файл Weka, но это так грязно.. другие варианты?

1 ответов


Я вижу 2 решения:

Решение 1

прочитайте ressource пути к классам во временный файл и удалите его после вызова load(File)

InputStream cpResource = this.getClass().getClassLoader().getResourceAsStream("file.name");
File tmpFile = File.createTempFile("file", "temp");
FileUtils.copyInputStreamToFile(cpResource, tmpFile); // FileUtils from apache-io
try {
    decider.load(tmpFile);
} finally {
    tmpFile.delete();
}

решение 2

если загрузчик классов, который загружает ресурс, является URLClassLoader, вы можете попытаться найти абсолютное имя файла. Но это!--11-->работает, только если ресурс, который вы хотите, существует в виде файла в файловой системе. Это не работает, если файл содержится в сосуд.

ClassLoader classLoader = this.getClass().getClassLoader();
if(classLoader instanceof URLClassLoader){
    URLClassLoader urlClassLoader = URLClassLoader.class.cast(classLoader);
    URL resourceUrl = urlClassLoader.findResource("file.name");

    if("file".equals(resourceUrl.getProtocol())){
        URI uri = resourceUrl.toURI();
        File file = new File(uri);
        decider.load(file);
    }
}

Я бы предложил написать класс утилиты, который пытается найти абсолютный файл через загрузчик классов или, если он не может получить его таким образом, использует подход temp file в качестве резервного.

или более объектно-ориентированным способом:

    public class FileResourceTest {

    public static void main(String[] args) throws IOException {
        File resourceAsFile = getResourceAsFile("file.name");
        System.out.println(resourceAsFile);
    }

    private static File getResourceAsFile(String resource) throws IOException {
        ClassLoader cl = FileResourceTest.class.getClassLoader();
        File file = null;
        FileResource fileResource = new URLClassLoaderFileResource(cl, resource);
        try {
            file = fileResource.getFile();
        } catch (IOException e) {
            fileResource = new ClasspathResourceFileResource(cl, resource);
            file = fileResource.getFile();
        }
        return file;
    }

    public static interface FileResource {

        public File getFile() throws IOException;

    }

    public static class ClasspathResourceFileResource implements FileResource {

        private ClassLoader cl;
        private String resource;

        public ClasspathResourceFileResource(ClassLoader cl, String resource) {
            this.cl = cl;
            this.resource = resource;
        }

        public File getFile() throws IOException {
            InputStream cpResource = cl.getResourceAsStream(resource);
            File tmpFile = File.createTempFile("file", "temp");
            FileUtils.copyInputStreamToFile(cpResource, tmpFile);
            tmpFile.deleteOnExit();
            return tmpFile;
        }

    }

    public static class URLClassLoaderFileResource implements FileResource {

        private ClassLoader cl;
        private String resource;

        public URLClassLoaderFileResource(ClassLoader cl, String resourcePath) {
            this.cl = cl;
            this.resource = resourcePath;
        }

        public File getFile() throws IOException {
            File resourceFile = null;
            if (cl instanceof URLClassLoader) {
                URLClassLoader urlClassLoader = URLClassLoader.class.cast(cl);
                URL resourceUrl = urlClassLoader.findResource(resource);
                if ("file".equals(resourceUrl.getProtocol())) {
                    try {

                        URI uri = resourceUrl.toURI();
                        resourceFile = new File(uri);
                    } catch (URISyntaxException e) {
                        IOException ioException = new IOException(
                                "Unable to get file through class loader: "
                                        + cl);
                        ioException.initCause(e);
                        throw ioException;
                    }

                }
            }
            if (resourceFile == null) {
                throw new IOException(
                        "Unable to get file through class loader: " + cl);
            }
            return resourceFile;
        }

    }
}

вы также можете использовать thrid библиотека партии, как commons-vfs, что позволяет ссылаться на файл в банке. Е. Г. jar:// arch-file-uri[! absolute-path]. Поскольку commons-vfs указывает собственный FileObject это представляет собой файл, который вы все равно должны скопировать содержимое в локальный java.io.File адаптироваться к Decider.load(File) API-интерфейс.