Was wäre der beste Ansatz, um eine große Textdatei umzukehren, die asynchron in ein Servlet hochgeladen wird, das diese Datei auf skalierbare und effiziente Weise umkehrt?
Ich dachte daran, Java NIO zu verwenden, um Datei als ein Array auf dem Datenträger zu behandeln (so dass ich die Datei nicht als einen Zeichenfolgenpuffer in Arbeitsspeicher behandeln muss). Außerdem denke ich daran, MapReduce zu verwenden, um die Datei zu trennen und auf separaten Rechnern zu verarbeiten.
Wenn es zu Ihnen hochgeladen wird und Sie die Länge am Anfang erhalten können, könnten Sie einfach eine leere Datei in voller Größe erstellen und von hinten auf die Datei schreiben und sich mit suche
Sie möchten wahrscheinlich eine Blockgröße (wie 1K?) definieren und diese im Speicher so lange umkehren, bevor Sie sie in die Datei schreiben.
Das ist eine ziemlich schwierige Aufgabe. Wenn Sie sicherstellen können, dass das HTTP Content-Length
und Content-Type
Header sind in der Upload-Anfrage vorhanden (oder im Multipart-Body, wenn es sich um ein% co_de handelt % request), dann wäre es ein einfacher Job mit Hilfe von multipart/form-data
. Die Länge des Inhalts ist obligatorisch, damit RandomAccessFile
weiß, wie lange die Datei sein wird, und das Zeichen an der Stelle schreiben, an der es sein soll. Die Zeichencodierung (die normalerweise als Attribut des Headers des Inhaltstyps vorhanden ist) ist erforderlich, um zu wissen, wie viele Bytes ein Zeichen berücksichtigt (weil RandomAccessFile
bytebasiert ist und z. B. die UTF-8-Codierung variable Byte- Länge).
Hier ist ein Kickoff-Beispiel (abgesehen von der offensichtlichen Ausnahmenbehandlung):
%Vor% Wenn diese Header nicht vorhanden sind (besonders RandomAccessFile
ist wichtig), müssen Sie sie wirklich erst auf dem Datenträger bis zum Ende des Streams speichern und dann erneut lesen und auf die gleiche Weise mit Hilfe von% co_de umkehren %.
Update : Es wäre tatsächlich härter als es aussieht. Ist die Zeichenkodierung des Eingangs immer garantiert gleich? Wenn ja, was wäre es? Was würden Sie beispielsweise mit Ersatzzeichen und Zeilenumbrüchen machen? Das obige Beispiel berücksichtigt das nicht korrekt. Aber es gibt zumindest die Grundidee.
Speichern Sie es in überschaubaren Stücken auf der Festplatte, wenn sie eintreffen, und lesen Sie die Teile dann bei Bedarf rückwärts und präsentieren Sie den Inhalt rückwärts.
Würde 1 MB eine vernünftige Größe sein, angesichts der Menge, die für eine normale Java-Anwendung in diesen Tagen verfügbar ist?
In der Map-Reduce-Paradigma-Datei kann in kleine Partitionen aufgeteilt werden, und jede Partition kann in einem Sammlungsobjekt gespeichert werden, das leicht umgekehrt werden kann, und in reduzierter Phase kann jede umgekehrte Ausgabe wieder zusammengeführt werden. zum Beispiel in Spark-Scala-Code sollte so etwas sein.
%Vor%