droptix hat geschrieben:BlackJack hat geschrieben:Falls bei dem Programm wirklich mehr Dateien verwaltet werden müssen als in den Speicher passen, würde ich für die flache Datenstruktur eine Datenbank benutzen.
Der Aufwand würde den Nutzen denke ich nicht rechtfertigen. Man könnte hier für eine schnelle Lösung zwar auf SQLite zurück greifen, aber es ist schon umständlich, erst alles in einer DB zu erfassen, um daraus dann das XML zu erzeugen. Ich mach das erstmal in einem Dictionary und werde mal die Grenzen austesten.
So aufwändig muss das ja nicht werden. Das erst einmal mit den eingebauten Datentypen zu machen ist keine schlechte Idee. Und den Datenbankzugriff kann man dann später auch so gestalten, dass sich für den Code, der vorher ein Dictionary benutzt hat, nichts ändert. Dann wäre es austauschbar. Man könnte dann auch zuerst ein Dictionary benutzen, und erst wenn das eine bestimmte Grösse erreicht hat, auf die Datenbank umsteigen.
Statt SQLite kann man auch erst einmal `shelve` benutzen. Das verhält sich ja schon wie ein Dictionary.
Irgendjemand gab letztens den Tipp, dass SQLite in Python 2.5 mittlerweile auch DBs im Arbeitsspeicher erstellen kann, so dass dafür keine Datei angelegt werden muss. Würde sich dafür perfekt eignen, aber:
1) Was passiert, wenn der Arbeitsspeicher voll ist? Swapping?
Natürlich was sonst. Aber wie kommst Du jetzt überhaupt darauf? Es ging ja gerade darum eine Datenbank zu benutzen wenn die Daten nicht mehr komplett in den Speicher passen. Wenn man diese DB dann im Speicher anlegt, wird sie ganz bestimmt nicht in den Speicher passen und alles wird noch langsamer weil noch die unnötige Datenbankschicht dazwischen liegt.
Der Sinn der Datenbank ist in diesem Fall doch gerade, dass man den Hauptspeicher entlastet, aber trotzdem noch möglichst schnell und effizient auf die Daten zugreifen kann.
2) Kann man das neue SQLite auch für ältere Python-Versionen nachrüsten?
Diese Funktion ist soweit ich weiss nicht neu. Man muss als DB-Namen nur ':memory:' angeben.
BlackJack hat geschrieben:Bei XML muss man auch aufpassen, dass die Namen unter den meisten Unix-Dateisystemen im Grunde kein Text, sondern Binärdaten sind. Bis auf das Nullbyte und '/' ist in der Regel alles erlaubt. Nichtdruckbare Zeichen mit ASCII-Code kleiner 32 sind aber teilweise illegal in XML-Dokumenten!
Wie jetzt? Unter Unix sind Dateinamen doch auch Text. Ich kenne keine Dateinamen, die Zeichen unter ASCII-Code 32 enthalten. Gibt's dafür mal ein Beispiel?
Also ich habe mehrere PDF-Dokumente auf der Festplatte wo ein '\n' im Namen ist, weil die automatisch nach den Metadaten benannt wurden und der Titel einen Zeilenumbruch enthält.
Ansonsten:
Code: Alles auswählen
In [29]: name = ''.join(chr(i) for i in xrange(1, 256)).replace('/', '')
In [30]: f = open(name, 'w')
In [31]: f.write('test\n')
In [32]: f.close()
In [33]: ls
??????????????????????????????? !"#$%&'()*+,-.0123456789:;<=>?@ABCDEFGHIJKLMNOPQ
RSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~???????????????????????????????????
????????????????????????????????????????????????????????????????????????????????
??????????????
In [34]: ls --quoting-style=escape
\001\002\003\004\005\006\a\b\t\n\v\f\r\016\017\020\021\022\023\024\025\026\027\0
30\031\032\033\034\035\036\037\ !"#$%&'()*+,-.0123456789:;<\=\>?\@ABCDEFGHIJKLMN
OPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{\|}~\177\200\201\202\203\204\205\2
06\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\2
32\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\2
56\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\3
02\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\3
26\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\3
52\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\3
76\377
In [35]: cat *
test
Wie gesagt: alles ausser '/' und '\0' ist grundsätzlich erst einmal erlaubt. Die C Bibliotheksfunktionen erwarten einen Zeiger auf ein `char`-Array dessen Ende mit '\0' gekennzeichnet ist und das Betriebssystem interpretiert den '/' als Pfadtrenner. Alles andere wird bei vielen Dateisystemen einfach durchgereicht und auf die Platte geschrieben. In diesem Fall ist's ReiserFS gewesen.
Ich würde wegen Sonderzeichen natürlich mit UTF-8 und Entities arbeiten.
Wie willst Du von den Bytes zu UTF-8 kommen? Wenn ein Name das Byte '\xf6' enthält, ist das ein u'ö' oder ein u'÷'?
Mit seriell meinst du ich generiere XML-Code und hänge den mittels writeline() an eine Datei hinten ran? Dann laufe ich aber Gefahr, nicht wohlgeformtes XML zu erzeugen... wenn z.B. das End-Tag vom Wurzelelement fehlt, weil ein Memory-Error zwischendrin abgebrochen hat.
Die Gefahr besteht auch, wenn Du das XML erst komplett im Speicher generierst und dann erst rausschreibst.
Ich dachte auch eher an den `XMLWriter` aus `elementtree.SimpleXMLWriter` oder das man sich selber so eine Klasse schreibt, statt `writeline()` direkt zu benutzen.
Ich muss das XML-Dokument zur Weiterverarbeitung ja auch wieder in Python einlesen können! Also irgendwie muss das in den Speicher passen
Nein, auch einlesen kann man das wieder inkrementell, z.B. mit SAX oder `iterparse()` aus `elementtree.ElementTree`.