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

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

【问题讨论】:

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

标签: java inputstream fileinputstream


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

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

    2 个选项

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

    2. 将你的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 实现。
      猜你喜欢
      • 2013-09-29
      • 1970-01-01
      • 1970-01-01
      • 2016-09-05
      • 2015-09-19
      • 1970-01-01
      • 2011-01-24
      • 2015-10-07
      • 1970-01-01
      相关资源
      最近更新 更多