# Datei auf Desktop ausgeben



## ToffieFaye (7. Jun 2018)

Hallo liebe Java-Fans,

ich schreibe gerade ein Programm, dass eine csv-Datei auswertet (das klappt schon alles).
Damit das Programm diese Datei auswerten kann, muss die csv-Datei zuerst vom Nutzer mit Informationen gefüttert werden. Der Nutzer soll sie z.B. mittels Excel öffnen und nachdem er die Infos eingegeben hat, die Datei als csv-Datei abspeichern oder die csv-Datei direkt im Editor Fenster ändern.
Ich habe die csv-Datei bereits erstellt, aber ich frage mich, wie ich sie dem Nutzer übergeben kann.
Ich habe einen Befehl gefunden, der Dateien verschiebt und hatte überlegt, Java dann einfach zu sagen, dass es die File im Unterordner "Ressourcen" meiner jar-Datei dann auf dem Desktop speichert. Das hat bisher nicht geklappt.

```
Path temp = Files.move(filepath1, filepath2)
```
Hat jemand noch eine andere Idee?
Habe bisher kein Erfolg bei meiner Suche gehabt und freue mich wirklich riesig über jeden Tipp!

Ein dickes Dankeschön!
von der Fee


----------



## mrBrown (7. Jun 2018)

ToffieFaye hat gesagt.:


> Java dann einfach zu sagen, dass es die File im Unterordner "Ressourcen" meiner jar-Datei dann auf dem Desktop speichert.


In der jar-Datei kannst du zur Laufzeit nichts speichern, irgendwo außerhalb sollte aber problemos klappen


----------



## ToffieFaye (7. Jun 2018)

Ok, danke. Aber wie dann das? Ich meine, Ich muss die Datei ja irgendwie mitgeben. Also würdest du das Programm dann einfach in einen Ordner packen, der ebenfalls die csv enthält oder wie meinst du das?


----------



## mrBrown (7. Jun 2018)

Moment, vielleicht hab ich dich falsch verstanden: Willst du eine Datei, die in den resourcen liegt, auf den ganz normalen Desktop kopieren?


----------



## ToffieFaye (7. Jun 2018)

Ja. Ich möchte die Datei vom Programm ausgeben lassen. Also nutzerfreundlich zum Beispiel auf dem Desktop speichern.


----------



## mihe7 (7. Jun 2018)

ungetestet:

```
Files.copy(getClass().getResourceAsStream(resource), targetPath, StandardCopyOption.REPLACE_EXISTING);
```


----------



## T_T (8. Jun 2018)

ToffieFaye hat gesagt.:


> Ja. Ich möchte die Datei vom Programm ausgeben lassen. Also nutzerfreundlich zum Beispiel auf dem Desktop speichern.


Lass dem Nutzer doch entscheiden, wo er die Datei abspeichern mag? 

JavaFX File Chooser

Swing JFileChooser

(Mit der Annahme, dass es sich bei deinem besagten Programm, um ein grafisches Programm handelt)


----------



## ToffieFaye (8. Jun 2018)

Vielen Dank! Die Idee mit dem JFileChooser ist klasse.
Hab es jetzt so umgesetzt:

```
try {
                    String speicherort;
                    JFileChooser chooser = new JFileChooser();
                        chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
                    int rueckgabeWert = chooser.showDialog(null, "Datei hier speichern");
                   
                    // Abfrage, ob auf "Öffnen" geklickt wurde:
                    if(rueckgabeWert == JFileChooser.APPROVE_OPTION) {
                        // Speichern des Dateipfades des ausgewaehlten Ordners:
                        speicherort = chooser.getSelectedFile().getAbsolutePath();
                    } else {
                        speicherort = "";
                    }
                    Path temp = Files.copy
                            (Paths.get(pathOfExistingFile),
                             Paths.get(speicherort + "_newFile.csv"));

                    if(temp == null){
                        failException();
                    }       
                } catch (IOException ex) {
                    failException();
                }
```

Noch ein Problem besteht beim Benennen der gespeicherten Datei. Und zwar heißt die immer genau wie das Verzeichnis bzw. Ordner in dem ich sie speichern möchte. Hat jemand eine Idee, wie man das ändern kann?
Also z.B. heißt sie dann "Desktop_newFile.csv" (ich habe noch die Endung "_newFile.csv" drangehängt, siehe Code).
Besten Dank, echt!!


----------



## mihe7 (8. Jun 2018)

```
Paths.get(speicherort, "newFile.csv")
```


----------



## ToffieFaye (8. Jun 2018)

Danke, hat leider aber nicht funktioniert..


----------



## mihe7 (8. Jun 2018)

Evtl. willst Du ja was anderes.
Beim JFileChooser hast Du DIRECTORIES_ONLY eingesetellt, damit lässt Du den Benutzer ein Verzeichnis auswählen. D. h. getSelectedFile() liefert den Namen des Verzeichnisses, z. B. "C:\Users\XYZ\Desktop".
Wenn Du jetzt Paths.get(speicherort, "test.csv") schreibst, erhältst Du "C:\Users\XYZ\Desktop\test.csv".
Willst Du, dass der Benutzer selbst einen Namen vergibt, brauchst Du einfach nur die Zeile

```
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
```
entfernen.

Update: natürlich liefert dann getSelectedFile() bereits den vollständigen Pfad zur Datei (inkl. des vom Benutzer angegeben Dateinamens). D. h. Paths.get(speicherort) reicht in diesem Fall aus.


----------



## ToffieFaye (8. Jun 2018)

Danke! So habe ich gar nicht darüber nachgedacht!
Es ist irgendwie komisch. Am liebsten würde ich die Datei selbst benennen also FileChooser.DIRECTORIES_ONLY aktivieren. Wenn ich dann aber den String selbst bestimme, funktioniert es nicht, nur wenn er über den JFileChooser bestimmt wird..
Weißt du, ob ich in das JFileChooser Feld einen Namen "einprogrammieren" kann? Also eine Art Vorschlag für den Namen für den Nutzer, damit würde ich das Problem ja umgehen können.
Vielen lieben Dank!!! )


----------



## mihe7 (9. Jun 2018)

> Wenn ich dann aber den String selbst bestimme, funktioniert es nicht


Was funktioniert nicht?


----------



## ToffieFaye (9. Jun 2018)

```
Paths.get(speicherort, "test.csv"));
```
oder

```
Paths.get(speicherort + "/test.csv"));
```
(FileChooser.DIRECTORIES_ONLY ist aktiviert)

Update
also ich habe natürlich den ganzen Befehl drin.
Wenn ich 

```
Path temp = Files.copy
                            (Paths.get("Users/xyz/testStart.csv"),
                             Paths.get(speicherort + "_test.csv"));
```
eingebe, funktioniert es. Die Datei heißt dann aber wenn Speicherort zum Beispiel "Users/xyz/directory" ist folgendermaßen: "directory_test.csv"


----------



## mihe7 (9. Jun 2018)

Folgendes funktioniert wunderbar (Datei test.txt wird als test.csv an den vom Benutzer gewählten Ort gespeichert):


```
import java.nio.file.*;
import javax.swing.*;

public class Test {
    public void run() {
        JFileChooser chooser = new JFileChooser();
        chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
        if (chooser.showDialog(null, "Speichern") == JFileChooser.APPROVE_OPTION) {
            String ort = chooser.getSelectedFile().getAbsolutePath();
            try {
                Files.copy(Paths.get("test.txt"), Paths.get(ort, "test.csv"));
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new Test().run());
    }
}
```


----------



## ToffieFaye (9. Jun 2018)

Danke. Hmm, merkwürdig.
Ich habe dein Beispiel getestet (als Minimaltest), aber es funktioniert bei mir leider nicht.

```
java.nio.file.NoSuchFileException: /Users/toffiefee/Documents/HSB/HSB/test.csv
```
Das ist die Fehlermeldung. Ich weiß auch woran das liegt:
Und zwar muss der Nutzer oben im JFileChooser (bei mir zumindest) etwas eingeben, sonst kann er nicht auf "Speichern" klicken. Automatisch wird dort als Eingabe immer der aktuell ausgewählte Ordner angezeigt. Problem ist dann nur, dass der zweimal im Pfad gespeichert wird und es den Pfad dann natürlich gar nicht gibt.
Hast du eine Idee, wie ich das lösen kann?
Danke für die ganze Hilfe!!!


----------



## mihe7 (9. Jun 2018)

> Automatisch wird dort als Eingabe immer der aktuell ausgewählte Ordner angezeigt.


Das ist richtig.


> Problem ist dann nur, dass der zweimal im Pfad gespeichert wird


Das nicht :-o
Was liefert denn "System.out.println(chooser.getSelectedFile());" ?


----------



## ToffieFaye (9. Jun 2018)

System.out.println(chooser.getSelectedFile()); liefert:
/Users/toffiefee/Documents/HSB/HSB

Das meine ich eben.. also 2 mal das Directory.
Es muss halt ganz oben im Feld "Datei:" (siehe angehängter Screenshot) etwas eingetragen sein, damit man überhaupt den "Speichern" Button auswählen kann. Automatisch wird dort immer das ausgewählte Verzeichnis angegeben.
Und so sieht das aus:


----------



## mihe7 (9. Jun 2018)

Scheint mir ein Java-Bug zu sein. Dann eben den von Dir vorgeschlagenen Workaround nutzen:

```
import java.io.File;
import java.nio.file.*;
import javax.swing.*;

public class Test {
    public void run() {
        JFileChooser chooser = new JFileChooser();
        chooser.setSelectedFile(new File("test.csv"));

        if (chooser.showDialog(null, "Speichern") == JFileChooser.APPROVE_OPTION) {
            String ort = chooser.getSelectedFile().getAbsolutePath();
            try {
                Files.copy(Paths.get("test.txt"), Paths.get(ort));
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new Test().run());
    }
}
```


----------



## mrBrown (9. Jun 2018)

In dem Fall einfach nur den Ordner auswählen, anstatt in den Ordner zu wechseln und dessen Namen noch mal einzutragen.

Afaik ist das nur eine Unzulänglichkeit des Swing-Filechoosers, müsste mit dem JavaFX-DirectoryChooser nicht mehr auftreten.


----------



## ToffieFaye (9. Jun 2018)

Danke! Jetzt funktioniert es!


----------



## T_T (9. Jun 2018)

Du kannst dir den Namen, welchen der User eingegeben hat folgendermaßen ausgeben lassen:


```
String filename = chooser.getSelectedFile().getName();
```


----------



## mihe7 (9. Jun 2018)

Ein anderer Workaround, wenn man unbedingt mit DIRECTORIES_ONLY arbeiten will, wäre zu prüfen, ob das zurückgegebene File-Objekt ein existierendes Verzeichnis kennzeichnet:

```
File selected = chooser.getSelectedFile();
if (!selected.isDirectory()) { selected = selected.getParentFile(); }
```


----------

