Seite 1 von 1

random write

Verfasst: Montag 26. Juli 2010, 14:00
von may24
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.

Re: random write

Verfasst: Montag 26. Juli 2010, 14:27
von tordmor
Öffne die Datei mit mode="r+b". cf. http://docs.python.org/library/functions.html#open

Re: random write

Verfasst: Montag 26. Juli 2010, 14:28
von 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.

Re: random write

Verfasst: Montag 26. Juli 2010, 15:25
von may24
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+' ?

Re: random write

Verfasst: Montag 26. Juli 2010, 15:41
von 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.

Re: random write

Verfasst: Montag 26. Juli 2010, 16:00
von may24
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 ?

Re: random write

Verfasst: Montag 26. Juli 2010, 16:52
von ms4py
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/ )

Re: random write

Verfasst: Montag 26. Juli 2010, 17:41
von pillmuncher
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)