6

我知道该getResourceAsStream()方法,但是读取文件的解析器存在问题,整个结构被实现为期望 aFileInputStream()并且getResourceAsStream()返回一个无法转换的输入流。这种情况有什么简单的“修复”吗?

4

3 回答 3

20

JAR 文件中包含的资源本身不是文件,因此无法使用FileInputStream. 如果您的代码绝对需要 a FileInputStream,那么您需要使用 提取数据getResourceAsStream(),将其复制到临时文件中,然后FileInputStream将该临时文件的 a 传递给您的代码。

当然,将来,永远不要编写代码来期望诸如 之类的具体实现InputStream,你总是会后悔的。

于 2009-12-16T09:59:31.410 回答
5

我最近遇到了同样的问题。我们使用的第三方库从 FileInputStream 读取,但资源可以在任何地方,在 JAR 或远程中。我们曾经写入临时文件,但开销太大。

更好的解决方案是编写一个包装 InputStream 的 FileInputStream。这是我们使用的类,

public class VirtualFileInputStream extends FileInputStream {

    private InputStream stream;

    public VirtualFileInputStream(InputStream stream) {
        super(FileDescriptor.in); // This will never be used
        this.stream = stream;
    }




    public int available() throws IOException {
        throw new IllegalStateException("Unimplemented method called");
    }


    public void close() throws IOException {
        stream.close();
    }


    public boolean equals(Object obj) {
        return stream.equals(obj);
    }


    public FileChannel getChannel() {
        throw new IllegalStateException("Unimplemented method called");
    }


    public int hashCode() {
        return stream.hashCode();
    }


    public void mark(int readlimit) {
        stream.mark(readlimit);
    }


    public boolean markSupported() {
        return stream.markSupported();
    }


    public int read() throws IOException {
        return stream.read();
    }


    public int read(byte[] b, int off, int len) throws IOException {
        return stream.read(b, off, len);
    }


    public int read(byte[] b) throws IOException {
        return stream.read(b);
    }


    public void reset() throws IOException {
        stream.reset();
    }


    public long skip(long n) throws IOException {
        return stream.skip(n);
    }


    public String toString() {
        return stream.toString();
    }

}
于 2009-12-16T15:26:12.253 回答
0

不要相信你的解析只适用于 FileInputStream 而不是 InputStream

如果这是真实情况,您必须使用该解析器

2 个选项

  1. 使用适配器模式创建一个 CustomFileInputStream 并覆盖各自的方法,更多地将 getResourceAsStream 数据重定向到 CustomFileInputStream

  2. 将您的 getResourceAsStream 保存到临时文件中,并解析临时文件,然后在完成后删除该文件

于 2009-12-16T12:48:22.320 回答