2012-01-03 21 views
60

Python ile özellikle zor okunan ikili dosyaları buluyorum. Bana yardım edebilir misin? Fortran 90 kolayca Ayrıntılı olarakPython ile bir ikili dosyayı okuma

int*4 n_particles, n_groups 
real*4 group_id(n_particles) 
read (*) n_particles, n_groups 
read (*) (group_id(j),j=1,n_particles) 

tarafından okunan bu dosyayı okumak gerekir, dosya biçimidir:

Bytes 1-4 -- The integer 8. 
Bytes 5-8 -- The number of particles, N. 
Bytes 9-12 -- The number of groups. 
Bytes 13-16 -- The integer 8. 
Bytes 17-20 -- The integer 4*N. 
Next many bytes -- The group ID numbers for all the particles. 
Last 4 bytes -- The integer 4*N. 

nasıl Python ile bunu okuyabilir? Her şeyi denedim ama hiç işe yaramadı. Python'da bir f90 programını kullanabileceğim, bu ikili dosyayı okuyabildiğim ve kullanmam gereken verileri kaydettiğim ihtimal var mı?

+1

bu dosya bir Fortran programı tarafından yazılmıştır oldu mu? Öyleyse, nasıl yazılmıştır, çünkü Fortran, varsayılan olarak, dosyaya yazdığı her kayıttan önce ek veriler ekler. Verileri okurken bununla ilgilenmeniz gerekebilir. – Chris

+1

Lütfen önceki yorumumu dikkate almayın, 8 ve 4 * N numaralı aralıklar açıkça bu ek veridir. – Chris

+2

Ayrıca, [python'da ikili dosyayı okuma] sorununun yanıtlarını görün (http://stackoverflow.com/questions/1035340/reading-binary-file-in-python). – Chris

cevap

79

Oku böyle ikili dosya içeriği:

with open(fileName, mode='rb') as file: # b is important -> binary 
    fileContent = file.read() 

sonra struct.unpack kullanarak ikili veri "açmak":

başlangıç ​​bayt: struct.unpack("iiiii", fileContent[:20])

gövdesi: başlık bayt görmezden gelip takip eden bayt (= 24); Kalan kısım bedeni oluşturur, vücuttaki bayt sayısını bilmek için 4 ile bir tamsayı bölüştürür; Elde edilen bölüm açmak yöntemi için doğru biçimi oluşturmak için dize 'i' ile çarpılır:

struct.unpack("i" * ((len(fileContent) -24) // 4), fileContent[20:-4]) 

uç bayt: struct.unpack("i", fileContent[-4:])

+0

Çok teşekkürler, ama kodunuzla, başlangıç ​​ve bitiş baytlarını okuyabilirim, ancak bedeni değil. Bu hata iletisini alır TypeError: // için desteklenmeyen işlenen türü (ler): 'str' ve 'int'. Dosyamın gövdesini okurken kodunuzun anlamını daha iyi anlatabilir misin? – Brian

+0

Bazı parantez eksikti. Mesajımı güncelledim – gecco

+0

Kendi kendime çözdüm! Çok yardımcı cevap için çok teşekkürler! – Brian

21

Genel olarak, bunun için Python'un struct modülünü kullanmayı tavsiye ederim. Python ile standarttır ve sorunuzun belirtimini struct.unpack() için uygun bir biçimlendirme dizesine çevirmek kolay olmalıdır.

Alanlar arasında/çevresinde "görünmez" dolgu varsa, bunu anlamanız venumaralı çağrıya eklemeniz gerektiğini veya yanlış bitleri okuyacağınızı unutmayın.

import struct 

data = open("from_fortran.bin", "rb").read() 

(eight, N) = struct.unpack("@II", data) 

Bu da dosya (hayır dolgu ya da gereksiz başında başlayacak varsayarak ilk iki alan açar: açmak için bir şey olması için dosyanın içeriğini okuma

hayli abes veri) ve ayrıca yerel bayt sırasını (@ sembolü) varsayar. Biçimlendirme dizesindeki I s "işaretsiz tam sayı, 32 bit" anlamına gelir.

+0

Tamam, ama dosyanın baytlarını nasıl okuyacağımı bile bilmiyorum. Soruma göre, dosyayı 5'ten 8'e kadar bayttan nasıl okuyabilirim ve sonucu bir tamsayıya nasıl dönüştürebilirim? Üzgünüm, ama Python ile yeniyim. – Brian

8

Hem metin hem de ikili dosyalardaki verileri okuyabilen numpy.fromfile kullanabilirsiniz. İlk olarak, dosya biçiminizi temsil eden bir veri türünü numpy.dtype kullanarak oluşturup numpy.fromfile kullanarak bu tür dosyaları dosyadan okuyabilirsiniz.

+0

Bunu kaçırmak çok kolay! Dokümanlar biraz zayıf; Bazı tartışmalar için https://www.reddit.com/r/Python/comments/19q8nt/psa_consider_using_numpy_if_you_need_to_parse_a/ sayfasına bakın. – lost

-1
import pickle 
f=open("filename.dat","rb") 
try: 
    while True: 
     x=pickle.load(f) 
     print x 
except EOFError: 
    pass 
f.close() 
+5

Muhtemelen bunun neden diğer cevaplardan (veya en azından aynı derecede iyi) daha iyi olduğuna dair küçük bir açıklama. – Phil

+1

Bu bir fortran oluşturulan ikili ile çalışır bir doğrulanmış test ettiniz? – agentp

+0

Ve ayrıca ne yaptığını açıklıyor ... Turşu nedir? Pickle.load' ne yüklüyor? Bir Fortran akışı, doğrudan veya sıralı dosyalar mı yüklüyor? Farklı ve uyumlu değiller. –

İlgili konular