readonly Datei verändert sich

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
synapsenstau
User
Beiträge: 11
Registriert: Freitag 6. März 2015, 18:39
Wohnort: Südharz

Nabend die Herrschaften,

irgendwas mache ich falsch, aber erst mal nen Codeschnipsel:

Code: Alles auswählen

for i in range(0, len(sfv_file_list)):                          
        open_sfv_file = open(sfv_file_list[i],  "rb")               # open to calc file binary
        for line in open_sfv_file:                                  # calc sfv from file
            test = zlib.crc32(line,  test)
        open_sfv_file.close()
        crc_test.append(hex(test).split('x')[1])                    # translate decimal in hex and remove 0x
        test = 0

Code: Alles auswählen

sfv_file_list = liste mit Dateinahmen aus einer *.sfv Datei
test = dump zum berechnen der crc wertes
crc_test = liste mit ergebnissen

Vor dem Programmstart habe ich mit cfv die Dateien überprüft und sie waren OK.
Nun zum Problem:
Berechnung der ersten Datei klappt berechneter crc ist gleich dem in der sfv Datei.
bei der zweiten funktioniert das schon nicht mehr. berechnetter crc nicht gleich sfv Datei.
Und jetzt wird es erst richtig spanisch. Wenn ich jetzt das Programm wieder starte passt auch der crc Wert der ersten Datei nicht mehr.
Der externe Check mittels cfv ergibt nun das beide Dateien corrupt sind. Wie geht das? Öffne sie doch "rb".
BlackJack

@synapsenstau: Du öffnest die Datei im Binärmodus und iterierst dann über Zeilen als wäre es eine Textdatei. Das kann funktionieren, muss es aber nicht. Bei Binärdateien liest man üblicherweise Blockweise mit einer geeigneten Blockgrösse. Mit `functools.partial()` und der `iter()`-Funktion kann man das in einer einfachen ``for``-Schleife machen.

Das `test` am Ende der äusseren Schleife an 0 gebunden wird ist komisch. Das muss ja irgendwo vor dem gezeigten Code auch schon mal passieren und ist damit eine Code-Wiederholung die man vermeiden sollte und auch sehr leicht kann, in dem man das direkt *vor* der Schleife macht die `test` berechnet.

Die äussere ``for``-Schleife ist in Python ein „anti pattern”. Das `i` ist eine völlig unnötige Indirektion, man kann direkt über die Elemente von `sfv_file_list` iterieren.

Datentypen wie `list` sollten nicht Bestandteil von Namen sein. Es kommt gar nicht so selten vor das man den Containertyp im Laufe der Programmentwicklung ändert, was dann umbennen nach sich zieht, obwohl sich an der *Bedeutung* des Wertes gar nichts geändert hat, oder man hat falsche und irreführende Namen im Programm. Bei Containertypen verwendet man üblicherweise die Mehrzahl des Bezeichners den man für ein Element wählen würde. `crc_test` ist deswegen auch kein passender Name. `test` ist ebenfalls nicht gut gewählt.

Umwandeln in Hexadezimaldarstellung würde man besser mit Zeichenkettenformatierung machen, denn dann braucht man keinen Präfix entfernen und kann auch gleich auf 8 Zeichen auffüllen wie man das üblicherweise bei 32-Bit-Werten macht.

Die Datei würde ich zusammen mit der ``with``-Anweisung öffnen damit das Schliessen automatisch und in jedem Fall passiert wenn der ``with``-Block verlassen wird.

Der gezeigte Code verändert die Dateien nicht. Das was Du beschreibst kann also nicht passieren oder hat nichts mit dem gezeigten Code zu tun.

Die Liste enthält Datei*namen* und keine Dateien. Das sollte sich im Namen widerspiegeln.
BlackJack

Ungetestet:

Code: Alles auswählen

import zlib
from functools import partial


def iter_crc32_sums(filenames):
    for filename in filenames:
        with open(filename, 'rb') as data_file:
            crc = 0
            for chunk in iter(partial(data_file.read, 2**20), ''):
                crc = zlib.crc32(chunk, crc)
        yield format(crc & 0xffffffff, '08X')
Antworten