Lesen von Objekten aus Random-Access-Datei
Schrieb ich eine Datei mit Java FileChannel-Klasse, die verwendet RandomAccessFiles. Ich schrieb von Objekten an verschiedenen Standorten in der Datei. Die Objekte wurden von Variablen Größen, aber alle von der gleichen Klasse. Ich schrieb die Objekte mithilfe der folgenden Idee :
ByteArrayOutputStream bos= new ByteArrayOutputStream(); ObjectOutput out = new ObjectOutputStream(bos); out.writeObject(r); byte[] recordBytes= bos.toByteArray();
ByteBuffer rbb= ByteBuffer.wrap(recordBytes); while(rbb.hasRemaining()) { fileChannel.write(rbb); }
Nun will ich Lesen aus dieser Datei. Ich will nicht angeben, die Anzahl der zu lesenden bytes. Ich möchte in der Lage sein, zu Lesen, das Objekt direkt mit dem Objekt-Eingabestream. Wie dies zu erreichen ?
Ich haben auf Random Access-Dateien, weil ich brauche, um zu schreiben, um die unterschiedlichen Positionen in der Datei. Ich bin auch die Aufzeichnung in einer separaten Datenstruktur, die Orte, an denen Objekte geschrieben wurden.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Nein, tun Sie nicht. Sie können verschieben Sie einen
FileOutputStream
oderFileInputStream
über seinen Kanal.Wäre wesentlich vereinfachen Sie Ihren code schreiben, als auch: Sie würden nicht müssen, verwenden Sie den Puffer oder Kanal, und je nach Bedarf könnte man weglassen
ByteArrayOutputStream
als gut. Jedoch, wie Sie Hinweis in einem Kommentar, die Sie nicht wissen, die Größe des Objekts im Voraus, und dieByteArrayOutputStream
ist eine nützliche Methode, um zu überprüfen, dass Sie nicht überrannt Ihr zugewiesenen Raum.Um die Objekte Lesen, tun Sie den folgenden:
Einem Kommentar hier: ich wickelte die
FileInputStream
imBufferedInputStream
. In diesem speziellen Fall, wo die stream-Datei wird neu positioniert vor jedem Gebrauch, dass ein performance-Vorteil. Beachten Sie jedoch, dass die gepufferten stream können Lesen Sie mehr bytes als nötig, und es gibt einige Situationen, über die Konstrukt-als-nötig-Objekt-streams, wo wäre es eine wirklich schlechte Idee.ObjectOutputStream.close()
weitergibt. Das ist, warum Sie sehen es nicht in meinem Beispiel. Stattdessen rufe ichflush()
um sicherzustellen, dass die Inhalte in den stream geschrieben werden, und lassen Sie dann den GC entsorgt werden.Warum nicht suchen für Sie arbeiten? Ich glaube, Sie brauchen, um
seek()
zu richtigen stellen und dann einfach nur Lesen, Objekte mit Ihren Objekt-stream. Auch, wenn man die richtigen Orte der serialisierten Objekte, warum nicht speichern Sie Ihre Größen? In diesem Fall können Sie sich bewerbenObjectInputStream
gegen bytes, die Sie Lesen aus Datei.Die einfachste Lösung, die mir einfällt, ist zu schreiben, die die Länge des Arrays vor dem schreiben aus dem array selbst:
Beim Lesen der Objekt, das Sie zuerst Lesen Sie die Länge. Diese werden Ihnen sagen, wie viele weitere bytes zu Lesen, um Ihr Objekt. Ähnlich zu dem, was Sie bereits tun, auf der schreiben-Seite, die Sie Lesen konnte, die Daten in eine
byte[]
und verwenden Sie dannByteArrayInputputStream
undObjectInputStream
.Könnte man eine
FileInputStream
konstruiert auf derRandomAccesFile
'sFileDescriptor
Objekt, etwa so:Unter der Annahme, dass die RandomAccessFile heißt raf.
RandomAccessFile
zu der Methode schreiben, die Objekte.