无法写入AppData

时间:2017-04-05 21:27:23

标签: java file javafx appdata

我正在JavaFX中制作一个小游戏,我想要一个Highscore系统。 因为我对数据库不太好,所以我将数据写入文本文件。 但这很容易编辑,所以我想把它写到AppData中的文本文件中。 所以我尝试了这一行:

File file = new File(System.getenv("AppData") + "\\" + [Namefoler\\NameFile]);

但它一直说我没有访问该文件夹。 写入和关闭文件是没有问题的,所以如果我把它写到与jar相同的目录中的文本文件中,我的系统工作正常。 但它不断抛出这些错误。

有人知道如何阻止这种情况,或者更好地解决我的问题吗?

提前致谢

1 个答案:

答案 0 :(得分:1)

这个答案与AppData无关,但您确实询问过其他解决方案,因此这是基于Preferences API的解决方案。该示例用于高分系统的基于首选项的API存储。该示例不加密数据。

您在问题中提到您担心用户修改偏好以捏造高分。加密或隐藏客户端应用程序的数据,使得用户无法修改数据是一个棘手的主张,所以我不会在这里讨论如何做到这一点。如果这是您的要求,那么您可以在互联网上研究其他信息,以获得实现这一目标的方法。

score system

ScoreStorage.java

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;

import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;

public class ScoreStorage {
    private static final int MAX_NUM_SCORES = 3;

    private static final String SCORE_PREFERENCE_KEY_PREFIX = "score-";

    private ObservableList<Integer> scores = FXCollections.observableArrayList();
    private Preferences scorePreferences = Preferences.userNodeForPackage(
        ScoreStorage.class
    );

    public ScoreStorage() throws BackingStoreException {
        for (String key: scorePreferences.keys()) {
            scores.add(scorePreferences.getInt(key, 0));
        }
    }

    public ObservableList<Integer> getUnmodifiableScores() {
        return FXCollections.unmodifiableObservableList(scores);
    }

    public void clearScores() {
        scores.clear();
        storeScores();
    }

    public void recordScore(int score) {
        int i = 0;
        while (i < MAX_NUM_SCORES && i < scores.size() && scores.get(i) >= score) {
            i++;
        }

        if (i < MAX_NUM_SCORES) {
            if (scores.size() == MAX_NUM_SCORES) {
                scores.remove(scores.size() - 1);
            }
            scores.add(i, score);
            storeScores();
        }
    }

    private void storeScores() {
        int i = 0;
        for (int score: scores) {
            scorePreferences.putInt(SCORE_PREFERENCE_KEY_PREFIX + i, score);
            i++;
        }
        while (i < MAX_NUM_SCORES) {
            scorePreferences.remove(SCORE_PREFERENCE_KEY_PREFIX + i);
            i++;
        }
    }
}

HighScoreApp.java

测试工具:

import javafx.application.Application;
import javafx.geometry.*;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;

import java.util.Random;
import java.util.prefs.BackingStoreException;

public class HighScoreApp extends Application {

    private static ScoreStorage scoreStorage;

    private Random random = new Random(42);

    @Override
    public void start(Stage stage) throws Exception {
        ListView<Integer> scoreList = new ListView<>(scoreStorage.getUnmodifiableScores());
        scoreList.setPrefHeight(150);

        Label lastScoreLabel = new Label();

        Button generateScore = new Button("Generate new score");
        generateScore.setOnAction(event -> {
            int lastScore = random.nextInt(11_000);
            lastScoreLabel.setText("" + lastScore);
            scoreStorage.recordScore(lastScore);
        });

        Button clearScores = new Button("Clear scores");
        clearScores.setOnAction(event -> scoreStorage.clearScores());

        HBox scoreGenerator = new HBox(10, generateScore, lastScoreLabel);
        scoreGenerator.setAlignment(Pos.BASELINE_LEFT);

        VBox layout = new VBox(10, scoreGenerator, scoreList, clearScores);
        layout.setPadding(new Insets(10));

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

    public static void main(String[] args) throws BackingStoreException {
        scoreStorage = new ScoreStorage();
        launch(args);
    }
}