random write

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
may24
User
Beiträge: 27
Registriert: Montag 7. September 2009, 17:14

Hi zusammen,

das ist jetzt wahrscheinlich 'ne Anfängerfrage die schon duzend mal gestellt wurde. Dennoch habe ich bisher (trotz Forumssuche und Google) nichts brauchbares gefunden.

Folgendes Problem: Ich habe einige Dateien (größer 150 MB) deren Header an zwei Stellen verändert werden sollen. Normalerweise mache ich das mit 'nem Hex Editor, nur bei 150+ Dateien dauert mir das einfach zu lange ...
Ich möchte nun zwei Stellen der Datei auslesen und wenn die Paraperter an dieses Stellen passen sollen sie ausgetauscht werden.
Mein Script (abgekürzt) soweit:

Code: Alles auswählen

for item in listOfFiles:
	try:
		file = open(item, 'rb')
		file.seek(112)
		get_fourcc_1 = file.read(4)
		file.seek(188)
		get_fourcc_2 = file.read(4)
		if ( get_fourcc_1 == o_fourcc_1 and get_fourcc_2 == o_fourcc_2 ):
			print get_fourcc_1, get_fourcc_2
			file.close()
			try:
				file = open(item, 'wb')
				file.seek(112)
				file.write(n_fourcc_1)
				file.seek(188)
				file.write(n_fourcc_2)
				file.close()

			except IOError:
				print "Error"
				sys.exit(1)
	except IOError:
		print file, "not readable"
		sys.exit(1)
Das Ganze funktioniert so natürlich nicht. Die Frage ist nun wie/ob es überhaupt geht.
Es macht für mich keinen Sinn wegen 8 Bytes die kompletten 150MB neu zu schreiben, deshalb soll ja auch nur an diesen besagten 2 Stellen etwas geändert werden.
tordmor
User
Beiträge: 100
Registriert: Donnerstag 20. November 2008, 10:29
Wohnort: Stuttgart

Öffne die Datei mit mode="r+b". cf. http://docs.python.org/library/functions.html#open
http://www.felix-benner.com
BlackJack

@may24: Du möchtest die Datei nur einmal öffnen und zwar mit dem Modus 'rb+', also zum lesen *und* schreiben. Dann sollte das grundsätzlich so funktionieren wie Du es skizziert hast.
may24
User
Beiträge: 27
Registriert: Montag 7. September 2009, 17:14

BlackJack hat geschrieben:@may24: Du möchtest die Datei nur einmal öffnen und zwar mit dem Modus 'rb+', also zum lesen *und* schreiben. Dann sollte das grundsätzlich so funktionieren wie Du es skizziert hast.
Hm, nein, das funktioniert nicht.
Hier ist mal der komplette Code:

Code: Alles auswählen

import sys, os, re

listOfFiles = []
i = 0
o_fourcc_1 = "xvid"
o_fourcc_2 = "XVID"
n_fourcc_1 = "divx"
n_fourcc_2 = "DX50"

###########################################################################################

for root, dirs, files in os.walk('.'):
	for items in files:
		fullPathName = os.path.join(root,items)
		if (re.search(".avi", fullPathName) != None ):
			listOfFiles.append(fullPathName)

print len(listOfFiles), "items found"

for item in listOfFiles:
	try:
		file = open(item, 'rb+')
		file.seek(112)
		get_fourcc_1 = file.read(4)
		file.seek(188)
		get_fourcc_2 = file.read(4)
		if ( get_fourcc_1 == o_fourcc_1 and get_fourcc_2 == o_fourcc_2 ):
			print get_fourcc_1, get_fourcc_2
			file.seek(112)
			file.write(n_fourcc_1)
			file.seek(188)
			file.write(n_fourcc_2)
			file.close()
	except IOError:
		print "Error"
Ich bekomme immer nur den except Error ... und sonst nichts.
Sicher das es 'rb+' ist ? Nicht 'wb+' ?
BlackJack

@may24: Dann binde beim ``except`` die Ausnahme an einen Namen und lass sie Dir mal ausgeben. Das ist sicher informativer als einfach nur "Error" ausgeben zu lassen.

Das Schliessen der Datei sollte übrigens auf Ebene der Schleife passieren. Und statt des regulären Ausdrucks wäre die `endswith()`-Methode von Zeichenketten einfacher und auch genauer.
may24
User
Beiträge: 27
Registriert: Montag 7. September 2009, 17:14

BlackJack hat geschrieben:@may24: Dann binde beim ``except`` die Ausnahme an einen Namen und lass sie Dir mal ausgeben. Das ist sicher informativer als einfach nur "Error" ausgeben zu lassen.

Das Schliessen der Datei sollte übrigens auf Ebene der Schleife passieren. Und statt des regulären Ausdrucks wäre die `endswith()`-Methode von Zeichenketten einfacher und auch genauer.
Ah, ich hab des Rätzel's Lösung gefunden. Die Datei war schreibgeschützt (Das Attribut war gesetzt). Und trotz Administrator Rechte schlägt dann das Schreiben fehl.
Gibt's so was wie eine "force overwrite" Option ?
ms4py
User
Beiträge: 1178
Registriert: Montag 19. Januar 2009, 09:37

Vermutlich nicht, aber du kannst das Read-Only Flag ändern:
http://docs.python.org/library/os.html#os.chmod

Ach, noch zu deinem Code:
- `file` solltest du nicht überschreiben
- Code ist nicht PEP-8 konform (http://www.python.org/dev/peps/pep-0008/ )
„Lieber von den Richtigen kritisiert als von den Falschen gelobt werden.“
Gerhard Kocher

http://ms4py.org/
Benutzeravatar
pillmuncher
User
Beiträge: 1484
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

may24 hat geschrieben:Gibt's so was wie eine "force overwrite" Option ?
Die wünsche ich mir immer, wenn jemand PEP8-unkonformen Code schreibt :P

Im Übrigen würde ich es so machen:

Code: Alles auswählen

import os

fourccs = [
    (112, "xvid", "divx"),
    (188, "XVID", "DX50")
]

for dirpath, dirnames, filenames in os.walk('.'):
    for name in filenames:
        if name.endswith('.avi'):
            with open(os.path.join(dirpath, name), 'r+b') as avifile:
                for byte, old4cc, new4cc in fourccs:
                    avifile.seek(byte)
                    if avifile.read(4) != old4cc:
                        break
                else:
                    for byte, old4cc, new4cc in fourccs:
                        avifile.seek(byte)
                        avifile.write(new4cc)
In specifications, Murphy's Law supersedes Ohm's.
Antworten