内存映射类路径资源

时间:2017-03-03 12:26:10

标签: java

对于从我的服务器(嵌入在JAR中)提供的静态资源 - 我想记忆映射它们。

我写了以下内容:

    try (InputStream is = getClass().getResourceAsStream(classpathItem)) {
        byte[] bytes = ByteStreams.toByteArray(is);

        ByteBuffer directBuffer = ByteBuffer.allocateDirect(bytes.length);
        directBuffer.put(bytes);
        directBuffer.flip();

        return directBuffer;
    }

然后我想,Java中必须有一个选项来执行此操作(可能是JVM参数)。有这样的事吗?

2 个答案:

答案 0 :(得分:1)

这个答案有点晚了,但我偶然发现了这个问题。

简短的回答是否定的,你可以从你的jar中记忆地图资源。 这是由于资源如何存储在jar本身中。 jar文件实际上只是一个zip文件,资源是zip文件的内容。这就是为什么您无法获得File或除了URLInputStream之外的任何内容来获取jar内的资源。 URL只允许您打开InputStream,而InputStream本身只允许您流式传输资源的内容,并将其解压缩。

有趣的是,如果ZipFileSystem支持内存映射,这将是可能的。

如果ZipFileSystem支持内存映射,工作的代码段:

// Hack to get URL to running jar
String path = Main.class.getResource("Main.class").toString().split("!")[0];
FileSystem fs = FileSystems.newFileSystem(URI.create(path), 
        Collections.singletonMap("create", "true"));
Path p = fs.getPath("/path/to/my/resource");
FileChannel fc = FileChannel.open(p);
MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());

问题是你得到了这个:

Exception in thread "main" java.lang.UnsupportedOperationException
        at com.sun.nio.zipfs.ZipFileSystem$4.map(ZipFileSystem.java:799)
        at com.example.Main.main(Main.java:25)

你可以做到最好,因为你很可能会得到糟糕的表现。 Zip文件将文件布局为平面和压缩文件,因此没有首先为自己分配内存映射缓冲区并将内容解压缩到其中,就没有简单的方法来布局它们。

可能为时已晚,无法帮助您,但可能会阻止某人稍后进行狂追:P

答案 1 :(得分:0)

您可以使用静态内容创建战争。

显示目录:

war
  WebContent
    META-INF
    WEB-INF
      classes
      web.xml
    index.html 
    ... etc static contents
  build.xml

<强>的web.xml

<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>

<强>的build.xml

    

<target name="war" description="Bundles the application as a WAR file" >
    <mkdir dir="WebContent/WEB-INF/classes"/>
    <copy includeemptydirs="false" todir="WebContent">
                <fileset dir="../dist">
                    <include name="**/*.html"/>
                    <include name="**/*.js"/>
                    <include name="**/*.css"/>
                    <include name="*.html"/>
                    <include name="*.js"/>
                    <include name="*.css"/>
                    <include name="**/**/*.png"/>
                </fileset>
    </copy>

    <war destfile="ScadaLTS.war"
                    basedir="WebContent"
                    needxmlfile="false">
    </war>
</target>   

建立命令:蚂蚁战争

提供静态内容可能比创建jar更简单。