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);
  }
}
4

3 回答 3

4

因为这条线:

String tempDir = System.getProperty("java.io.tmpdir") + "\\BONotifier\\";

我推断您正在使用 Windows。你可以很容易地使这个代码多平台,你知道的。

你的问题的答案是:不。Desktop 类需要知道文件的位置,以便使用参数调用正确的程序。请注意,该类中没有方法接受InputStream,这可能是一个解决方案。

无论如何,我看不出问题出在哪里:您创建了一个临时文件,然后在编辑器中打开它或其他任何东西。没关系。在 Linux 中,当应用程序(通常)退出时,它的所有临时文件都会被删除。在 Windows 中,用户需要触发临时文件删除。但是,如果您没有安全限制,我无法理解问题出在哪里。毕竟,临时文件是操作系统的关注点。

于 2012-10-18T21:54:21.020 回答
1

根据您的应用程序需要的可移植性,您的问题可能没有“一刀切”的解决方案。但是,您可以帮助自己一点:

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

echo "hello world" | gedit

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


上面的问题是,这可能不是一个独立于平台的解决方案。它适用于 Linux,也可能适用于 OS X,但我没有安装 Windows 来测试它。

此外,您需要自己找出默认编辑器。这个较旧的问题及其链接文章提供了一些关于这可能如何工作的想法。

于 2012-10-18T21:46:21.637 回答
0

我不太明白你的问题。我只能看到您的问题的两种可能性。

  1. 打开现有文件,您希望对其流进行操作,但不想保存任何修改。

  2. 创建一个文件,以便您可以使用文件 i/o 对文件流进行操作,但您不希望将流保存到文件。

无论哪种情况,您的主要动机是利用现有的文件 i/o 供您自行决定和编程乐趣,我说的对吗?

我觉得这个问题并不那么简单,我的答案可能不是你想要的答案。但是,如果我对问题的理解与您的问题不谋而合……

如果您希望使用 Stream io,而不是使用 FileOutputStream 或 FileInputStream 来打开 File 对象,为什么不使用非 File 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

无需涉及临时文件。

于 2012-10-18T22:04:17.203 回答