import struct class FileOf: """(Pascal) File of XX, als Beispiel für das Python "struct"-Modul. Der Parameter "fmt" gibt den record-Typ an, siehe doc/lib/module-struct.html Beispiele: Integer: "h" String[255] "256p" (das Stringlängenbyte muß mitgezählt werden) Single "f" (das 6-Byte-Real von Turbo-Pascal gibt's leider nicht) Double "d" record aus 3 Integers und ein String[20]: "hhh21p" oder "3h21p" """ def __init__(self, fmt, filename, modus="rb"): modus = modus.strip().lower() if not modus: modus = "rb" if "t" in modus: raise "Textmodus??? wieso das denn?" if "b" not in modus: modus += "b" self.modus = modus self.file = open(filename, self.modus) self.fmt = fmt self.recsize = struct.calcsize(fmt) def write(self, zahl): if type(zahl) == type(()): self.file.write(struct.pack(self.fmt, *zahl)) else: self.file.write(struct.pack(self.fmt, zahl)) def read(self): bytes = self.file.read(self.recsize) if len(bytes) == self.recsize: value = struct.unpack(self.fmt, bytes) if len(value) == 1: return value[0] # statt Tupel mit 1 Wert nur Wert zurückgeben else: return value else: return None # eingebautes .read() würde bei EOF "" zurückgeben def close(self): self.file.close() def test(fmt, name, list_of_values): file = FileOf(fmt, name, "w") for value in list_of_values: file.write(value) file.close() file = FileOf(fmt, name) for value in list_of_values: vergl = file.read() if vergl != value: print "Error: written", repr(value), "read back", repr(vergl) file.close() if __name__ == "__main__": # Integer test("h", "test_i.dat", (1, 2573, 4711, 32733, -179, 3338, -1)) # String[255] test("256p", "test_str255.dat", ("hallo", "guten\n\rAbend", "")) # Single test("f", "test_s.dat", (0, -1, 47.3125, 1e7, 100.001953125)) # Double test("d", "test_d.dat", (0, 1, 47.2, -13, -2e9, 0.00001)) test("hhh21p", "test_r.dat", ((1,2,3,"haha"), (4, 7, 11, "")))