Hallo Community,
für mein Programm möchte ich eine Textdatei erstellen, in die ich Variablen schreiben kann, sodass sie beim Beenden nicht verloren gehen.
Nun habe ich das auch mit:
f = new File("./users/list.txt");
try{
s = new Scanner(f);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
für einen “absoluten” Pfad hinbekommen. (also dass die .jar, in einem Ordner liegt, in dem auch der Ordner “user” ist mit der list.txt-Datei)
Jetzt würde ich die Textdatei gerne in die Ressourcen speichern.
Aber wie komme ich jetzt an diese ran?
Ich habe es mit:
URL url = getClass().getResource("/users/list.txt");
f = new File(url.toString());
try{
s = new Scanner(f);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
versucht, aber dann kommt immer die FileNotFoundException.
du kannste in die laufende JAR nicht reinspeichern sondern nur aus ihr lesen
aus diesem grund gibt es auch nur die methode InputStream getResourceAsStream()
beim start sperrt java automatisch das jar exklusiv, also auch “von außen reinschreiben” fällt flach
musst du daten speichern bleibt dir nur die möglich ins dateisystem, ins jar geht nicht
Dein Ansatz war schon richtig, das Problem ist nur, dass dein Ordner “users” nicht im Classpath drin ist. Du müsstest dafür “.” mit in den Classpath aufnehmen, entweder in MANIFEST.MF für das Jar oder eben beim Aufruf:
java -cp . -jar foobar.jar
Dann befindet sich auch der Ordner “users” im Classpath und die Datei wird auch gefunden.
oder die standard-zeile für einen absoluten pfad File dir=(new File(this.getClass().getProtectionDomain().getCodeSource().getLocation().toURI())).getParentFile();
wenn aus einem JAR ausgeführt zeigt “dir” auf den ordner in dem das JAR liegt
[QUOTE=Akeshihiro]Dein Ansatz war schon richtig, das Problem ist nur, dass dein Ordner „users“ nicht im Classpath drin ist. Du müsstest dafür „.“ mit in den Classpath aufnehmen, entweder in MANIFEST.MF für das Jar oder eben beim Aufruf:
java -cp . -jar foobar.jar
Dann befindet sich auch der Ordner „users“ im Classpath und die Datei wird auch gefunden.[/QUOTE]
Der Ordner „users“ liegt im Ordner „res“, welchen ich zum Build Path hinzugefügt habe.
Ich möchte die Textdatei benutzten um den Ordner-Pfad zu speichern in dem das Spiel „installiert“ ist.
(Ich würde ungern in die Registry schreiben, da ich da nichts kaputt machen möchte, wenn ich ein Fehler mache).
So dass die jar irgendwo liegen kann, die Speicherdaten jedoch an einer anderen Stelle.
Aber vielleicht ist das keine so gute Idee. Ich sollte die JAR einfach mit in den Ordner legen in dem die Speicherdaten sind oder?
Bei meiner Idee habe ich mich am Spiel „Minecraft“ inspiriert.
Die Minecraft.exe kann ich überall auf der Festplatte ablegen.
Die Speicherdatein, wie Spielwelten liegen dann irgendwo in %appdata%/roaming/.minecraft/…
Diesen Pfad kann man Launcher jedoch auch ändern.
Dein Buildpath gilt aber nur für Eclipse, nicht für die Jar, die schlussendlich erzeugt wird. Startest du die Jar, ist nur das im Classpath eingetragen, was auch im Manifest drin steht und sonst nichts. Was in deinem Build-Path drin steht, ist also vollkommen egal, der gilt nur für die Entwicklungsarbeiten, aber nicht für das Deployment. Und eben der Ordner des Jars, also “.”, fehlt bei dir anscheinend, daher wird auch nichts gefunden.
URL url = getClass().getResource("/users/list.txt");
f = new File(url.toString());
try{
s = new Scanner(f);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
Wenn die Datei in der .jar ist klappt das mit dem File-Object nicht. Falls du in die Datei schreiben willst sollte sie aber sowieso nicht in der .jar sondern neben der .jar liegen.
z.b.
myapp.jar
users
—list.txt
[QUOTE=Firephoenix]Wenn die Datei in der .jar ist klappt das mit dem File-Object nicht. Falls du in die Datei schreiben willst sollte sie aber sowieso nicht in der .jar sondern neben der .jar liegen.
z.b.
myapp.jar
users
—list.txt
URL url = getClass().getResource("/users/list.txt");
f = new File(url.toString());
try{
s = new Scanner(f);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
[/QUOTE]
Wenn du eine Runnable Jar erstellst und keine normale Jar, in der du alles selbst einstellst, dann wird alles, was sich im Build-Path befindet, in die Jar kopiert. Die Bilder befinden sich also innerhalb der Jar, somit innerhalb des Classpath und werden deshalb auch gefunden. Gleiches würde für list.txt gelten, aber wie Firephoenix bereits sagte, funktioniert File auf Jar-Inhalte nicht. Was du machen kannst, ist, Templates im Jar zu haben, diese zu laden und auch zu benutzen. Aber das Schreiben muss dann auf dem Dateisystem stattfinden. Wo ist egal, solange die nötigen Schreibrechte vorhanden sind.
Das Programm liest seinen eigenen Quelltext aus dem “Inneren” der Jar-Datei.
Zur Lösung deines Problems taugt es freilich nicht, da man nichts in einer zur Laufzeit ausgeführten Jar-Datei ablegen kann.
Du könntest aber vielleicht beim Beenden eine neue Jar-Datei erstellen und dort alles hinein speichern, was du zur Laufzeit neben deiner Jar abgelegt hast.
ich würde mit den java.util.prefs.Preferences doch die Registry benutzen. Das geht so einfach und man kann kaum was kaputt machen. Hier ein kleines Beispiel:
import java.io.File;
import java.util.prefs.Preferences;
public class PrefsDemo {
public static void main(String[] args) throws Exception {
Preferences pfad;
// ergibt den Registry-Knoten: HKEY_CURRENT_USER\Software\JavaSoft\Prefs\meinprogramm
pfad = Preferences.userRoot().node("meinprogramm");
// speichert den Pfad, wo diese main ausgeführt wird
pfad.put("installationspfad", new File(".").getAbsolutePath());
// ein Highscore als Beispiel
pfad.putInt("highScore", 6);
// Ausgabe zu Demo-Zwecken
System.out.println("Punkte = " + pfad.getInt("highScore", -1));
}
}
Ich ebenfalls nicht. Der Grund, warum die Registry unter Windows immer mehr zugemüllt wird, sind solche Sachen. Unter Linux kenne ich auch keine Anwendungsfall, in dem in eine Art Registry geschrieben wird (doch, etwas in der Art gibt es da auch). Der übliche Weg bei *nix-Systemen ist einen unsichtbaren Ordner im Home-Verzeichnis anzulegen und dort die ganze Konfiguration, Rankings, etc. abzulegen. Und dieser Trend scheint sich inzwischen auch in der Windows-Welt so langsam durchzusetzen. Auch wenn nicht jeder Software die Konvention mit dem Punkt als erstes Zeichen pflegt (unsichtbare Ordner bei *nix beginnen mit einem Punkt), so legen zumindest immer mehr Programme im User-Verzeichnis die Informationen ab. Ist nach meiner subjektiven Wahrnehmung zwar noch immer die Minderheit, aber es wird mehr.
Die Idee eine zentrale Ablage für Einstellungen und anderes in einer Registry war vor etlichen Jahren sicherlich nicht schlecht und ist für viele auch heute sicherlich noch eine gute Idee, aber scheinbar wandelt sich das und immer mehr Programmierer gehen einen anderen Weg, vor allem Crossplattform-Entwickler. Mit den plattformspezifischen Einzelheiten will sich inzwischen doch niemand mehr rumärgern und die Windows-Registry ist sowieso ein heikles Pflaster, da die Nebenwirkungen gravierende Folgen haben können, wenn was schief gelaufen ist.