سؤال

في بايثون يمكنك استخدام StringIO لمخزن مؤقت يشبه الملف لبيانات الشخصية. ملف الذاكرة المعينة يقوم بشكل أساسي بنفس الشيء بالنسبة للبيانات الثنائية، ولكنه يتطلب ملفًا يتم استخدامه كأساس.هل تحتوي لغة Python على كائن ملف مخصص للبيانات الثنائية وهو عبارة عن ذاكرة فقط، أي ما يعادل لغة Java ByteArrayOutputStream?

حالة الاستخدام التي أستخدمها هي أنني أريد إنشاء ملف ZIP في الذاكرة، و ملف مضغوط يتطلب كائنًا يشبه الملف.

هل كانت مفيدة؟

المحلول

ربما كنت تبحث عنه io.BytesIO فصل.إنه يعمل تمامًا مثل StringIO باستثناء أنه يدعم البيانات الثنائية:

from io import BytesIO
bio = BytesIO(b"some initial binary data: \x00\x01")

سترمي StringIO خطأ TypeError:

from io import StringIO
sio = StringIO(b"some initial binary data: \x00\x01")

نصائح أخرى

طالما أنك لا تحاول وضع أي بيانات Unicode في ملف StringIO وأنت حريص على عدم الاستخدام cStringIO يجب أن تكون بخير.

بحسب ال StringIO الوثائق، طالما أنك تحتفظ إما بـ Unicode أو 8 بت، فكل شيء يعمل كما هو متوقع.محتمل، StringIO يفعل شيئا خاصا عندما يفعل شخص ما f.write(u"asdf") (وهو ما لا يفعله ZipFile، على حد علمي).على أي حال؛

import zipfile
import StringIO

s = StringIO.StringIO()
z = zipfile.ZipFile(s, "w")
z.write("test.txt")
z.close()
f = file("x.zip", "w")
f.write(s.getvalue())
s.close()
f.close()

يعمل تمامًا كما هو متوقع، ولا يوجد فرق بين الملف الموجود في الأرشيف الناتج والملف الأصلي.

إذا كنت تعرف حالة معينة لا يعمل فيها هذا النهج، سأكون مهتمًا جدًا بمعرفة ذلك :)

انظر إلى حزمة البنية: https://docs.python.org/library/struct.html, ، فهو يسمح لك بتفسير السلاسل كبيانات ثنائية معبأة.

لست متأكدًا مما إذا كان هذا سيجيب على سؤالك تمامًا ولكن يمكنك استخدام struct.unpack() لتحويل البيانات الثنائية إلى كائنات بايثون.


import struct
f = open(filename, "rb")
s = f.read(8)
x, y = struct.unpack(">hl", s)

في هذا المثال، يخبرنا ">" بقراءة النهاية الكبيرة، بينما يقرأ "h" مسافة قصيرة بطول 2 بايت، و"l" بطول 4 بايت.من الواضح أنه يمكنك تغييرها إلى ما تحتاج إلى قراءته من البيانات الثنائية...

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top