يمكن أن تسعى وإخبار العمل مع المستندات المشفرة UTF-8 في بيثون؟

StackOverflow https://stackoverflow.com/questions/1510188

  •  19-09-2019
  •  | 
  •  

سؤال

لدي تطبيق ينشئ بعض ملفات السجل الكبيرة> 500 ميغابايت.

لقد كتبت بعض المرافق في بيثون التي تسمح لي بتصفح ملف السجل بسرعة والعثور على بيانات ذات أهمية. لكنني أحصل الآن على بعض مجموعات البيانات حيث يكون الملف كبيرا جدا لتحميل كل شيء في الذاكرة.

هكذا أريد مسح المستند مرة واحدة، قم ببناء فهرس ثم قم بتحميل قسم المستند فقط في الذاكرة التي أريد أن أنظر إليها في وقت واحد.

يعمل هذا لي عندما أفتح "ملف" قرأته سطر واحد في وقت واحد وتخزين الإزاحة من file.tell (). يمكنني بعد ذلك العودة إلى هذا القسم من الملف لاحقا مع file.seek (الإزاحة، 0).

مشكلتي ومع ذلك فقد لدي UTF-8 في ملفات السجل، لذلك أحتاج إلى فتحها باستخدام وحدة الترميز (codecs.open(<filename>, 'r', 'utf-8')). مع الكائن الناتج، يمكنني الاتصال بالتسعى وإخبارها لكنها لا تتطابق معها.

أفترض أن برامج الترميز تحتاج إلى القيام ببعض التخزين المؤقت أو ربما ترجع عدد الأحرف بدلا من البايتات من أخبر؟

هل هناك طريقة للتغلب على ذلك؟

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

المحلول

إذا كان هذا صحيحا، فهذا يبدو وكأنه خطأ أو قيود على وحدة برامج الترميز، حيث أنه من المحتمل أن يربك البايت وآفاق الحرف.

أود استخدام العادية open() وظيفة لفتح الملف، ثم seek()/tell() سوف تعطيك إزاحات البايت التي تتفق دائما. كلما أردت القراءة، استخدم f.readline().decode('utf-8').

حذار على الرغم من ذلك باستخدام f.read() يمكن للوظيفة تهبطك في منتصف حرف متعدد البايات، مما يؤدي إلى إنتاج خطأ فك التشفير UTF-8. readline() سوف تعمل دائما.

هذا لا يتعامل بشفافية مع علامة ترتيب البايت لك، لكن الفرص هي ملفات السجل الخاصة بك لا تحتوي على بومتين على أي حال.

نصائح أخرى

بالنسبة إلى UTF-8، لا تحتاج فعليا لفتح الملف باستخدام Codecs.Open. بدلا من ذلك، فهو موثوقة لقراءة الملف كسلسلة بايت أولا، ثم فك شفرة قسم فردي فقط (استدعاء طريقة .DECODE على السلسلة). كسر الملف في حدود الخط آمنة؛ الطريقة غير الآمنة الوحيدة لتقسيمها ستكون في منتصف شخصية متعددة البايات (والتي يمكنك التعرف عليها من قيمة البايت> 128).

الكثير من ما يحدث مع UTF8 في Python منطقي إذا نظرت إلى كيفية القيام به في Python 3. في حالتك، سيكون من المعنى أكثر قليلا إذا كنت تقرأ فصل الملفات في الغوص في Python 3: http://diveintopython3.org/files.html.

اختصار ذلك، على الرغم من ذلك file.seek و file.tell العمل مع مواقف البايت، في حين أن أحرف يونيكود يمكن أن تأخذ بايت متعددة. وهكذا، إذا قمت بذلك:

f.seek(10)
f.read(1)
f.tell()

يمكنك بسهولة الحصول على شيء آخر غير 17, ، اعتمادا على طول الشخصية التي قرأتها واحدة.

تحديث: لا يمكنك البحث / معرفة الكائن الذي تم إرجاعه بواسطة Codec.Open (). تحتاج إلى استخدام ملف عادي، وفك تشفير السلاسل إلى Unicode بعد القراءة.

أنا لا أعرف لماذا لا يعمل ولكن لا يمكنني القيام بذلك. يبدو أن السعي يعمل مرة واحدة فقط، على سبيل المثال. ثم تحتاج إلى إغلاق الملف وإعادة فتحه، وهو بالطبع غير مفيد.

لا يستخدم القول مواقع الأحرف، ولكن لا ينظر إليك حيث يكون موضعك في الدفق (ولكن ربما يكون لك كائن الملف الأساسي في القراءة من القرص).

لذلك ربما بسبب نوع من التخزين المؤقت الأساسي، لا يمكنك القيام بذلك. لكن الغطاء بعد القراءة يعمل بشكل جيد، لذلك اذهب لذلك.

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