Java 如何在应用程序运行时从包中打开文本文件?

Java 如何在应用程序运行时从包中打开文本文件?,java,javafx,netbeans,fxml,embedded-resource,Java,Javafx,Netbeans,Fxml,Embedded Resource,我有一个JavaFX应用程序,其中有一个按钮,我想打开一个我已经编写的“帮助文件”,当用户按下按钮时,我想在默认文本编辑器中打开它。此文件位于包含主FX类、控制器和FXML文件的包中。我试着做了一些不同的事情来打开文件,但没有一个成功。这是我目前使用的一种方法,在我看来它应该是有效的,但事实并非如此。我做错了什么?所有内容所在的包的名称都被命名为“nutritionfx”,只是为了澄清,此代码是控制器中的一个方法 //method to open help file when help butt

我有一个JavaFX应用程序,其中有一个按钮,我想打开一个我已经编写的“帮助文件”,当用户按下按钮时,我想在默认文本编辑器中打开它。此文件位于包含主FX类、控制器和FXML文件的包中。我试着做了一些不同的事情来打开文件,但没有一个成功。这是我目前使用的一种方法,在我看来它应该是有效的,但事实并非如此。我做错了什么?所有内容所在的包的名称都被命名为“nutritionfx”,只是为了澄清,此代码是控制器中的一个方法

//method to open help file when help button is pressed
@FXML private void handleHelpButton(ActionEvent event) throws IOException, URISyntaxException {
    URL url = this.getClass().getResource("/nutritionfx/help.txt");
    File file = new File(url.toURI());
    Desktop.getDesktop().edit(file);
}

下面是一个示例应用程序,它演示了您提出的解决方案

从打包的文件创建一个新文件,然后打开该文件

示例应用程序将从与应用程序打包的资源中读取数据,并将其保存到用户主目录中应用程序目录(名为“.FileEditor”)中的本地文件中。用户可以在文本编辑器中编辑文本,并将修改后的文本保存到本地文件中。下次运行应用程序时,它将读取并使用修改后的文本,而不是来自打包资源的文本

import javafx.application.Application;

import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.Collectors;

public class FileEditor extends Application {

    private static final Path USER_FILE_PATH = Paths.get(
        System.getProperty("user.home"), 
        ".FileEditor"
    );

    private static final String SOURCE_FILE_NAME = "xyzzy.txt";

    @Override
    public void start(Stage stage) throws Exception {
        if (!Files.isDirectory(USER_FILE_PATH)) {
            Files.createDirectory(USER_FILE_PATH);
        }

        Path editableFilePath = Paths.get(USER_FILE_PATH.toString(), SOURCE_FILE_NAME);
        if (!Files.exists(editableFilePath)) {
            Files.copy(
                FileEditor.class.getResourceAsStream(SOURCE_FILE_NAME),
                editableFilePath
            );
        }

        String text = Files.readAllLines(
                editableFilePath
        ).stream()
                .collect(Collectors.joining("\n"));

        TextArea textArea = new TextArea(text);

        MenuItem save = new MenuItem("Save...");
        save.setOnAction(event -> {
            try {
                Files.write(editableFilePath, textArea.getText().getBytes());
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
        MenuItem exit = new MenuItem("Exit");
        exit.setOnAction(event -> stage.hide());
        MenuBar menuBar = new MenuBar(
                new Menu("File", null, save, exit)
        );

        BorderPane layout = new BorderPane();
        layout.setTop(menuBar);
        layout.setCenter(textArea);

        Scene scene = new Scene(layout);
        stage.setScene(scene);
        stage.show();
    }


    public static void main(String[] args) {
        launch(args);
    }
}
示例源资源
xyzy.txt
,放置在与FileEditor.java代码相同的目录中,并由生成系统复制到资源输出和打包目录:

You are in a maze of twisty passages, all alike.
xyzzy
You are inside the building.

此示例使用JavaFX应用程序中的TextArea编辑文件,但您也可以使用以下结构在默认系统文本编辑器中轻松打开:

getHostServices().showDocument(
    editableFilePath.toUri().toURL().toExternalForm()
);

文件中包装资源uri不会使其成为文件。如果资源文件在jar中,并且编辑器需要一个文件,那么它将无法访问该文件。我所知道的将资源作为文件进行访问的唯一方法是将资源的内容复制到一个文件中……因此,最好从打包的文件中创建一个新文件,然后打开该文件?这会在用户计算机上创建一个新文件吗?是的,确实如此,进行跟踪。