如何在不将文件保存到磁盘的情况下打开文件

5

我的问题:如何在不先将文件保存到磁盘的情况下打开文件(使用系统默认[外部]文件程序)?

我的情况:我有资源中的文件,我想直接显示它们而不必先将它们保存到磁盘。例如,我有一个xml文件,并且我想在用户的计算机上使用读取xml文件的默认程序打开它,而不必先将它保存到磁盘。

我一直在做的事情:到目前为止,我只是将文件保存到临时位置,但我不知道何时他们不再需要该文件,因此我不知道何时/是否删除它。这是我用于此的SSCCE代码(好吧,除了资源,这基本上是sscce...您必须自己创建它):

package main;

import java.io.*;

public class SOQuestion {

  public static void main(String[] args) throws IOException {
    new SOQuestion().showTemplate();
  }

  /** Opens the temporary file */
  private void showTemplate() throws IOException {
    String tempDir = System.getProperty("java.io.tmpdir") + "\\BONotifier\\";
    File parentFile = new File(tempDir);
    if (!parentFile.exists()) {
      parentFile.mkdirs();
    }
    File outputFile = new File(parentFile, "template.xml");
    InputStream inputStream = getClass().getResourceAsStream("/resources/template.xml");
    int size = 4096;
    try (OutputStream out = new FileOutputStream(outputFile)) {
      byte[] buffer = new byte[size];
      int length;
      while ((length = inputStream.read(buffer)) > 0) {
        out.write(buffer, 0, length);
      }
      inputStream.close();
    }
    java.awt.Desktop.getDesktop().open(outputFile);
  }
}

这取决于您要将文件加载到哪个程序中。它是否具有某些API或在某个端口上列出?根据您的操作系统,即使该文件仍在程序中使用,您也可以删除该文件--这样,您就可以使用当前方法,而不必担心用户何时完成查看。 - martinez314
@whiskeyspider:使用Desktop类,它会自动确定默认值。如果可能的话,我希望有一个多平台的解决方案 :) - kentcdodds
http://superuser.com/questions/430466/in-windows-can-i-redirect-stdout-to-a-named-pipe-in-command-line - Blessed Geek
3个回答

4
由于这行代码:
String tempDir = System.getProperty("java.io.tmpdir") + "\\BONotifier\\";

我推断你正在使用Windows操作系统。你可以轻松地使这段代码多平台运行。
回答你的问题是:不可以。Desktop类需要知道文件的位置,以便使用参数调用正确的程序。请注意,该类中没有接受InputStream的方法,它可能是一种解决方案。
无论如何,我看不到问题在哪里:你创建一个临时文件,然后在编辑器或其他应用程序中打开它。这很好。在Linux中,当应用程序退出(正常退出)时,其所有临时文件都将被删除。在Windows中,用户需要触发临时文件的删除。但是,只要没有安全约束,我就不明白问题出在哪里。毕竟,临时文件是操作系统的关注点。

感谢您的建议。如果您能指导我如何使其多平台化,我将会点赞+1 :) 虽然我很感激您的回答,无论如何我都会点赞。 - kentcdodds
非常简单。不要使用'\'作为目录分隔符,改用char/String常量。这个常量将让你的程序自动从Windows中的'\'更改为Linux中的'/',而不是依靠其中之一。http://docs.oracle.com/javase/1.4.2/docs/api/java/io/File.html#separatorChar - Baltasarq

1

根据您的应用程序需要多么便携,可能没有“一刀切”的解决方案。但是,您可以自己稍微帮助一下:

至少在Linux下,您可以使用管道(|)将一个程序的输出直接导向另一个程序的输入。一个简单的例子(使用gedit文本编辑器)可能是:

echo "hello world" | gedit

这将会(对于gedit)打开一个新的编辑器窗口,并在一个新的未保存的文档中显示内容“hello world”。


以上的问题是,这可能不是一个独立于平台的解决方案。它适用于Linux和可能的OS X,但我没有Windows安装在这里进行测试。
此外,您需要自己找出默认编辑器。这个旧问题和它的链接文章提供了一些关于如何解决这个问题的想法。

0

我不是很明白你的问题。根据我的理解,你的问题有两种可能性:

  1. 打开一个已存在的文件,并且你想要操作它的流,但是不想保存任何修改。

  2. 创建一个文件,以便你可以使用文件 I/O 操作文件流,但是你不想将流保存到文件中。

无论哪种情况,你的主要动机都是利用文件 I/O 已经提供的功能来进行编程,是这样吗?

我感觉这个问题并不简单,我的回答可能并不是你所寻求的答案。然而,如果我的理解与你的问题相符...

如果你想要使用流 I/O,而不是使用 FileOutputStream 或 FileInputStream,那么为什么不使用非文件 InputStream 或 OutputStream 呢?你的文件 I/O 工具最终都会归结为操作 I/O 流。

http://docs.oracle.com/javase/7/docs/api/java/io/OutputStream.html

http://docs.oracle.com/javase/7/docs/api/java/io/InputStream.html

不需要涉及临时文件。


我编辑了我的问题。希望这能帮助你理解我的问题。 - kentcdodds

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接