Как мне записать файл в правильный каталог, независимо от того, запускается ли программа из jar или из IDE? - PullRequest
1 голос
/ 25 марта 2019

У меня проблемы с записью в текстовый файл, когда моя программа запускается двумя разными способами. Я могу либо заставить его работать правильно при запуске в качестве jar или из NetBeans, но не оба.

Я добавил свою папку ресурсов в качестве исходного пакета в Netbeans, и это заставляет мою программу работать правильно в IDE, но не при работе в качестве jar. Если у меня нет папки ресурсов в качестве исходного пакета, а вместо этого она находится только в корневой папке моего проекта, она корректно запускается из jar, но не из IDE. Я пытаюсь преобразовать мою программу в веб-приложение java, поэтому я бы хотел, чтобы она работала в обоих направлениях, но, если в этом нет необходимости, сообщите мне.

Сначала я выясняю, был ли мой код запущен из банки, чтобы я мог отделить свою логику в будущем. На данный момент это та же логика в любом случае. Этот код работает в IDE, но не сохраняется при запуске из фляги. FILEPATH - это путь к одному из двух файлов с высокими показателями, который будет выглядеть как «data / classichighscores.txt». временный файл - это пустой текстовый файл, уже созданный в том же каталоге.

  /**
     * saves the data to its own text file.
     */
    public void save() {
        File dataFile = null;
        File tempFile = null;

        String className = this.getClass().getName().replace('.', '/');
        String classJar = this.getClass().getResource("/" + className + ".class").toString();
        if (!classJar.startsWith("jar:")) {
            dataFile = new File(ClassLoader.getSystemResource(FILEPATH).getFile());
            tempFile = new File(ClassLoader.getSystemResource("data/myTempFile.txt").getFile());
        } else {
            dataFile = new File(ClassLoader.getSystemResource(FILEPATH).getFile());           
            tempFile = new File(ClassLoader.getSystemResource("data/myTempFile.txt").getFile());
        }
        try {
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
                    new FileOutputStream(tempFile), "UTF-8"));

            for (String line : FILEDATA) {
                bw.write(line);
                bw.newLine();
           }

            bw.close();
            dataFile.delete();
            tempFile.renameTo(dataFile);
            tempFile.createNewFile();
        } catch (IOException ex) {
            System.err.println(tempFile.toString());
            System.err.pritnln(dataFile.toString());

В прошлом я также менял свой XML-файл и файл манифеста, что может быть связано с моей проблемой. Я вставил этот код, чтобы мой файл jar и ресурсы находились в одной папке дистрибутива.

<?xml version="1.0" encoding="UTF-8"?>

<project name="TheLostWand" default="default" basedir=".">
    <description>Builds, tests, and runs the project TheLostWand.</description>
    <import file="nbproject/build-impl.xml"/>
    <!--adding resources to dist folder-->
    <target name="-post-jar">
        <mkdir dir="${dist.dir}/resources"/>
        <copy todir="${dist.dir}/resources">
            <fileset dir="${basedir}/resources" />
        </copy>
    </target>

</project>

Я добавил строку Class-Path.

Manifest-Version: 1.0
X-COMMENT: Main-Class will be added automatically by build
Class-Path: resources/  

Я ожидаю, что мой текстовый файл будет отредактирован и сохранен с добавленной высокой оценкой. Он работает правильно при запуске из IDE, но не при запуске из банки. Я могу удалить папку ресурсов из исходного пакета, и она будет работать из jar, но не из IDE.

1 Ответ

1 голос
/ 25 марта 2019

Для сохранения текстовых файлов я бы рекомендовал сериализацию.

//Credit to Jaroslaw Janas
    public void save(String filepath, Object obj) {
//        get the folder
//        if no folder create a new one
        File folder = new File("foldername");
        if (!folder.exists()){
            folder.mkdirs();
        }

        try {
            FileOutputStream file = new FileOutputStream(filepath);
            ObjectOutputStream out = new ObjectOutputStream(file);
            out.writeObject(obj);
            out.close();
            file.close();
        } catch (IOException ex) {
            System.out.println("IOException is caught");
        }
    }

//    this method loades the saved object
//    from a location passed in as an argument
    public Object load(String filepath) {
        Object obj = null;
        try {
            // reading from the file
            FileInputStream file = new FileInputStream(filepath);
            ObjectInputStream in = new ObjectInputStream(file);

            // deserialization
            obj = in.readObject();

            in.close();
            file.close();

        } catch (IOException ex) {
            System.out.println("IOException");
        } catch (ClassNotFoundException ex) {
            System.out.println("ClassNotFoundException");
        }
        return obj;
    }

Для универсального каталога% AppData% может быть хорошим выбором.

...