Frage

Zuvor fragte ich das Frage.

Das Problem ist, dass die Anforderungen unserer Dateistruktur sehr hoch sind.

Zum Beispiel versuchen wir, einen Container mit bis zu 4500 Dateien und 500 MB Daten zu erstellen.

Die Dateistruktur dieses Containers besteht aus

  • SQLite DB (unter 1 MB)
  • Textbasierte XML-ähnliche Datei
  • Bilder in einer dynamischen Ordnerstruktur, die den Rest der 4.500 -Dateien ausmachen

  • Nach der ersten Erstellung werden die Bilderdateien nur mit Ausnahme der Löschung gelesen.

  • Der kleine DB wird regelmäßig verwendet, wenn der Behälter zugegriffen wird.

Teer, Reißverschluss und dergleichen sind allzu langsam (auch bei 0 Komprimierung). Langsam ist subjektiv, ich kenne, aber um einen Behälter dieser Größe zu enträt, beträgt über 20 Sekunden.

Irgendwelche Gedanken?

War es hilfreich?

Lösung

Drei Dinge.

1) Was Timothy Walters gesagt hat, ist richtig, ich werde in detailliertere Aussagen eingehen.

2) 4500 Dateien und 500 MB Daten sind einfach viele Daten und Scheiben. Wenn Sie im gesamten Datensatz arbeiten, wird dies langsam sein. Nur die Wahrheit.

3) Wie andere erwähnt haben, gibt es keine Details zum Anwendungsfall.

Wenn wir nur ein Szenario von LEAD -Access -Szenario annehmen, ist das, was Timothy sagt, ziemlich tot, und die Implementierung ist unkompliziert.

Kurz gesagt, hier ist was Sie tun.

Sie verkettet alle Dateien in einen einzelnen Blob. Während Sie sie verkettet, verfolgen Sie ihren Dateinamen, die Dateilänge und den Offset, den die Datei im Blob beginnt. Sie schreiben diese Informationen in einen Datenblock, der nach Namen sortiert ist. Wir nennen dies das Inhaltsverzeichnis oder den TOC -Block.

Als nächstes verkettet Sie die beiden Dateien zusammen. Im einfachen Fall haben Sie zuerst den TOC -Block, dann den Datenblock.

Wenn Sie Daten aus diesem Format abrufen möchten, suchen Sie den TOC nach dem Dateinamen, schnappen Sie sich den Offset vom Beginn des Datenblocks, fügen Sie die TOC -Blockgröße hinzu und lesen Sie Datei -Länge -Bytes von Daten. Einfach.

Wenn Sie klug sein möchten, können Sie das TOC am Ende der Blob -Datei einstellen. Gehen Sie dann ganz am Ende an, den Offset bis zum Start des TOC. Dann sind Sie bis zum Ende der Datei, die 4 oder 8 Bytes (abhängig von Ihrer Anzahl), diesen Wert und Lseek noch weiter zum Beginn Ihres TOC zurückzahlen. Dann bist du zurück zum Platz eins. Sie tun dies, damit Sie das Archiv am Anfang nicht zweimal wieder aufbauen müssen.

Wenn Sie Ihren TOC in Blöcken auslegen (z. B. 1K -Byte in Größe), können Sie leicht eine binäre Suche auf dem TOC durchführen. Füllen Sie einfach jeden Block mit den Dateiinformationseinträgen aus und schreiben Sie einen Marker, pad mit Nullen und gehen Sie zum nächsten Block vor. Um die binäre Suche durchzuführen, kennen Sie bereits die Größe des TOC, beginnen Sie in der Mitte, lesen Sie den ersten Dateinamen und gehen Sie von dort aus. Bald finden Sie den Block und lesen Sie dann im Block und scannen ihn für die Datei. Dies macht es effizient zum Lesen, ohne den gesamten TOC im RAM zu haben. Der andere Vorteil ist, dass die Blockierung weniger Festplattenaktivität erfordert als ein gekettetes Schema wie Tar (wo Sie das Archiv kriechen müssen, um etwas zu finden).

Ich empfehle Ihnen, die Dateien auch zu den Größen zu blockieren. Festplatten wie Datenblocks mit regulärer Daten. Dies ist auch nicht schwierig.

Es ist schwierig, dies zu aktualisieren, ohne das Ganze wieder aufzubauen. Wenn Sie ein aktualisierbares Containersystem wünschen, können Sie auch einige der einfacheren Dateisystemdesigns betrachten, da Sie dies in diesem Fall wirklich suchen.

Was die Portabilität betrifft, empfehle ich Ihnen, Ihre Binärnummern in Netzwerkreihenfolge zu speichern, da die meisten Standardbibliotheken Routinen haben, um diese Details für Sie zu verarbeiten.

Andere Tipps

Da Sie anscheinend beliebige Dateisystemvorgänge in Ihrem Container ausführen (z. B. Erstellung, Löschen neuer Dateien im Container, Überschreibung vorhandener Dateien, Anhängen), sollten Sie sich für eine Art Dateisystem entscheiden. Weisen Sie eine große Datei zu und erstellen Sie dann eine Dateisystemstruktur darin.

Für das Dateisystem gibt es mehrere Optionen: Für Berkeley UFS und Linux Ext2/Ext3 stehen Benutzer-Modi-Bibliotheken zur Verfügung. Es kann auch möglich sein, dass Sie irgendwo eine FAT -Implementierung finden. Stellen Sie sicher, dass Sie die Struktur des Dateisystems verstehen, und wählen Sie eine aus, die sich verlängert. Ich weiß, dass Ext2 ziemlich einfach zu erweitern ist (nach einer anderen Blockgruppe), und das Fett ist schwer zu verlängern (müssen sich an das Fett anhängen).

Alternativ können Sie ein virtuelles Datenträgerformat unter dem Dateisystem einstellen, wodurch ein beliebiges Neuapparat von Blöcken ermöglicht wird. Dann müssen "freie" Blöcke des Dateisystems nicht auf der Festplatte angezeigt werden, und Sie können die virtuelle Festplatte, die viel größer als die reale Containerdatei ist, zuweisen.

Arbeiten Sie an der Annahme Position und Länge. Alles, was Sie tun müssen, ist bis zum Startpunkt zu suchen und die richtige Anzahl von Bytes zu lesen. Die Methode variiert je nach Sprache, ist aber in den meisten von ihnen ziemlich einfach.

Der schwierigste Teil wird dann zum Erstellen Ihrer Datendatei + Index, und selbst das ist ziemlich einfach!

Ein ISO -Datenträgerbild kann den Trick machen. Es sollte in der Lage sein, so viele Dateien leicht zu halten, und wird von vielen Software -Teilen auf allen wichtigen Betriebssystemen unterstützt.

Erstens, danke, dass Sie Ihre Frage erweitert haben, es hilft sehr, bessere Antworten zu geben.

Haben Sie sich die Leistung angesehen, da Sie sowieso eine SQLite -Datenbank benötigen, die alles in die Datenbank einfügt? Meine Erfahrung basiert auf SQL Server 2000/2005/2008, daher bin ich nicht positiv auf die Funktionen von SQLite, aber ich bin sicher, dass es eine ziemlich schnelle Option für die Suche nach Aufzeichnungen und das Erhalten der Daten sein wird und gleichzeitig das Löschen zulässt und/oder aktualisieren Optionen.

Normalerweise würde ich nicht empfehlen, Dateien in die Datenbank einzustellen, aber angesichts der Gesamtgröße aller Bilder beträgt Sie etwa 500 MB für 4500 Bilder, die Sie etwas mehr als 100.000 pro Bild sehen, oder? Wenn Sie einen dynamischen Pfad verwenden, um die Bilder zu speichern, können Sie in einer etwas normalisierteren Datenbank eine "ImagePaths" -Tabelle haben, die jeden Pfad zu einer ID ordnet, können Sie nach Bildern mit diesem Pathid suchen und die Daten aus dem laden BLOB -Säule nach Bedarf.

Die XML -Datei (en) könnten sich auch in der SQLite -Datenbank befinden, mit der Sie eine einzelne "Datendatei" für Ihre App erhalten, die sich ohne Probleme zwischen Windows und OSX verschieben kann. Sie können sich einfach auf Ihre SQLite -Engine verlassen, um die Leistung und Kompatibilität zu gewährleisten, die Sie benötigen.

Wie Sie es optimieren, hängt von Ihrer Verwendung ab. Zum Beispiel, wenn Sie häufig alle Bilder auf einem bestimmten Pfad erhalten müssen, wäre es schnell, wenn Sie eine Pathid (als Ganzzahl für die Leistung) haben, aber wenn Sie alle Bilder anzeigen, die beginnen Mit "a" und einfach den Pfad als Eigenschaft anzeigen, dann wäre ein Index in der Bildname -Spalte nützlicher.

Ich bin jedoch ein wenig besorgt, dass dies nach einer vorzeitigen Optimierung klingt, da Sie wirklich eine Lösung finden müssen, die „schnell genug“ funktioniert, die Mechanik abstrahiert, damit Ihre Anwendung (oder beide Apps, wenn Sie sowohl Mac- als auch PC -Versionen haben) verwenden Ein einfaches Repository oder ähnliches und dann können Sie die Speicher-/Abrufmethode nach Belieben ohne Auswirkungen auf Ihre Anwendung ändern.

Prüfen Solides Dateisystem - Es scheint das zu sein, was Sie brauchen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top