如何使用 FileInputStream 访问 jar 中的 txt 文件?

Posted

技术标签:

【中文标题】如何使用 FileInputStream 访问 jar 中的 txt 文件?【英文标题】:How can I access a txt file in a jar with FileInputStream? 【发布时间】:2010-12-27 04:19:49 【问题描述】:

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

【问题讨论】:

这就是为什么最好对接口而不是实现进行编码。 您不应该将输入流转换为它们的实现。他们被认为用于实现管道和过滤器。它是,一个(文件)inputsrteam 从文件中读取,另一个解压缩(GZipI.S.),另一个断行(bufferedI.S.),另一个......等等。因此,如果您的程序需要一个字节流,则需要一个输入流(任何 I.S.),然后提供它的一些实现。如果您想将流与另一个连接转换:例如 new GZipInputStream(new FileInputStream(path))。 【参考方案1】:

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

当然,在未来,永远不要写代码期望像InputStream 这样的具体实现,你会永远后悔的。

【讨论】:

【参考方案2】:

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

如果这是真实情况,你必须使用那个解析器

2 个选项

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

    将你的getResourceAsStream保存到临时文件中,解析临时文件,完成后删除文件

【讨论】:

【参考方案3】:

我最近遇到了同样的问题。我们使用的第三方库从 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();
    


【讨论】:

+1 但我将其称为 FakeFileInputStream 以强调伪造事物的必要性:) 并鼓励不要使用具体的 FileInputStream 实现。

以上是关于如何使用 FileInputStream 访问 jar 中的 txt 文件?的主要内容,如果未能解决你的问题,请参考以下文章

37使用FileInputStream和FileOutputStream读取和写入

Java Inventory - 如何使用 FileInputStream 读取文件?

如何使用 loc[i,j] 根据索引值访问数据框中的特定值

如何在没有 OutOfMemory 错误的情况下从 FileInputStream 获取字节数组

使用 neo4j-graphql-js 时如何访问自定义 graphQL 解析器中的请求标头?

如何修复 Kotlin 中 FileInputStream 和 FileDescriptor 的错误路径