পাইথন সহ একটি বাইনারি ফাইল পড়া


104

পাইথনের সাথে বাইনারি ফাইল পড়তে আমার বিশেষ অসুবিধা আছে। স িপস ্িপটসনসপেোসেসচিপ? আমার এই ফাইলটি পড়তে হবে যা ফোর্টরান 90 এ সহজেই পড়ে

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)

বিশদভাবে, ফাইল ফর্ম্যাটটি হ'ল:

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. 

পাইথনের সাথে এটি কীভাবে পড়তে পারি? আমি সব চেষ্টা করেছিলাম কিন্তু এটি কখনই কার্যকর হয়নি। পাইথনে আমি f90 প্রোগ্রাম ব্যবহার করার, এই বাইনারি ফাইলটি পড়তে এবং তারপরে আমার যে ডেটা ব্যবহার করা দরকার সেগুলি সংরক্ষণ করার কোনও সুযোগ আছে কি?


1
এই ফাইলটি কি কোনও ফোর্টরান প্রোগ্রাম দ্বারা লিখিত হয়েছিল? যদি তা হয় তবে এটি কীভাবে লেখা হয়েছিল, যেহেতু ফোর্টরান, ডিফল্টরূপে, প্রতিটি রেকর্ড ফাইল করার আগে এটি অতিরিক্ত ডেটা যুক্ত করে। ডেটা পড়ার সময় আপনাকে এইটি যত্ন সহকারে নিতে হবে।
ক্রিস

1
দয়া করে আমার পূর্ববর্তী মন্তব্যটি উপেক্ষা করুন, 8 এবং 4 * এন সংখ্যার স্পষ্টতই এই অতিরিক্ত ডেটা।
ক্রিস

2
এছাড়াও, পাইথনে বাইনারি ফাইল পড়ার প্রশ্নের উত্তরগুলি দেখুন ।
ক্রিস

নম্পির fromfileফাংশন বাইনারি ফাইলগুলি পড়া সহজ করে তোলে। আমি এটি সুপারিশ।
ছোট

... এবং সর্বদা আপনার এন্ডিয়ান-নেসেসের জন্য নজর রাখুন, এসএসপি। বিভিন্ন প্রস্তুতকারকের কম্পিউটারের মধ্যে পোর্টিং করার সময়।
ড্রাগনলর্ড

উত্তর:


154

বাইনারি ফাইল সামগ্রীটি এর মতো পড়ুন:

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

তারপরে স্ট্রাক্ট.নপ্যাক ব্যবহার করে বাইনারি ডেটা "আনপ্যাক করুন" :

শুরু বাইট: struct.unpack("iiiii", fileContent[:20])

দেহ: শিরোনাম বাইট এবং ট্রেলিং বাইট উপেক্ষা করুন (= 24); অবশিষ্ট অংশটি শরীরকে গঠন করে, শরীরের বাইটের সংখ্যা জানতে 4 দ্বারা পূর্ণসংখ্যা বিভাগ হয়; 'i'আনপ্যাক পদ্ধতির জন্য সঠিক বিন্যাস তৈরি করতে প্রাপ্ত ভাগফলটি স্ট্রিং দ্বারা গুণিত হয় :

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

শেষ বাইট: struct.unpack("i", fileContent[-4:])


আপনি কি এই অন্যান্য পোস্ট তাকান করতে পারেন? stackoverflow.com/questions/8092469/… ... আমি আবার একটি বাইনারি ফাইল পড়তে এসেছি, তবে এই ক্ষেত্রে আমি বিশদে বাইট কাঠামো জানি না। উদাহরণস্বরূপ, আমি বুঝতে পেরেছিলাম যে কখনও কখনও পূর্ণসংখ্যা 8 থাকে However তবে আইডিএল সহ এই ডেটাটি পড়া খুব সহজ। আমি কি অজগর দিয়ে একই করতে পারি?
ব্রায়ান

আপনি পোস্ট করা উত্তর এবং মন্তব্যে কেন সন্তুষ্ট নন দয়া করে (অন্য পোস্টের ভিতরে, এখানে নয়) নির্দেশ করুন। আরও বিশদ সরবরাহ করার জন্য আপনারও সম্ভবত প্রশ্নটি আপডেট করা উচিত ... এটি আপডেট হয়ে গেলে আমার এটি একবার দেখুন।
gecco

যদি আপনার কোনও প্যাকযুক্ত চারি [] কোনও স্ট্রিংয়ে রূপান্তর করতে হয় তবে এই উত্তরটি দেখুন ।
পিটারএম 20'16

import struct
JW

23

সাধারণভাবে, আমি আপনাকে এটির জন্য পাইথনের স্ট্রাক্ট মডিউলটি ব্যবহার করার পরামর্শ দিচ্ছি into পাইথনের সাথে এটি স্ট্যান্ডার্ড এবং আপনার প্রশ্নের স্পেসিফিকেশনটিকে উপযুক্ত ফরমেটিং স্ট্রিংয়ে অনুবাদ করা সহজ হওয়া উচিত struct.unpack()

মনে রাখবেন যে যদি ক্ষেত্রগুলির মধ্যে / তার আশেপাশে "অদৃশ্য" প্যাডিং থাকে তবে আপনাকে এটি নির্ধারণ unpack()করতে হবে এবং এটি কলটিতে অন্তর্ভুক্ত করতে হবে, বা আপনি ভুল বিটগুলি পড়তে পারবেন।

আনপ্যাক করার জন্য কিছু রাখার জন্য ফাইলের বিষয়বস্তুগুলি পড়া খুব নগণ্য:

import struct

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

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

এটি প্রথম দুটি ক্ষেত্রটি আনপ্যাক করে ধরে নিচ্ছে যে তারা ফাইলের একেবারে শুরু (কোনও প্যাডিং বা বহিরাগত ডেটা নেই) শুরু করে এবং দেশীয় বাইট-অর্ডার ( @প্রতীক) ধরেও নেয়। Iবিন্যাস স্ট্রিং গুলি ", স্বাক্ষরবিহীন পূর্ণসংখ্যা 32 বিট" মানে।


ঠিক আছে, তবে আমি কীভাবে ফাইলের বাইটগুলি পড়তে জানি তাও জানি না। আমার প্রশ্ন থেকে আমি কীভাবে 5 থেকে 8 বাইট ফাইলটি পড়তে পারি এবং তারপরে ফলাফলটিকে পূর্ণসংখ্যায় রূপান্তর করতে পারি? দুঃখিত, তবে আমি পাইথনের সাথে নতুন।
ব্রায়ান

14

আপনি ব্যবহার করতে পারেন numpy.fromfile, যা পাঠ্য এবং বাইনারি ফাইল উভয় থেকে ডেটা পড়তে পারে । আপনি প্রথমে একটি ডেটা টাইপ তৈরি করবেন, যা আপনার ফাইল ফর্ম্যাটকে উপস্থাপন করে, এটি ব্যবহার করে numpy.dtypeএবং তারপরে ফাইলটি ব্যবহার করে এই প্রবন্ধটি পড়ুন numpy.fromfile


2
এটিকে মিস করা সহজ! ডক্স কিছুটা পাতলা; reddit.com/r/Python/comments/19q8nt/… কিছু আলোচনার জন্য দেখুন
হারিয়েছেন

11

কোনও bytesবস্তুর কাছে বাইনারি ফাইল পড়তে :

from pathlib import Path
data = Path('/path/to/file').read_bytes()  # Python 3.5+

intডেটার 0-3 বাইট থেকে একটি তৈরি করতে :

i = int.from_bytes(data[:4], byteorder='little', signed=False)

intডেটা থেকে একাধিক গুলি আনপ্যাক করতে :

import struct
ints = struct.unpack('iiii', data[:16])

0

বাইনারি ফাইলগুলি পড়ার এবং লেখার ক্ষেত্রে পাইথনটির অভাব দেখতে পেয়েছি, তাই আমি একটি ছোট মডিউল লিখেছি (পাইথন ৩.6+ এর জন্য)।

সঙ্গে binaryfile আপনি ভালো কিছু (আমি, অনুমান করছি যেহেতু আমি ফোরট্রান জানি না) করতে চাই:

import binaryfile

def particle_file(f):
    f.array('group_ids')  # Declare group_ids to be an array (so we can use it in a loop)
    f.skip(4)  # Bytes 1-4
    num_particles = f.count('num_particles', 'group_ids', 4)  # Bytes 5-8
    f.int('num_groups', 4)  # Bytes 9-12
    f.skip(8)  # Bytes 13-20
    for i in range(num_particles):
        f.struct('group_ids', '>f')  # 4 bytes x num_particles
    f.skip(4)

with open('myfile.bin', 'rb') as fh:
    result = binaryfile.read(fh, particle_file)
print(result)

যা এর ফলে একটি আউটপুট উত্পাদন করে:

{
    'group_ids': [(1.0,), (0.0,), (2.0,), (0.0,), (1.0,)],
    '__skipped': [b'\x00\x00\x00\x08', b'\x00\x00\x00\x08\x00\x00\x00\x14', b'\x00\x00\x00\x14'],
    'num_particles': 5,
    'num_groups': 3
}

ফোর্ত্রান যুক্ত হওয়া অতিরিক্ত ডেটা এড়াতে আমি স্কিপ () ব্যবহার করেছি, তবে আপনি তার পরিবর্তে ফোর্টরান রেকর্ডগুলি হ্যান্ডেল করার জন্য কোনও ইউটিলিটি যুক্ত করতে চাইতে পারেন। যদি আপনি এটি করেন, একটি টান অনুরোধ স্বাগত হবে।


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

6
এটি কেন অন্যান্য উত্তরগুলির চেয়ে ভাল (বা কমপক্ষে হিসাবে ভাল) এর চেয়ে একটু ব্যাখ্যা করার জন্য মূল্যবান।
ফিল

2
আপনি কি কোনও যাচাই করে পরীক্ষা করেছেন যা এই কেল্লাগুলি উত্পন্ন বাইনারি দিয়ে কাজ করে?
এজেন্টপ্রেস

1
এবং এটি কী করে তাও ব্যাখ্যা করুন ... আচার কী? কি pickle.loadবোঝা? এটি কি কোনও ফোর্টরান স্ট্রিম, সরাসরি বা অনুক্রমিক ফাইল লোড করে? এগুলি আলাদা এবং সামঞ্জস্যপূর্ণ নয়।
ভ্লাদিমির এফ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.