Scheinbar zufällig hin und wieder: Can't create an ImageOutputStream!

Voldemort92

Mitglied
Moin moin!

Ich habe gerade folgendes Problem:
Ich habe mehrere BufferedImages, welche ich nacheinander (nicht unmittelbar nacheinander, eher im Abstand von ca. 1 Sekunde) per writeImage (siehe unten) in die selbe File schreibe. An sich klappt das auch, das Problem besteht darin, dass hin und wieder (manchmal nach 20 BufferedImages, mal erst nach 200) folgende Exception geworfen werden:

java.io.FileNotFoundException: test.png (Zugriff verweigert)
IOException.getMessage() = "Can't create an ImageOutputStream!"

Danach ist test.png nicht mehr vorhanden.

Der Vollständigkeit halber hier kurz der Code - die ImageIO.write Zeile wirft den Fehler. Aber halt nicht immer, nur hin und wieder... vielleicht hat ja jemand eine Idee.
Code:
 public void writeImage(BufferedImage image){
    String name = "test.png";
    File pngImg = new File(name);
    try
    {
      ImageIO.write(image, "png", pngImg);
    }
    catch(IOException e)
    {
      System.out.println("Konnte die Datei nicht erstellen:\n" + e.getMessage());
    }
    pngImg.deleteOnExit();
  }

Bei Bedarf kann ich auch die komplette Exception aus der Konsole abtippen.
Danke im Voraus!

PS: "Zugriff verweigert" klingt zwar danach, aber ich habe natürlich die nötigen Rechte, dort Files zu speichern - sonst würde es ja auch immer meckern und nicht nur manchmal.
 
Mal ganz davon abgesehen, dass ich nicht den Sinn verstehe eine Bilddatei jede Sekunde zu überschreiben:

1. Stellt dein Aufrufender Code sicher, dass die Schreibeoperation fertig ist, bevor du eine neue startest? Wenn die Platte wegen anderen Sachen ausgelastet ist, könnte das ja mal länger als deine Sekunde dauern.
2. Wieso erstellst du jedes mal wieder die gleiche File Instanz, welche du dann auch noch jedes mal mit "deleteOnExit" markierst? Geht das nicht statisch?
 
1. also aktuell habe ich sinngemäß
Code:
writeImage(img);
wait(1);
writeImage(img2);
Sollte das nicht automatisch sicherstellen, dass das erste writeImage fertig ist? Ansonsten könnte es tatsächlich daran liegen (und ich sollte mir Threads in Java noch mal ansehen).

2. Stimmt, das geht.
 
Sollte das nicht automatisch sicherstellen, dass das erste writeImage fertig ist? Ansonsten könnte es tatsächlich daran liegen (und ich sollte mir Threads in Java noch mal ansehen).
Der gezeigte Code ja, aber bei was "sinngemäßem" kann das völlig anders aussehen 😉

2. Wieso erstellst du jedes mal wieder die gleiche File Instanz, welche du dann auch noch jedes mal mit "deleteOnExit" markierst? Geht das nicht statisch?
Was meinst du mit statisch? 😉 static ist meistens nicht die sinnvollste Lösung, in diesem beschränkten Fall haben beide Varianten keinen großen Vorteil, aber dafür ist das auch einfach zu klein...
 
Okay, dann nicht nur sinngemäß 😀

Code:
while()
{
    changeImage(image);
    writeImage(image);
    try
    {
        TimeUnit.SECONDS.sleep(1);
    }
    catch(InterruptedException e)
    {
        e.printStackTrace();
    }
}
 
@Voldemort92 Für wen änderst du das Bild? Greift ein fremdes Programm direkt auf diese Datei zu? Kann es sein, dass dieses den Zugriff ggf. sperrt?

Was meinst du mit statisch? 😉 static ist meistens nicht die sinnvollste Lösung, in diesem beschränkten Fall haben beide Varianten keinen großen Vorteil, aber dafür ist das auch einfach zu klein...

Erscheint mir besser als ständig die gleiche Instanz aufzubauen und direkt wieder vom GC entsorgen zu lassen. Auch wenn ich gerade noch mal nachgeschaut hab und "deleteOnExit" selber dafür sorgt keine doppelten Pfade entgegen zu nehmen. Da File aber auch Immutable ist, bietet es sich doch für ein "static final" an.
 
Die png Datei wird vom Programm erstellt und nach Beendigung gelöscht, zwischendurch passiert mit ihr auch nichts außerhalb des Programms.

Vereinfacht gesagt habe ich ein Ausgangsbild, was ich iterativ mutiere, bis es bestimmte Eigenschaften besitzt. Viel mehr passiert da eigentlich auch nicht.
Mir ist inzwischen nur aufgefallen, dass das Problem nicht oder zumindest viel seltener auftritt, wenn ich den Ordner nicht offen hab, in dem das Bild gespeichert wird. Ich wollte mir einfach anschauen wie es sich langsam verändert.. jetzt hab ich den Ordner mal geschlossen und es gab jetzt seit 8000 Iterationen keinen Fehler, kann es da nen Zusammenhang geben?
 
Windows erstellt in bestimmten Ordner-Ansichten Thumbnails von Bildern (z.B. thumbs.db), damit du diese direkt im Explorer sehen kannst. Könnte ich mir zumindest als Erklärung vorstellen.
 
Erscheint mir besser als ständig die gleiche Instanz aufzubauen und direkt wieder vom GC entsorgen zu lassen.
Lokale Variablen kann die JVM völlig wegoptimierten und Objekte erstellen und direkt wegschmeißen kann für den GC durchaus besser sein, als sie lange zu behalten. Rein aus Laufzeitoptimierungsgründen würde ich sowas nicht ohne sehr viel Profiling und Benchmarking machen 😉

Da File aber auch Immutable ist, bietet es sich doch für ein "static final" an.
Das ganze als Konstante anlegen, einfach weil sich eine konstante anbietet, ist da schon sinnvoller - die Frage ist dann nur, ob es bei einer Datei bleibt, oder ob nicht sehr bald eh schon mehrere kommen, bspw. alle 1000 Iterationen das Bild speichern.
 

Zurück
Oben