Bilddatei kopieren, aber ohne verluste und ohne zu großen Speicherverbrauch

stevey

Aktives Mitglied
Hi Leute,
ich habe für meine Eltern ein Programm geschrieben, mit dem sie die vielen Bilder von unserer Kamera ansehen können und direkt in eine Liste schieben können, welche dann die ausgewählten Bilder enthält und gespeichert wird. Es ist schon alles fertig, nur das speichern macht noch Probleme. Ich habe es bis jetzt so gelöst, dass ich das Bild vom Originalverzeichnis ins Programm lade, mittels ImageIO.read und dann wieder in das neue Verzeichnis mittels ImageIO.write speichere. es ist also ein einfacher Kopiervorgang. das problem ist dann allerdings das Bildformat des gespeicherten Bildes. entweder ich speichere es als .jpg, dann ist allerdings die Qualität wgen der komprimierung nicht mehr so gut. andererseits, wenn ich es als .png speichere ist die qualität zwar die gleiche, aber der Speicherbedarf, also die Dateigröße erheblich größer als beim Ausgangsbild.

ich hoffe ihr könnt mir irgendwie weiterhelfen, das Bild in gleicher Qualität und gleicher Dateigröße zu speichern, euer stevey
 
G

Gastredner

Gast
Verwende ein beliebiges Codeschnipsel zum Kopieren von Dateien, findest du über Google in wenigen Sekunden. Du musst die Bilder nicht als Bilder einlesen, wenn auch ein einfacher Kopiervorgang der Dateien reicht.
 

stevey

Aktives Mitglied
Hmm, dann hab ich vorhin entweder nicht genau genug gesucht, oder war einfach zu faul ein Codesnipsel zu testen. Mit folgender Methode hats funktioniert :
Java:
public void copyFile(File in, File out) throws Exception 
	{
        FileInputStream fis = new FileInputStream(in);
        FileOutputStream fos = new FileOutputStream(out);
        byte[] buf = new byte[1024];
        int i = 0;
        while((i=fis.read(buf))!=-1) 
        {
            fos.write(buf, 0, i);
        }
        fis.close();
        fos.close();
    }

Mfg stevey
 

Kr0e

Gesperrter Benutzer
Für die Zukunft: 1024 Byte Buffer sind ein Witz. Bei Bildern machst bestimmt nichts aus, aber wenn du iwann mal < 1 Gb DAteien kopierst, dann wirst du merken, was ihc meine...

Nimm bei modernen Sataplatten ruhig < 64kb große Buffer. Um die maximale Geschwindigkeit mit minimaler CPU Last zu erreichen, nimm 1 MB große Puffer.
 

Volvagia

Top Contributor
Schau dir mal den FileChannel an, der soll angeblich sehr viel schneller als Lesen/Schreiben direkt per Stream sein. Habs selbst nicht getestet aber wüsste auch nicht warum andere lügen sollten.

btw. warum 1 MB? Moderne HDDs haben ja bereits Buffer mit 8, 16 oder sogar noch mehr MB. Wäre es da nicht vorteilhafter, den Buffer voll zu füllen, bevor man dem Schreibvorgang startet, indem man ihm gleich so viel wie möglich schickt? Sonst muss er ja unnötig oft zwischen Source und Dest hin- und hersteuern.
 
Zuletzt bearbeitet:

Kr0e

Gesperrter Benutzer
Ja stimmt, natürlich wären größere Buffer noch besser. - doof formuliert.

Aber ich sehe das häufig, dass so kleine Puffer genommen werden... Also 8192 oder so... Da wäre 1Mb schon ne echte Verbesserung. Und fileChannel sind schneller, da dort direkte Puffer genommen werden und die Daten keinen Umweg über die JVM nehmen müssen...
 

stevey

Aktives Mitglied
sorry für die dumme Frage, aber was genau ist denn ein Buffer und wie arbeitet der code von oben überhaupt? hab den einfach ausm Internet kopiert, weil ich das Programm einfach fertig haben wollte.
 

Volvagia

Top Contributor
Der Buffer speichert die gelesenen bytes zwischen, um sie quasi zwischen In- und Outputstream zu übertragen. Ein Array wird verwendet, damit die Köpfe nicht nach jeden gelesenen Byte zwischen den beiden Dateien hin und herschwenken müssen, sondern in einen durchgelesen/schrieben werden kann. (Natürlich nur solange defragmentiert ist.)


read(byte[]) ließt die Daten beginnend mit Feld 0 aus bis der Buffer voll ist, und liefert zurück wie viel gelesen wurde oder -1, wenn nichts mehr da ist. Das ist in der Regel aber nicht immer buffer.lenght oder "Dateigröße - bisher gelesene Daten". Ich weiß aber nicht mehr in welchen Fall es nicht so war.

Code:
Reads up to byte.length bytes of data from this input stream into an array of bytes. This method blocks until some input is available.

This method simply performs the call read(b, 0, b.length) and returns the result. It is important that it does not do in.read(b) instead; certain subclasses of FilterInputStream depend on the implementation strategy actually used.
Code:
Reads bytes from this byte-input stream into the specified byte array, starting at the given offset.

This method implements the general contract of the corresponding read method of the InputStream class. As an additional convenience, it attempts to read as many bytes as possible by repeatedly invoking the read method of the underlying stream. This iterated read continues until one of the following conditions becomes true:

    The specified number of bytes have been read,
    The read method of the underlying stream returns -1, indicating end-of-file, or
    The available method of the underlying stream returns zero, indicating that further input requests would block. 

If the first read on the underlying stream returns -1 to indicate end-of-file then this method returns -1. Otherwise this method returns the number of bytes actually read.

Subclasses of this class are encouraged, but not required, to attempt to read as many bytes as possible in the same fashion.

write macht halt genau das umgekehrte, also schreibt den Inhalt des Buffers im Stream.
Am Ende schließt close noch die Streams damit u. a. die Dateihandler wieder freigegeben werden, das umbedingt in ein finally setzen.
 

stevey

Aktives Mitglied
das würde ja dann heißen, je größer der buffer, umso schneller geht das speichern.das hat sich auch so bei testen gezeigt(beim kopieren von 100 bildern). stimmt das?
 

Volvagia

Top Contributor
Nein, die optimale Buffergröße setzt sich aus vielen verschiedenen Faktoren zusammen. Da die aber idR. Maschinenabhängig sind wird mehr oder weniger geraten. Wenn dir der Kopiervorgang zu langsam ist und auch der FileChannel keine wirkliche Besserung bringt kannst du ja immer noch ändern und testen. Es gibt hier irgendwo eine Benchmark-Programmbasis, mit der du das sicher testen kannst. Aber ich beweifel irgendwie, dass sich beim Kopieren von Fotos überhaupt eine so starke Verzögerung zeigt, die eine Änderung nötig macht.
 

Kr0e

Gesperrter Benutzer
Aber ja, je größer der Buffer umso besser.... Aber auch nicht den Arbeitsspeicher vergessen ;)
Am ALLER BESTEN wäre es, die Datei komplett in den Arbeitsspeicher zu laden und dann zu schreiben.
 

HoaX

Top Contributor
Aber ja, je größer der Buffer umso besser.... Aber auch nicht den Arbeitsspeicher vergessen ;)
Am ALLER BESTEN wäre es, die Datei komplett in den Arbeitsspeicher zu laden und dann zu schreiben.

Nö.

Wenn du alles in den Speicher lädst, dann musst du die komplette Zeit warten bis der Lesevorgang vorbei ist, und dann nochmal bis alles geschrieben ist, nebenläufig kann da nichts passieren.

Wenn du blockweise liest kann etwas nebenläufig laufen, nämlich das Schreiben. Die Daten werden bei Schreiben erstmal in des Puffer des OS/Platte geschrieben und der Schreibaufruf im Code kehrt bereits zurück. So können bereits während das OS die Daten noch schreibt weitere Daten gelesen und verarbeitet werden.
 

Kr0e

Gesperrter Benutzer
Aber uach nur wenn es um 2 Festplatte geht ;) Beim Kopieren auf einer Datei auf einer Festplatte ist es ja eh sequentiell... Ansonsten hast recht.. War gestern schon was spät...
 

HoaX

Top Contributor
Selbst bei einer Platte wird es was bringen. Du hast ja noch die Verarbeitungszeit im Programm während welcher die Daten aus dem Puffer geschrieben werden. Und dann natürlich noch das Multithreading, welches deine Anwendung schlafen legt.
 

Kr0e

Gesperrter Benutzer
Ein kleiner Test:

Java:
        ByteBuffer b = ByteBuffer.allocateDirect(1024 * 1024 * 110);

        FileChannel in = new FileInputStream("D:/TEST.MOV").getChannel();
        FileChannel out = new FileOutputStream("D:/TEST2.MOV").getChannel();

        Stopwatch s = new Stopwatch(true);


        in.read(b);

        b.flip();

        out.write(b);

        System.out.println(s.getTime());

Stopwathc ist eine Klasse von mir... Im Prinzip System.currentTimeMillies();

Dateigröße: 108 MB. Zeit: 953.0 Millisekunden.


Java:
        ByteBuffer b = ByteBuffer.allocateDirect(1024 * 64);

        FileChannel in = new FileInputStream("D:/TEST.MOV").getChannel();
        FileChannel out = new FileOutputStream("D:/TEST2.MOV").getChannel();

        Stopwatch s = new Stopwatch(true);
        while(in.read(b) != -1) {
            b.flip();
            out.write(b);
            
            b.clear();
        }
        

        System.out.println(s.getTime());

Dateigröße: 108 MB. Zeit: 771.0 Millisekunden.

Damit wäre bewiesen, dass du Recht hast. Auch wenn das Ergebnis knapp ist^^
 

HoaX

Top Contributor
Zumal 108mb je nach OS locker noch vom Betriebssystem gepuffert werden.
Wenn ich hier unter Linux Dateien auf den USB-Stick ziehe bricht die Rate erst ab >250Mb ein, weil dann die Puffer voll sind.
So ein Test sollte schon mit Dateien > 1Gb gemacht werden.

PS: Knapp würde ich das nicht nennen, das ist eine Beschleunigung um fast 20% ...
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
R Bilddatei exportieren AWT, Swing, JavaFX & SWT 0
S Java weigert sich Bilddatei zu verarbeitet -.- AWT, Swing, JavaFX & SWT 2
B Problem bei der Erstellung einer Bilddatei aus einem JPanel AWT, Swing, JavaFX & SWT 16
K Bilddatei mit Filechooser auswählen und anzeigen/impotieren AWT, Swing, JavaFX & SWT 18
M Java Dateien kopieren mit Fortschrittsbalken AWT, Swing, JavaFX & SWT 13
izoards Ordner Rekursiv kopieren - Fortschritt? AWT, Swing, JavaFX & SWT 5
E JLabel kopieren AWT, Swing, JavaFX & SWT 31
VPChief Gibt es eine möglichkeit Dateien aus der jar datei zu kopieren? AWT, Swing, JavaFX & SWT 46
J SWT Textfeld markieren und kopieren AWT, Swing, JavaFX & SWT 0
F JavaFX textField Ausgabe automatisch kopieren AWT, Swing, JavaFX & SWT 7
L Image in anderes kopieren AWT, Swing, JavaFX & SWT 0
S Swing Style Attribute aus JTextPane kopieren AWT, Swing, JavaFX & SWT 1
S Swing Kopieren einer vollständigen Zeile einer JTable AWT, Swing, JavaFX & SWT 3
F Bilder ineinander kopieren AWT, Swing, JavaFX & SWT 3
D Schnelles kopieren von Pixeln in ein BufferedImage AWT, Swing, JavaFX & SWT 25
GUI-Programmer InputStream zu File kopieren - JPrograssbar anzeigen AWT, Swing, JavaFX & SWT 10
D Applet FTP Ordner kopieren AWT, Swing, JavaFX & SWT 3
P Objekt kopieren AWT, Swing, JavaFX & SWT 2
S Dateien kopieren mit ProgressBar AWT, Swing, JavaFX & SWT 6
Landei Swing JTable - Tabellenzeile kopieren AWT, Swing, JavaFX & SWT 2
Daniel_L jEditorPane - Formatierten Text in Zwischenablage kopieren? AWT, Swing, JavaFX & SWT 2
S Inhalt einer JTable kopieren? (GlazedLists) AWT, Swing, JavaFX & SWT 2
H explorer in java - datein kopieren AWT, Swing, JavaFX & SWT 5
M JPanel Inhalt kopieren AWT, Swing, JavaFX & SWT 5
G AbstractTableModel kopieren AWT, Swing, JavaFX & SWT 4
O Panel "kopieren" ? AWT, Swing, JavaFX & SWT 6
H JTable Text aus mehreren Zellen in einer Spalte kopieren? AWT, Swing, JavaFX & SWT 3
E SWT: Tabellen-Inhalt kopieren AWT, Swing, JavaFX & SWT 2
T BufferedImage kopieren AWT, Swing, JavaFX & SWT 3
D Inhalt eines JPanel kopieren AWT, Swing, JavaFX & SWT 7
A Kopieren aus JTextArea nicht zulassen AWT, Swing, JavaFX & SWT 6
R Kopieren in Java AWT, Swing, JavaFX & SWT 2
U Was ist ein Shape, also klar ein Objekt, aber was ist damit gemeint (Graphics2d)? Und was sidn affinetransformationen AWT, Swing, JavaFX & SWT 1
pkm MainFrame durch Actionlistener auffrischen, aber wie? AWT, Swing, JavaFX & SWT 2
G JavaFX , Duplicate erzeugt aber ich weis nicht wo AWT, Swing, JavaFX & SWT 4
HoT Sortieren von ein paar Zeilen in einer Tabelle, aber nicht die ganze Tabelle AWT, Swing, JavaFX & SWT 3
J Warum kann ich die Spaltennummer in der Konsole anzeigen, diese aber nicht speichern ? AWT, Swing, JavaFX & SWT 6
J Injection - Aber Controller sind null AWT, Swing, JavaFX & SWT 3
A Swing Datei lässt sich zwar speichern, aber nicht laden (Inhalt im JTextField anzeigen) AWT, Swing, JavaFX & SWT 18
X JavaFX Einfache FX Application, aber wie alte Features umgehen? AWT, Swing, JavaFX & SWT 10
M Swing Code funktioniert auf Windows aber nicht Linux... AWT, Swing, JavaFX & SWT 3
Blender3D Meine Swing Anwendung läuft unter Windows 10 und Ubuntu aber nicht auf Windows 7 AWT, Swing, JavaFX & SWT 16
Joker4632 JButton nicht sichtbar, aber funktionsfähig AWT, Swing, JavaFX & SWT 8
A Swing Programm funktioniert aber zwei Buttons werden angezeigt AWT, Swing, JavaFX & SWT 3
K Swing Textfeld verstecken aber benutzen AWT, Swing, JavaFX & SWT 15
Z Swing Frame wird geöffnet, aber ist ohne Inhalt AWT, Swing, JavaFX & SWT 0
K Fenster mittig im Vollbildschirm - ok, aber ... AWT, Swing, JavaFX & SWT 2
D Swing JFreeChart Crosshair Label - setPreferredSize oder ähnliches, aber wo ? AWT, Swing, JavaFX & SWT 1
Tausendsassa Frame öffnet aber zeigt keinen Inhalt... AWT, Swing, JavaFX & SWT 10
O JTabeddpane aber jedes JPanel als eigene Klasse anlegen AWT, Swing, JavaFX & SWT 7
P jtabel Zeilen auswählbar, aber nicht editierbar AWT, Swing, JavaFX & SWT 3
D Passwort [Aber mit 3 Versuchen] Funktioniert nicht wie erwartet AWT, Swing, JavaFX & SWT 4
A Swing Koordinatensystem wird gezeichnet verschwindet aber und die Einteilungen bleiben nicht bestehen AWT, Swing, JavaFX & SWT 5
C Applet Applet funktioniert in Eclipse aber nicht in Browser AWT, Swing, JavaFX & SWT 1
Tom299 JavaFX AnchorPane resizen, aber wie? AWT, Swing, JavaFX & SWT 3
wolfgang63 JavaFX Transparenter Hintergrund aber sichtbare Buttons AWT, Swing, JavaFX & SWT 6
J JavaFX Anwendung läuft in eclipse, nicht aber exportiert AWT, Swing, JavaFX & SWT 2
S JList ist leer, aber DefaultListModel hat die Daten? AWT, Swing, JavaFX & SWT 9
X Swing 1 JButton bedeckt meine ganze Frame aber Warum? AWT, Swing, JavaFX & SWT 2
X Swing Ein neues Fenster öffen aber ohne ein extra Prozess zu starten AWT, Swing, JavaFX & SWT 1
X AWT Graphics2D zum LWJGL Display hinzufügen aber wie? AWT, Swing, JavaFX & SWT 4
V kann ich in einer Klasse stage und scene deklarieren, aber in anderen Klassen Inhalte hinzufügen ? AWT, Swing, JavaFX & SWT 5
N Programm läuft perfekt in Eclipse aber nicht in .JAR AWT, Swing, JavaFX & SWT 3
F Swing String[] in JTextArea ausgeben. Jeder Eintrag in neue Zeile, aber ohne "\n"- Geht das? AWT, Swing, JavaFX & SWT 3
TheJavaKid JFrame defokusieren aber im Vordergrund behalten AWT, Swing, JavaFX & SWT 0
brunothg Swing JTable -> AUTO_RESIZE_OFF aber das Fenster ausfüllen AWT, Swing, JavaFX & SWT 0
J JFrame maximierbar aber nicht resizable AWT, Swing, JavaFX & SWT 6
D JTable markier- aber nicht veränderbar AWT, Swing, JavaFX & SWT 10
E Angehängtes Layout, aber wie? AWT, Swing, JavaFX & SWT 12
O getValueAt liefert "", aber es wird was angezeigt AWT, Swing, JavaFX & SWT 12
S JTable Zellinhalt markierbar aber nicht editierbar AWT, Swing, JavaFX & SWT 4
V Swing Wochenplaner in Swing erstellen! Aber wie? AWT, Swing, JavaFX & SWT 13
M Swing eigene Dialoge, aber wie genau? AWT, Swing, JavaFX & SWT 5
B Swing JDialog modal, aber trotzdem Frame auswählbar AWT, Swing, JavaFX & SWT 2
D JDialog alwaysOnTop, aber nur innerhalb der Applikation AWT, Swing, JavaFX & SWT 3
Asamandra LayoutManager GridBagLayout - Komponenten (mit fill?) vergrößern aber Proportionen dabei erhalten? AWT, Swing, JavaFX & SWT 3
J JMenuBar ist geaddet, aber nicht im Frame. Wo ist der Fehler? (inkl. Code) AWT, Swing, JavaFX & SWT 2
J Swing JDialog blokiert mehrere JFrames - soll aber nur den aufrufenden blockieren AWT, Swing, JavaFX & SWT 4
L SWT Drop erfolgreich, aber GUI-Aktion abgebrochen AWT, Swing, JavaFX & SWT 4
G Swing resizeable aber nur y-Achse nur wie? AWT, Swing, JavaFX & SWT 5
M Swing JMenu verdeckt durch Komponente (aber kein AWT und Swing mix!?) AWT, Swing, JavaFX & SWT 3
N Swing JSpinner mit Datum aber ohne Uhrzeit AWT, Swing, JavaFX & SWT 2
propra Doppelklick von Einzelklick unterscheiden, aber richtig ... AWT, Swing, JavaFX & SWT 10
J Swing JTable: Komplette Zeile aber ohne Spalten markieren AWT, Swing, JavaFX & SWT 11
T speichern funktioniert,aber öffnen nicht AWT, Swing, JavaFX & SWT 2
C JFrame ohne Titelleiste, aber mit Borders AWT, Swing, JavaFX & SWT 2
M Fenster aufteilen, aber mit welchem LayoutManager? AWT, Swing, JavaFX & SWT 10
K Modaler Dialog aber trotzdem Aktualisierung des MainFrames AWT, Swing, JavaFX & SWT 6
M Swing MVC Pattern verstanden, aber Probleme bei der Umsetzung AWT, Swing, JavaFX & SWT 5
J Mehrere JRadioButtons, aber nur 1 darf ausgewählt sein AWT, Swing, JavaFX & SWT 4
F JTable soll mit Buttons befüllt werden, aber nicht in jede Zelle einer Spalte AWT, Swing, JavaFX & SWT 3
S Swing Grundprinzip String ausgeben, aber wie? AWT, Swing, JavaFX & SWT 6
J Swing JCheckBox enabled, aber graues Kästchen AWT, Swing, JavaFX & SWT 2
F Bild auf JPanel, aber wie? AWT, Swing, JavaFX & SWT 6
O Swing JButton werden richtig gewechselt aber die Maus macht die alten wieder Sichtbar?? AWT, Swing, JavaFX & SWT 5
G SWT-App läuft nicht unter OSX, unter Win aber problemlos AWT, Swing, JavaFX & SWT 3
F ActionListener von JButton funktioniert mit JFrame aber nicht mit JDialog AWT, Swing, JavaFX & SWT 2
L Swing Serverbrowser, aber welche componenten? AWT, Swing, JavaFX & SWT 2
F In Textfeld Kommazahl anzeigen aber ohne Komma eingeben AWT, Swing, JavaFX & SWT 14
T JTable: editieren bei Doppelklick deaktivieren, aber... AWT, Swing, JavaFX & SWT 2

Ähnliche Java Themen

Neue Themen


Oben