Eddie: FileOutputStream mit Datei innerhalb des Projekts erzeugen

Hallo allerseits,

ich brauche einen FileOutputStream, allerdings befindet sich die Datei im Classpath meines Projekts (der ja auf einem anderen System auchmal anders sein kann).
An anderer Stelle konnte ich einen InputStream (nicht FileInputStream!) verwenden, das ging mit

InputStream in = getClass().getResource("/subDir/Datei").openStream();

Nur den FileOutputStream krieg ich nicht hin :-(

Danke für eure Hilfe,
Eddie

--
Old men and far travelers may lie with authority.
  1. Hallo,

    ich brauche einen FileOutputStream, allerdings befindet sich die Datei im Classpath meines Projekts (der ja auf einem anderen System auchmal anders sein kann).
    An anderer Stelle konnte ich einen InputStream (nicht FileInputStream!) verwenden, das ging mit

    InputStream in = getClass().getResource("/subDir/Datei").openStream();

    Nur den FileOutputStream krieg ich nicht hin :-(

    Wirst du auch nicht, da eine Datei aus dem Classpath, die du auf diese
    Weise ermittelst, auch innerhalb einer JAR-Datei liegen könnte. Man
    kann aber keine Dateien innerhalb von Archiven (direkt) beschreiben.

    Du solltest dir eine andere Lösung einfallen lassen.

    Was willst du denn erreichen?

    Gruß
    Slyh

    1. Hallo Slyh,

      Wirst du auch nicht, da eine Datei aus dem Classpath, die du auf diese
      Weise ermittelst, auch innerhalb einer JAR-Datei liegen könnte. Man
      kann aber keine Dateien innerhalb von Archiven (direkt) beschreiben.

      Leuchtet mir ein.

      Was willst du denn erreichen?

      Ich will eine Property-Datei schreiben (mittels

      myProperty.store(outputStream, ...);

      Die Datei soll immer am selben Ort innerhalb der Package-Struktur sein, also z.B.

      c:/bla/blub/MeinProgramm/Properties/user.properties
      aber auch
      c:/wherever/MeinProgramm/Properties/user.properties

      Nur wie bekomme ich diesen FileOutputStream auf diese Datei?

      Danke für eure Hilfe,
      Eddie

      --
      Old men and far travelers may lie with authority.
      1. Hi,

        Die Datei soll immer am selben Ort innerhalb der Package-Struktur sein,

        Auf welcher Baumebene beginnt die Package-Struktur? (gemäß Java-Konvention erwarte ich nach einem Ordner namens "de"..).

        also z.B.

        c:/bla/blub/MeinProgramm/Properties/user.properties
        aber auch
        c:/wherever/MeinProgramm/Properties/user.properties

        Nur wie bekomme ich diesen FileOutputStream auf diese Datei?

        Annahme: "MeinProgramm" ist das Top-Level Package.

        // holen der URL
        URL url = getClass().getResource("/MeinProgramm/Properties/user.properties");

        hinweis: wenn die Klasse, die die Generation des OutputStreams übernimmt, im Package Properties liegt, genügt der Parameter "user.properties" (ohne führendes "/"!!!)

        // String Repräsentation der entsprechenden Datei
        String filePath = url.getFile();

        // OutputStream erzeugen
        OutputStream os = new FileOutputStream(filePath);

        if (url.getProtocol().indexOf("jar") == -1 ) {
            myProperties.store(os....);
        }

        Dies ist eine (ungetestete) Möglichkeit.

        Viele Grüße,
        Martin Jung

        1. Hallo,

          Annahme: "MeinProgramm" ist das Top-Level Package.

          // holen der URL
          URL url = getClass().getResource("/MeinProgramm/Properties/user.properties");

          Soweit geht das. Im Falle einer Datei innerhalb eines JAR-Archivs
          würde die URL dann z.B. so aussehen:

          file:/c:/programme/java/meinprogramm.jar!/de/mein/package/MeinProgramm.class

          // String Repräsentation der entsprechenden Datei
          String filePath = url.getFile();

          Das geht auch noch gut, weil hier keinerlei Überprüfung erfolgt.

          // OutputStream erzeugen
          OutputStream os = new FileOutputStream(filePath);

          Hier wird er dann mit einer FileNotFoundException rausfliegen, sofern
          die Datei in einem JAR liegt, weil er mit o.g. URL nichts anfangen
          kann.
          Wenn du diese Zeile aber noch in den untenstehende if-Block packen
          würdest, würde das prinzipiell natürlich gehen. Auch wenn man im
          Falle einer Datei innerhalb eines JAR-Archivs eben nichts gewonnen
          hätte... :-)

          if (url.getProtocol().indexOf("jar") == -1 ) {
              myProperties.store(os....);
          }

          Das ist aber eine sehr bastelige Abfrage! :)

          Gruß
          Slyh

          1. Hi Slyh,

            Hier wird er dann mit einer FileNotFoundException rausfliegen, sofern
            die Datei in einem JAR liegt, weil er mit o.g. URL nichts anfangen
            kann.
            Wenn du diese Zeile aber noch in den untenstehende if-Block packen
            würdest, würde das prinzipiell natürlich gehen.

            Ungetestet halt ;-)

            if (url.getProtocol().indexOf("jar") == -1 ) {
                myProperties.store(os....);
            }

            Das ist aber eine sehr bastelige Abfrage! :)

            Yep. Aber m.E. legitim, da der OP behauptet, er könne oder will die notwendigen Umstände garantieren. Wenn er dann später feststellt, dass ein Deployment in jar-form, die Ausführung aus der jar heraus und die Verwaltung der Properties nach Deinem Vorschlag doch möglicherweise sinnvoller ist, wird er in Zukunft sicher zu einem Nicht-Befürworter der gegenwärtig angestrebten Lösung mutieren (schwall...)

            Viele Grüße,
            Martin Jung

        2. Hallo Martin,

          Auf welcher Baumebene beginnt die Package-Struktur? (gemäß Java-Konvention erwarte ich nach einem Ordner namens "de"..).

          Äh, hab ich noch nie was von gehoert... ;-?

          Ich hab einfach nur ein Verzeichnis eingerichtet "mein_Projekt" und darunter dann direkt die die Hauptklassen.
          In Unterverzeichnissen wie /GUI oder /RPC sollen dann die entsprechenden anderen Klassen stehen...

          Das ist also nicht richtig so? Mir ist auch aufgefallen, dass es manchmal offenbar standardisierte Pfade zu geben scheint, z.B. "org.xml.sax". Nur sollte ich das selber auch machen? Und wie?

          Waere dankbar fuer Hinweise!
          Eddie

          --
          Old men and far travelers may lie with authority.
          1. Hi,

            Hallo Martin,

            Auf welcher Baumebene beginnt die Package-Struktur? (gemäß Java-Konvention erwarte ich nach einem Ordner namens "de"..).
            Äh, hab ich noch nie was von gehoert... ;-?

            z.B. http://java.sun.com/docs/books/tutorial/java/interpack/createpkgs.html ("Naming a Package").

            Ich hab einfach nur ein Verzeichnis eingerichtet "mein_Projekt" und darunter dann direkt die die Hauptklassen.
            In Unterverzeichnissen wie /GUI oder /RPC sollen dann die entsprechenden anderen Klassen stehen...

            Das ist bereits eine (gewisse) Package Organisation. Wenn Du eine "moderne" IDE verwendest, musst Du Dich um die Erzeugung von Verzeichnissen nicht mehr selbst kümmern, sondern es ist ausreichend, auf der (abstrakten) Package-Ebene zu denken. Übrigens, nach Konvention sind alle Package-Namen auschließlich klein geschrieben.

            Das ist also nicht richtig so?

            Falsch im technischen Sinne ist es nicht. Es ist eine Abweichnung von der Konvention.

            Viele Grüße,
            Martin Jung

      2. Hallo,

        Was willst du denn erreichen?
        Ich will eine Property-Datei schreiben (mittels

        myProperty.store(outputStream, ...);

        Die Datei soll immer am selben Ort innerhalb der Package-Struktur sein, also z.B.

        c:/bla/blub/MeinProgramm/Properties/user.properties
        aber auch
        c:/wherever/MeinProgramm/Properties/user.properties

        Naja, wie gesagt, das geht nicht, da sich die Dateien in einem JAR
        befinden könnten. Und diese Möglichkeit solltest du immer bedenken!

        Nur wie bekomme ich diesen FileOutputStream auf diese Datei?

        Ich würde das so nicht versuchen.

        Speichere die Properties-Datei doch besser in das Home-Verzeichnis
        des Benutzers. Dieses Verzeichnis kannst du über die System-Property
        "user.home" ermitteln. (Siehe java.lang.System.getProperty())

        Als Grundlage für die spezifische Property-Datei des Benutzers
        verwendest du einfach die o.g. Property-Datei aus dem JAR-Archiv bzw.
        dem Classpath.

        Immer wenn du die Einstellungen lesen möchtest, guckst du erst im
        Home-Verzeichnis des Benutzers nach, ob da schon die Property-Datei
        liegt. Wenn nicht, legst du sie dort an. (Die Datei sollte natürlich
        einen möglichst eindeutigen Namen haben.)
        Existiert sie dort schon, kannst du sie ja lesen (und dann auch
        schreiben.)

        Gruß
        Slyh

  2. Ahoi,

    ich brauche einen FileOutputStream, allerdings befindet sich die Datei im Classpath meines Projekts

    handelt es sich um eine Class-Datei? Die ist doch schreibgeschützt, wenn sie geladen ist.

    ansonsten würde ich mal folgendes versuchen: (ungetestet)
    FileInputStream fos = new FileOutputStream(getClass().getResource("/subDir/Datei").getPath());

    Gruß,
    MrWurf

    1. Hi,

      FileInputSream != FileOutputStream.

      Zum Schreiben von Resourcen hatte Slyh ja bereits sinnvolle (= in jedem Fall zu berücksichtigende) generelle Hinweise gegeben.

      Viele Grüße,
      Martin Jung

      1. Ahoi,

        FileInputSream != FileOutputStream.

        einigen wir uns auf FileInputScream ?

        Zum Schreiben von Resourcen hatte Slyh ja bereits sinnvolle (= in jedem Fall zu berücksichtigende) generelle Hinweise gegeben.

        und ich habe diese um einen in speziellen Fällen evtl. nützlichen Tip ergänzt.

        Gruß,
        MrWurf

        1. Hi,

          FileInputSream != FileOutputStream.
          einigen wir uns auf FileInputScream ?

          Von mir aus - es wurde allerdings nach einem FileOutputStream gefragt (scream....).

          Zum Schreiben von Resourcen hatte Slyh ja bereits sinnvolle (= in jedem Fall zu berücksichtigende) generelle Hinweise gegeben.
          und ich habe diese um einen in speziellen Fällen evtl. nützlichen Tip ergänzt.

          Wieso? Wie hilft dieser Tip (FileINPUTStream) bei der Beantwortung Frage "Wie kann ich eine Resource persistent ändern (= schreiben)?"?
          Oder meintest Du etwas anderes?

          Viele Grüße,
          Martin Jung

    2. Hallo allerseits,

      ansonsten würde ich mal folgendes versuchen: (ungetestet)
      FileInputStream fos = new FileOutputStream(getClass().getResource("/subDir/Datei").getPath());

      Nein, das gibt eine FileNotFoundException. Bin immer noch nicht weiter, wie in meiner anderen Antwort (https://forum.selfhtml.org/?t=89148&m=532588) zu sehen :-(

      Eddie

      --
      Old men and far travelers may lie with authority.