Ich mache einige ungewöhnliche Datenmanipulation. Ich habe 36.000 Eingabedateien. Mehr kann dann gleichzeitig in den Speicher geladen werden. Ich möchte das erste Byte jeder Datei nehmen und es in eine Ausgabedatei einfügen, und dann das für die zweite und so weiter tun. Es muss nicht in einer bestimmten Reihenfolge erfolgen. Da die Eingabedateien komprimiert sind, dauert das Laden etwas länger und sie können nicht 1 Byte gleichzeitig gelesen werden. Ich am Ende mit einem Byte-Array jeder Eingabedatei.Zehntausende von Dateien lesen und in Millionen von Dateien in Java schreiben
Die Eingabedateien sind ungefähr ~ 1-6 MB unkomprimiert und ~ .3-1 MB komprimiert (verlustbehaftete Komprimierung). Die Ausgabedateien sind die Anzahl der Eingabedateien in Byte. ~ 36KB in meinem Beispiel.
Ich weiß, die ulimit kann auf einem Linux-Betriebssystem eingestellt werden und das Äquivalent kann unter Windows erfolgen. Obwohl diese Zahl erhöht werden kann, glaube ich nicht, dass OS Millionen von Dateien gleichzeitig schreiben werden.
Meine aktuelle Lösung besteht darin, 3000 oder so gepufferteWriter-Streams zu machen und jede Eingabedatei der Reihe nach zu laden und 1 Byte in 3000 Dateien zu schreiben und dann die Datei zu schließen und die nächste Eingabe zu laden. Bei diesem System muss jede Eingabedatei jeweils etwa 500 Mal geöffnet werden.
Die gesamte Operation dauert 8 Tage und ist nur ein Testfall für eine praktischere Anwendung, die mit größeren Eingabedateien, mehr davon und mehr Ausgabedateien enden würde.
Wenn Sie alle komprimierten Dateien im Speicher abfangen und sie dann nach Bedarf dekomprimieren, klingt das nicht praktisch und würde sich nicht auf größere Eingabedateien skalieren lassen.
Ich denke, die Lösung wäre zu puffern, was ich kann aus den Eingabedateien (weil Speicher Einschränkungen erlauben nicht alles zu puffern), und dann in Dateien sequentiell schreiben und dann noch einmal alles tun.
Allerdings weiß ich nicht, ob es eine bessere Lösung gibt, die etwas verwendet, das ich nicht gelesen habe.
BEARBEITEN Ich bin dankbar für die schnelle Antwort. Ich weiß, dass ich bei der Anwendung meiner Arbeit vage war und ich werde versuchen, das zu korrigieren. Ich habe grundsätzlich ein dreidimensionales Array [Bilder] [X] [Y] Ich möchte über jedes Bild iterieren und speichern Sie jede Farbe von einem bestimmten Pixel auf jedem Bild, und zwar für alle Bilder. Die Probleme sind Speicherbeschränkungen.
Byte [] Pixel = ((DataBufferByte) ImageIO.read (Dateiliste.get (k)) .getRaster(). GetDataBuffer()). GetData();
Dies ist, was ich verwende, um Bilder zu laden, weil es Dekompression kümmert und den Header überspringt.
Ich bearbeite es nicht als ein Video, weil ich einen Rahmen bekommen würde, dann verwandelte es in ein Bild (eine kostspielige Farbraumumwandlung), und wandle es dann in ein Byte um, um Pixeldaten int zu bekommen RGB-Farbraum
Ich könnte jedes Bild laden und teilen Sie es in ~ 500 Teile (Größe von Y) und schreibe in separate Dateien lassen ich offen und schreibe für jedes Bild. Die Ausgänge wären leicht unter einem Gig. Die resultierende Datei könnte vollständig in den Speicher geladen und in ein Array zum sequentiellen Schreiben von Dateien umgewandelt werden.
Die Zwischenschritte bedeutet, dass ich die Last in einem Netzwerk aufteilen konnte, aber ich versuche, es auf einem Laptop niedriger Qualität mit 4 GB RAM, keine GPU und eine niedrige Qualität i7 zu tun.
Ich hatte nicht daran gedacht, irgendwas in der Datei als Zwischenschritt zu speichern, bevor ich davidbaks Antwort gelesen habe. Größe ist die einzige Sache, die dieses Problem nicht trivial macht und ich sehe jetzt, dass die Größe in kleinere handlichere Stücke geteilt werden kann.
nicht sicher, was der Teil 3 ist. Sie müssen eine Datei dekomprimieren und die ersten paar Bytes an eine Datei anhängen? Warum zu 3.000 Dateien? Wenn Sie mehr als 8 Server haben, können Sie hadoop verwenden – tgkprog
Die Eingaben sind alle gleich groß für einen gegebenen Lauf, aber könnte sehr in der Größe zwischen Läufen und auch sehr in der Anzahl der Dateien. Wenn es 1MB pro und 36000 Dateien wären, dann wäre es eine 36GB Datei und das ist das untere Ende der Dinge. Ich konnte diese Datei dann auf sehr vorhersehbare Weise lesen. Jedes Byte, das ich brauche, wäre genau 1MB (die Größe einer Eingabedatei), aber wenn man bedenkt, wie viel Zeit es kostet, eine riesige Datei zu erstellen, ist das wirklich viel schneller? Es würde laden und dann jedes Byte von 36 Gigs in den Speicher löschen, nur um eine Datei zu vervollständigen. Es würde dies 1 Million Mal tun. –