سؤال

أنا تستهلك تغذية البيانات التي أضافت مؤخرا رأس Unicode Bom (U + FEFF)، ومهمة أشعل النار الآن أفسد بها.

يمكنني تخطي أول 3 بايت مع file.gets[3..-1] ولكن هل هناك طريقة أكثر أناقة لقراءة الملفات في Ruby والتي يمكن أن تتعامل مع هذا بشكل صحيح، سواء كانت BOM موجودة أم لا؟

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

المحلول

مع روبي 1.9.2 يمكنك استخدام الوضع r:bom|utf-8

text_without_bom = nil #define the variable outside the block to keep the data
File.open('file.txt', "r:bom|utf-8"){|file|
  text_without_bom = file.read
}

أو

text_without_bom = File.read('file.txt', encoding: 'bom|utf-8')

أو

text_without_bom = File.read('file.txt', mode: 'r:bom|utf-8')

لا يهم، إذا كان BOM متاحا في الملف أم لا.


قد تستخدم أيضا خيار الترميز مع أوامر أخرى:

text_without_bom = File.readlines(@filename, "r:utf-8")

(تحصل على مجموعة مع جميع الخطوط).

أو مع CSV:

require 'csv'
CSV.open(@filename, 'r:bom|utf-8'){|csv|
  csv.each{ |row| p row }
}

نصائح أخرى

لن أتخطى عمياء البايت الثلاثة الأولى؛ ماذا لو كان المنتج توقف إضافة BOM مرة أخرى؟ ما يجب أن تفعله هو يختبر البايت القليلة الأولى، وإذا كانت 0xef 0xbb 0xbf، تجاهلها. هذا هو شكل حرف BOM (U + FEFF) يأخذ في UTF-8؛ أفضل التعامل معها قبل محاولة فك تشفير الدفق لأن المناولة BOM غير متسقة للغاية من لغة / أداة / إطار إلى آخر.

في الواقع، هذا هو كيف حالك مفترض للتعامل مع bom. إذا تم تقديم ملف مثل UTF-16، فعليك فحص أول اثنين من البايتين قبل أن تبدأ فك التشفير حتى تعرف ما إذا كنت قد قرأتها بأنها نبيذ كبير أو قليل. بالطبع، لا علاقة ل BOM UTF-8 بأمر بايت، إنه موجود فقط لأعلمك أن الترميز هو UTF-8، في حال لم تعرف ذلك بالفعل.

لن يتم ترميز بعض الملفات "ثقة" في بعض الملفات UTF-8 عند وجود bom of 0xef 0xbb 0xbf، فقد تفشل. عادة عند اكتشاف UTF-8 BOM، يجب أن يكون بالفعل ملف مشفر UTF-8 بالطبع. ولكن، إذا كان على سبيل المثال، فقد أضف شخص ما لتوه Outf-8 Bom إلى ملف ISO، فستفشل في تشفير هذا الملف سيئا للغاية إذا كان هناك بايت في ذلك أعلاه 0x0f. يمكنك الوثوق في الملف إذا كان لديك فقط بايت حتى 0x0f في الداخل، لأنه في هذه الحالة هو ملف ASCII متوافق مع UTF-8 وفي نفس الوقت هو ملف UTF-8 صالح.

إذا لم يكن هناك بايت فقط <= 0x0f داخل الملف (بعد BOM)، للتأكد من أنه يتم ترميز UTF-8 بشكل صحيح، فسيتعين عليك التحقق من تسلسل صالح و - حتى عندما تكون جميع التسلسلات صالحة - تحقق أيضا إذا كان كل منها يستخدم CodePoint من تسلسل أقصر تسلسل ممكن وتحقق أيضا إذا لم يكن هناك CodePoint يطابق بديلة عالية أو منخفضة. تحقق أيضا من ما إذا كان الحد الأقصى لحياء التسلسل لا يزيد عن 4 وأعلى CodePoint هو 0x10FFFF. أعلى حدود CodePoint أيضا BITS الحمولة الخاصة ب STARTBYTE غير مرتفعة من 0x4 وأول حمولات بايت التالية ليس أعلى من 0xf. إذا تم تمرير جميع الشيكات المذكورة بنجاح، فإن UTF-8 Bom يحكي الحقيقة.

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