شرح ترميزات النصّ ونهايات السطور في Windows - Shift_JIS و UTF-8 و UTF-16 و mojibake و CRLF و LF
· 小村 豪 · Windows, ترميزات النصّ, mojibake, نهايات السطور, UTF-8, CP932, PowerShell, Unicode
في النقاشات حول التعامل مع النصّ في Windows، تختلط الموضوعات الآتية بسرعة كبيرة:
- ما الفرق بين
Shift_JISوUTF-8 - لماذا يحدث mojibake
- ما الفرق بين
CRLFوLF - لماذا قد يبقى شيء ما يفشل حتّى بعد
التحوّل إلى UTF-8 - لماذا يبدو الملفّ نفسه مختلفًا في المحرّر، والـ console، و Excel، و Git
هذا لا يحدث لأنّ اليابانيّة صعبة في ذاتها. ففي معظم الحالات، يكون السبب أنّ التتالي البايتيّ نفسه قُرئ تحت افتراض مختلف، أو أنّ محتوى مُساء قراءته حُفظ كما هو.
يُظهر Windows القصّة بمظهر أكثر تعقيدًا لأنّ عالم Unicode وعالم الـ code page لا يزالان متعايشَين هناك. فوق ذلك، يتراكم BOM ونهايات السطور، والكشف التلقائيّ في المحرّرات، و code page الخاصّة بالـ console، وتحويل نهايات السطور في Git.
تنظّم هذه المقالة الموضوعات التي تختلط بكثرة في Windows: Shift_JIS / UTF-8 / UTF-16، ولماذا يحدث mojibake، والفرق بين CRLF و LF، ولماذا يصبح الموضوع كلّه مربكًا بسهولة في الممارسة.
يستند المحتوى إلى Microsoft Learn، و PowerShell، و Git، والوثائق العامّة المتعلّقة بـ W3C / Unicode، المتوفّرة حتّى أبريل 2026. للاطّلاع على التفاصيل راجع المراجع في النهاية.
جدول المحتويات
- ما ينبغي وضعه في الذهن أوّلًا
- تفكيك المصطلحات
- 2.1 ما الفرق بين Unicode / UTF-8 / UTF-16 / CP932
- 2.2 كيف نفكّر في
Shift_JISوCP932 - 2.3 الفخاخ خلف كلمات
ANSIوUnicodeوUTF-8N
- لماذا يحدث mojibake
- 3.1 ما هو mojibake فعلًا
- 3.2 كسر العرض وتلف البيانات شيئان مختلفان
- 3.3 بمجرّد العودة إلى ترميز لا يمكنه تمثيل الأحرف، لن تستردّها
- ماذا يعني الفرق في نهايات السطور
- 4.1
CRLF/LF/CR - 4.2 نهايات السطور قضيّة مختلفة عن ترميز النصّ
- 4.3
\nليس دائمًا الشيء نفسه الذي يخزَّن في الملفّ بوصفه بايتات السطر الجديد
- 4.1
- لماذا يسهل الوقوع في الخطأ في Windows بشكل خاصّ
- 5.1 يتعايش Unicode مع code pages القديمة
- 5.2 التسميات غير متّسقة
- 5.3 المحتوى المقتصر على ASCII يخفي المشكلة
- 5.4 محتوى الملفّ، وأسماء الملفّات، والـ console، وملفّات المصدر طبقات مختلفة
- 5.5 BOM ونهايات السطور تهمّ على محورين منفصلين
- 5.6 الأدوات تغيّر الأمور بصمت
- أنماط الإخفاق الشائعة
- قواعد تقلّل الحوادث في الممارسة
- التحقيق في mojibake وفروق نهايات السطور بهذه الأسئلة الخمسة
- الخلاصة
- مقالات ذات صلة
- المراجع
1. ما ينبغي وضعه في الذهن أوّلًا
إذا أردنا سرد الخلاصة فقط أوّلًا، فالنقاط السبع المهمّة هي هذه:
- ملفّ النصّ ليس مجرّد سلسلة محارف في ذاته؛ إنّه مبنيّ من بايتات + ترميز + اصطلاح نهاية سطر. وبحسب الحالة، قد يكون BOM داخلًا أيضًا.
- يحدث mojibake عندما تُفكَّ نفس البايتات تحت افتراض ترميز مختلف
- تحدث مشكلة نهايات السطور عندما يكون الترميز صحيحًا لكنّ الافتراض حول فواصل السطور ليس كذلك
UnicodeوUTF-8لا يعنيان الشيء نفسه. فـUnicodeيخصّ جانب مجموعة المحارف، بينماUTF-8وUTF-16ترميزان.- في Windows، ما يسمّيه الناس
Shift_JISيُعالَج عمليًّا بصورة أفضل بوصفه CP932 / Windows Japanese code page - قول
لقد تحوّلنا إلى UTF-8فقط لا يكفي. تحتاج أيضًا إلى تحديد هل هناك BOM و أيّ نمط من نهايات السطور يُستخدم - المصدر الحقيقيّ للارتباك ليس اليابانيّة في ذاتها، بل أنّ افتراضات تاريخيّة متعدّدة لا تزال متعايشة معًا على الجهاز ذاته في Windows
في الممارسة، نقطة البداية الصحيحة هي الفصل بين هذه الأسئلة الأربعة:
- ما البايتات في هذا الملفّ؟
- تحت أيّ ترميز كُتب؟
- تحت أيّ ترميز يُقرأ الآن؟
- هل نهايات السطور
CRLFأمLF؟
بمجرّد فصل هذه الأسئلة، يصبح التحقيق عادةً أسهل بكثير.
2. تفكيك المصطلحات
2.1 ما الفرق بين Unicode / UTF-8 / UTF-16 / CP932
أسرع طريقة للمضيّ قُدُمًا هي تفكيك الكلمات لمرّة واحدة.
| المصطلح | إلى ماذا يشير | مثال | الالتباس الشائع |
|---|---|---|---|
| Unicode | إطار لإسناد أرقام إلى المحارف | U+3042 (あ) |
يظنّ الناس أنّه الشيء نفسه مثل UTF-8 |
| UTF-8 | ترميز يحوّل Unicode إلى بايتات | E3 81 82 |
يظنّ الناس أنّه Unicode في ذاته |
| UTF-16LE | ترميز يحوّل Unicode إلى بايتات | 42 30 |
يخلط الناس بينه وبين تسمية قائمة مثل Unicode |
| CP932 | code page اليابانيّ التراثيّ في Windows | 82 A0 |
يفترض الناس أنّه مطابق تمامًا لـ Shift_JIS |
| CRLF / LF | تتاليات بايتيّة تفصل بين السطور | 0D 0A / 0A |
يظنّ الناس أنّها نوع من الترميز |
| BOM | بايتات تعريفيّة في بداية الملفّ | EF BB BF وما شابه |
يظنّ الناس أنّها اسم الترميز نفسه |
حتّى للحرف المنفرد あ، تختلف البايتات بحسب الترميز:
Character: あ
UTF-8 : E3 81 82
CP932 : 82 A0
UTF-16LE : 42 30
النقطة المهمّة هي أنّ المحارف والبايتات ليست الشيء نفسه. تعرض لك التطبيقات شيئًا يبدو مثل المحارف على الشاشة، لكنّها عند الحفظ أو الإرسال تتبادل بايتات في النهاية. تحدث الحوادث عادةً عند حدّ التحويل ذلك.
2.2 كيف نفكّر في Shift_JIS و CP932
في المشاريع الواقعيّة، كثيرًا جدًّا ما تُسمّى ملفّات النصّ اليابانيّ في Windows Shift_JIS كمصطلح شامل. هذا يكفي محادثاتيًّا، لكنّه غير دقيق نسبيًّا للعمل التنفيذيّ.
إن أردت أن تكون أكثر دقّة بشأن النصّ اليابانيّ التراثيّ في Windows، فالأكثر أمانًا هو التفكير من زاوية CP932، أو على نطاق أوسع Windows Japanese code page.
إن بقيت غامضًا هنا، تبدأ المحادثات في الانحراف هكذا:
- يقول أحدهم
احفظه بـ Shift_JIS، لكنّ الطرف الآخر يفترض في الواقع CP932 على نمط Windows - تتعامل Linux أو macOS مع الملفّ بوصفه
shift_jis، لكنّ بعض الملفّات الناشئة في Windows لا تُستنسخ تمامًا كما هو متوقَّع - يقول أحدهم
احفظ بـ ANSI، لكنّ أيّ code page يعني ذلك يعتمد على البيئة
لذا، في المواصفات وملاحظات التحقيق، الأكثر أمانًا أن تكتب الأمور بصورة أكثر صراحة:
- اكتب
CP932بدلًا منShift_JIS - اكتب
ACP (active code page) / عادةً CP932 على Windows اليابانيّبدلًا منANSI - اكتب شيئًا محدّدًا مثل
UTF-8 no BOM، LFبدلًا من مجرّدtext
2.3 الفخاخ خلف كلمات ANSI و Unicode و UTF-8N
حول Windows، التسميات نفسها جزء من المشكلة.
الفخاخ الشائعة هي هذه:
ANSI
يظهر هذا في واجهات Windows القديمة والشروح القديمة، لكنّه لا يعني ASCII. ففي حالات كثيرة يعني active code page الخاصّ بالجهاز.Unicode
في بعض المحرّرات والأدوات، تسمية القائمةUnicodeتعني فعلًا UTF-16LE. إذا قال أحدهمحفظتُه كـ Unicode، فهذا لا يعني تلقائيًّاUTF-8.UTF-8N
قد ترى هذه التسمية في محرّرات السوق اليابانيّ. عادةً ما تكون مجرّد تسمية UI للتمييز عن UTF-8 بدون BOM. إنّها ليست اسم ترميز رسميًّا.
بعبارة أخرى، في Windows يمكن للكلمة نفسها أن تعني أشياء مختلفة قليلًا بحسب الأداة. هذه واحدة من أوّل المصادر الكبرى للارتباك.
3. لماذا يحدث mojibake
3.1 ما هو mojibake فعلًا
mojibake نفسه بسيط مفهوميًّا:
- حوِّل سلسلة محارف إلى بايتات بترميز واحد
- حوِّل تلك البايتات مرّة أخرى إلى سلسلة محارف بترميز مختلف
- إن لم تتطابق الافتراضات، تحصل على سلسلة محارف مختلفة
على سبيل المثال، إذا حُفظ あ بـ UTF-8، تكون البايتات:
E3 81 82
إذا قُرئت تلك البايتات على أنّها UTF-8، فستحصل على あ. أمّا إذا قُرئت تحت افتراض موجَّه بـ CP932، فقد تظهر بصورة 縺� أو نصّ مكسور آخر.
ما هو مكسور هناك ليس النصّ اليابانيّ في ذاته، بل افتراض فكّ الترميز.
إن أردت تلخيص mojibake في جملة واحدة، فهي هذه:
قُرئت نفس البايتات وكأنّها تنتمي إلى ترميز مختلف.
3.2 كسر العرض وتلف البيانات شيئان مختلفان
من المهمّ الفصل بين المرحلة التي لا يزال الاسترداد فيها ممكنًا، والمرحلة التي يصبح فيها الاسترداد أصعب بكثير.
على سبيل المثال، الآتي قد يبقى قابلًا للاسترداد:
- افتح ملفّ UTF-8 وكأنّه CP932
- يبدو على الشاشة مثل
縺� - لم يُحفظ شيء بعد
في تلك المرحلة لا تزال البايتات الأصليّة بـ UTF-8. إذا أُعيد فتح الملفّ بالترميز الصحيح، فقد يستردّ النصّ.
المسار الخطير هو هذا:
- أُسيءَ قراءة ملفّ UTF-8 كـ CP932
- حُفظ العرض المكسور أصلًا كما هو
- فُقد التتالي البايتيّ الأصليّ بـ UTF-8
في تلك المرحلة لم تَعُد قضيّة عرض فحسب. إنّها تلف بيانات.
في الممارسة، بدلًا من تسطيح كلّ شيء في جملة أصبح mojibake، ينبغي على الأقلّ الفصل بين هذين السؤالين:
- هل البايتات نفسها لا تزال صحيحة؟
- أم أنّ المحتوى المُساء قراءته قد حُفظ بالفعل من جديد؟
3.3 بمجرّد العودة إلى ترميز لا يمكنه تمثيل الأحرف، لن تستردّها
حالة خطيرة أخرى هي عندما تُدفَع سلسلة Unicode إلى code page أضيق مثل CP932.
إن لم يكن في وسع code page الهدف تمثيل بعض المحارف، يحدث عادةً أحد الآتي:
- تُستبدل بـ
? - تُدرَج محارف استبدال
- تحدث أخطاء تحويل
- تُجبَر على محارف مختلفة شبيهة الشكل
على سبيل المثال، بعض emoji وبعض الأحرف الصينيّة الموسَّعة لا يمكن أن تجتاز رحلة ذهاب وإياب إلى CP932.
لا ينبغي الحكم على هذا بمجرّد ما إذا كان النصّ لا يزال قابلًا للقراءة، بل بـ ما إذا كانت رحلة الذهاب والإياب تحفظ النصّ الأصليّ.
بمجرّد ضياع المعلومات، لن تعيد معرفة الترميز الصحيح لاحقًا بناءها.
4. ماذا يعني الفرق في نهايات السطور
4.1 CRLF / LF / CR
نهايات السطور أيضًا بايتات.
CR= carriage return =0DLF= line feed =0A- في ملفّات نصّ Windows التقليديّة،
CRLF(0D 0A) هي الصورة الكلاسيكيّة - في الأنظمة على نمط Linux / Unix،
LF(0A) هي الصورة الشائعة - يظهر
CRالمنفرد في الغالب في سياقات تاريخيّة قديمة مثل بيانات Mac الكلاسيكيّة
في صورة جدول:
| نهاية السطر | البايتات | السياق المعتاد |
|---|---|---|
CRLF |
0D 0A |
ملفّات نصّ Windows التقليديّة، الأدوات التراثيّة |
LF |
0A |
Linux / macOS / كثير من أدوات التطوير |
CR |
0D |
بيانات تراثيّة قديمة جدًّا |
4.2 نهايات السطور قضيّة مختلفة عن ترميز النصّ
هذه النقطة مهمّة جدًّا.
نمط نهاية السطر قضيّة مختلفة عن الترميز.
حتّى ملفّان من UTF-8 قد يختلفان في نهايات السطور فقط.
مثلًا، إذا كان المحتوى A ثمّ سطر جديد ثمّ B، تصبح البايتات:
UTF-8 + LF : 41 0A 42
UTF-8 + CRLF : 41 0D 0A 42
لذا فإنّ كلّ ما يلي ممكن تمامًا:
- ملفّ بـ
UTF-8، لكنّ نهايات السطور هي ما يختلف فقط - ملفّ بـ
CP932، لكنّ نهايات السطورLF - ملفّ بـ
UTF-16LE، لكنّ نهايات السطورCRLF
ولذلك، حين يقول أحدهم لقد غيّرناه بالفعل إلى UTF-8 لكنّ شيئًا ما لا يزال غير سليم، قد يكون الفرق الفعليّ هو نهايات السطور وحسب.
4.3 \n ليس دائمًا الشيء نفسه الذي يخزَّن في الملفّ بوصفه بايتات السطر الجديد
هذا مصدر سهل للارتباك من زاوية المبرمج.
مجرّد أنّك كتبت \n في الكود المصدريّ لا يضمن أنّ ما يخزَّن في الملفّ هو 0A فقط.
في text mode، بحسب اللغة أو وقت التشغيل أو واجهة I/O API، قد يُحوَّل \n إلى CRLF على Windows.
هذا يعني أنّ هذه الأمور قد تنحرف عن بعضها:
- تمثيل السطر الجديد في الكود المصدريّ
- السلسلة المحرفيّة في وقت التشغيل
- البايتات المحفوظة في الملفّ
- فواصل السطور الظاهرة في المحرّر
ولذا تنتهي أحيانًا بـ ظننتُ أنّي كتبتُ LF، لكنّ الملفّ صار CRLF.
تستطيع المحرّرات الحديثة التعامل مع LF المجرَّد جيّدًا، لكنّ الأدوات المحيطة، والتطبيقات التراثيّة، وسير العمل في الأعمال لا تزال كثيرًا ما تفترض CRLF.
لذا فإنّ متاعب نهايات السطور ليست مجرّد قصّة قديمة. إنّها لا تزال تظهر في العمل اليوميّ الاعتياديّ.
5. لماذا يسهل الوقوع في الخطأ في Windows بشكل خاصّ
5.1 يتعايش Unicode مع code pages القديمة
هذا هو السبب الأكبر الواحد الذي يجعل Windows معقّدًا.
لا يزال Windows يحوي كلًّا من:
- مسار يستخدم Unicode
- مسار يستخدم code pages
التطبيقات الأحدث، والأصول المتعلّقة بالويب، والأنظمة العابرة للمنصّات تميل إلى UTF-8، بينما CSV و TXT والسجلّات القديمة، وسير العمل المتاخم لـ Excel، وتكامل أنظمة الأعمال كثيرًا ما لا تزال تحمل CP932.
فوق ذلك، بعض المخرجات وبعض الـ APIs لا تزال تُصدر UTF-16LE بصورة طبيعيّة.
بعبارة أخرى، تتعايش ثقافات نصّ متعدّدة على جهاز Windows واحد.
5.2 التسميات غير متّسقة
ما يزيد الارتباك ليس التقنيّة في ذاتها في الغالب، بل التسميات:
- يقول الناس
Shift_JIS، لكنّ الواقع هو CP932 - يقول الناس
ANSI، لكنّ الواقع هو active code page - يقول الناس
Unicode، لكنّ الواقع هو UTF-16LE - يقول الناس
UTF-8، لكنّ ما إذا كان BOM موجودًا لا يزال غير محدَّد - تظهر تسميات خاصّة بمحرّرات مثل
UTF-8N
إن بقي ذلك غامضًا، تبدو المحادثة متطابقة بينما الافتراضات التقنيّة الفعليّة ليست كذلك.
5.3 المحتوى المقتصر على ASCII يخفي المشكلة
هذا أيضًا يهمّ كثيرًا.
نظرًا لأنّ UTF-8 متوافق مع نطاق ASCII، فإنّ الملفّات التي تحوي حروفًا وأرقامًا ورموزًا فقط قد تبدو جيّدة نوعًا ما حتّى تحت الافتراض الخاطئ.
على جانب CP932، النطاق المكافئ لـ ASCII أيضًا كثيرًا ما ينجو بصريًّا، فلا تظهر القضيّة.
نتيجةً لذلك، تحصل على حالات مثل:
- ملفّ إعدادات بالإنجليزيّة فقط يبدو سليمًا
- في اللحظة التي يُضاف فيها سطر واحد من اليابانيّة، ينكسر
- مشكلة كامنة تطفو إلى السطح للمرّة الأولى أثناء التشغيل
ولذلك تبدو حوادث الترميز كثيرًا بصورة كان يعمل حتّى الأمس وانكسر فجأةً اليوم.
في الواقع، كان الفخّ موجودًا بالفعل، ولم يصبح مرئيًّا إلّا حين دخل نصّ غير ASCII الملفّ.
5.4 محتوى الملفّ، وأسماء الملفّات، والـ console، وملفّات المصدر طبقات مختلفة
في Windows، إذا سمّيتَ كلّ هذه ترميزًا، فستضلّ:
- أسماء الملفّات / المسارات
- محتويات الملفّات
- عرض الـ console
- ترميز ملفّ الكود المصدريّ نفسه
- التمثيل النصّيّ في وقت التشغيل
- عرض الحافظة أو مكوّنات GUI
على سبيل المثال، قد تظهر أسماء الملفّات اليابانيّة بشكل طبيعيّ بينما لا تزال محتويات الملفّ محفوظة بـ CP932.
أو قد يكون الملفّ نفسه بـ UTF-8 بينما العرض مكسور فقط لأنّ code page الـ console خاطئ.
عمليّة مثل chcp 65001 تغيّر افتراضًا أساسًا على جانب الـ console. إنّها لا تعيد كتابة بايتات ملفّ موجود.
كذلك، حتّى لو كان ملفّ الكود المصدريّ بـ UTF-8، فهذا لا يعني أنّ ملفّ السجلّ المكتوب في وقت التشغيل هو أيضًا بـ UTF-8.
عليك أن تفصل في كلّ مرّة أيّ طبقة ترميز تتحدّث عنها.
في Windows اليابانيّ، قد يظهر \ أيضًا كرمز الين. ويختلط ذلك كثيرًا في نقاش الترميز.
لكن في كثير من الحالات تلك قضيّة خطّ أو عرض رسم glyph، لا تغيير في فاصل المسار أو دلالات الـ escape.
5.5 BOM ونهايات السطور تهمّ على محورين منفصلين
تسمية UTF-8 لا تزال تترك نصف القصّة فقط معرَّفًا.
في الممارسة، تهمّ هذه أيضًا:
- هل BOM موجود أم غائب؟
- هل نهايات السطور
CRLFأمLF؟
على سبيل المثال، حتّى مع UTF-8 نفسه:
- بعض أدوات Windows تقرأه فقط حين يكون BOM موجودًا
- بعض المعالجة على نمط Unix تعامل BOM بوصفه إضافة غير مرغوبة في بداية الحقل الأوّل
- بعض الأدوات على الجانب التراثيّ غير ملائمة إن كان الملفّ
LFفقط - يمكن أن يجعل
CRLFنصوص shell أو الـ diffs أكثر ضوضاء
لذا يمكن أن تظلّ لديك حوادث حتّى بعد مطابقة الترميز نفسه.
5.6 الأدوات تغيّر الأمور بصمت
ما يزيد الأمر صعوبةً أنّ الأدوات المحلّيّة قد تضيف سلوكًا ضمنيًّا:
- يكتشف المحرّر الترميز تلقائيًّا
- عمليّات الحفظ تُضيف BOM أو تزيله
- يحوّل Git بين
CRLF/LF - shell أو أمر يكتب باستخدام ترميزه الافتراضيّ
- تصدير CSV يستخدم code page غير متوقَّع
- إصدار مختلف من PowerShell أو من أداة يغيّر الإعدادات الافتراضيّة
لذا، حتّى عندما لم يغيّر الشخص الذي يشغّل النظام شيئًا صراحةً، قد تكون طبقة ما قد أدخلت افتراضها الخاصّ.
هذا هو المعنى الحقيقيّ لـ انكسر مع أنّي لم أغيّر شيئًا.
في الغالب، لم يكن شخصًا هو من غيّر، بل السلوك الافتراضيّ للأداة.
6. أنماط الإخفاق الشائعة
تبدو الحوادث النموذجيّة كذلك:
| الموقف | ما المختلّ فعلًا | العَرَض النموذجيّ |
|---|---|---|
أداة Windows تراثيّة تعامل ملفّ إعدادات UTF-8-no-BOM على أنّه ANSI / CP932 |
افتراض فكّ الترميز | يصبح النصّ اليابانيّ فقط mojibake |
| تُمرَّر CSV بـ CP932 إلى مسار معالجة موجَّه بـ UTF-8 | افتراض فكّ الترميز | �، أخطاء فكّ ترميز، أو نصّ يابانيّ بلا معنى |
| يُمرَّر سجلّ UTF-16LE إلى أدوات نصّ على نمط Unix | افتراض الترميز | تظهر بايتات NUL ويبدو مثل بيانات ثنائيّة |
ملفّ مصدر بـ LF يُحوَّل إلى CRLF في بيئة أخرى |
افتراض السطر الجديد | فروق هائلة في نهايات السطور أو متاعب في النصوص البرمجيّة |
| المحتوى المُساء قراءته يُحفظ كما هو | البايتات نفسها تصير شيئًا آخر | تلف بيانات لا رجعة فيه |
المواصفة تقول فقط export CSV |
الواجهة غير معرَّفة | يستطيع Excel قراءته، لكنّ أداة أخرى تفشل |
يقرّر الفريق فقط توحيد التشغيل على UTF-8 |
يبقى BOM / نهايات السطور غير معرَّفة | تفشل بعض الأدوات |
المسار الخطير بشكل خاصّ هو رؤية العرض المكسور ثمّ حفظه، ممّا يحوّل سوء فهم قابلًا للاسترداد إلى حادثة مؤكَّدة.
7. قواعد تقلّل الحوادث في الممارسة
من هنا فصاعدًا، السؤال هو ما القواعد التي تقلّل الحوادث على المستوى التشغيليّ.
7.1 حدِّد خطّ الأساس للملفّات النصّيّة الجديدة
للملفّات الجديدة، UTF-8 خيار أوّل معقول.
لكنّ ذلك وحده لا يكفي.
في الحدّ الأدنى، حدِّد هذه أيضًا:
- هل هو
UTF-8 with BOMأمUTF-8 no BOM - هل نهايات السطور
CRLFأمLF - من سيقرأ الملفّ
- هل التوافق مع أدوات Windows التراثيّة مطلوب
- هل تستهلك Linux / macOS / CI / الحاويات الملفّ أيضًا
على سبيل المثال، إن كان كودًا مصدريًّا أو إعدادًا عابرًا للمنصّات، فإنّ UTF-8 no BOM + LF كثيرًا ما يكون أقوى مرشّح أوّل.
في المقابل، إن كان لا بدّ أن يلائم أدوات Windows القديمة أو عمليّة تشغيل قائمة، فقد يكون UTF-8 with BOM أو CP932 + CRLF هو الخيار الصحيح.
المهمّ ليس إجابة كونيّة على ما الصحيح موضوعيًّا، بل مع من يحتاج هذا الملفّ إلى التعامل البَيْنيّ.
7.2 لا تغيّر الملفّات التراثيّة الموجودة بصمت
إن كان ملفّ موجود بـ CP932، فالأكثر أمانًا عادةً ألّا تحوّله إلى UTF-8 كأثر جانبيّ لتحرير يوميّ صغير.
النموذج التشغيليّ الأكثر أمانًا هو:
- احتفظ بالترميز / BOM / نهايات السطور الأصليّة للملفّات الموجودة
- عامل تحويل الترميز بوصفه مهمّة هجرة منفصلة
- أكِّد المجموعة المستهدفة والمستهلكين النهائيّين قبل إجراء تحويل دفعيّ
حصّة كبيرة من حوادث mojibake تأتي من نوايا حسنة من نوع بما أنّي هنا، سأحدِّثه.
7.3 عامل الترميز ونهايات السطور بوصفها جزءًا من الواجهة
CSV و TXT والسجلّات وملفّات الإعدادات والبروتوكولات الخفيفة لا تتعلّق بالمحتوى وحده. تنسيق النصّ نفسه جزء من الواجهة.
في الحدّ الأدنى، ينبغي أن تنصّ المواصفة على:
- الترميز
- ما إذا كان BOM موجودًا
- نمط السطر الجديد
- ما إذا كان هناك header
- قواعد الاقتباس / الفاصل
- ما الأدوات التي استُخدمت للتحقّق من التنسيق
على سبيل المثال، الأحرف الثلاثة CSV لا تكفي.
فقط حين تكتب شيئًا مثل UTF-8 with BOM، CRLF، فاصل comma، مع header تتوقّف المحادثة عن الانحراف.
7.4 كن صريحًا عند حدود القراءة / الكتابة
على جانب الكود أيضًا، الأكثر أمانًا ألّا تعتمد على الإعدادات الافتراضيّة الخفيّة.
- حدّد الترميز عند قراءات وكتابات الملفّات
- ابقَ منتبهًا للترميز عند تمرير النصّ عبر حدود العمليّات
- ثبّت نهايات السطور كجزء من المواصفة في مسارات التصدير / الاستيراد
- لا تجعل إعادات توجيه shell الارتجاليّة جزءًا من المسار الإنتاجيّ الفعليّ
خصوصًا في Windows، حُفظ بنجاح و حُفظت البايتات الصحيحة ليستا العبارة نفسها.
7.5 شارك قواعد Git والمحرّر أيضًا
لا يصلح Git الترميز لك تلقائيًّا.
في الوقت نفسه، قد يحوّل نهايات السطور.
لذا على مستوى المستودع، الأكثر أمانًا أن تقرّر:
- هل الكود المصدريّ افتراضيًّا
LF - هل النصوص الخاصّة بـ Windows فقط يمكنها استخدام
CRLF - كيف ينبغي أن يثبّت
.gitattributesالسلوك - كيف ينبغي مشاركة إعدادات المحرّر
النقطة المهمّة هي التفكير في الترميز ونهايات السطور بصورة منفصلة.
حتّى إن طبَّع Git نهايات السطور، تبقى حادثة الترميز حادثة ترميز.
7.6 لا تتوقّف عند قول “صار mojibake”؛ قُل ما الذي انحرف
في الفرق الواقعيّة، هذه إعادات الصياغة فعّالة بشكل مفاجئ:
- صياغة سيّئة:
صار mojibake - صياغة أفضل:
يبدو أنّ ملفّ UTF-8 no BOM يُفتح تحت افتراض CP932 - صياغة سيّئة:
نهايات السطور غريبة - صياغة أفضل:
يُحوَّل ملفّ LF إلى CRLF، ممّا يزيد الـ diffs
بمجرّد أن تستطيع قول ما الذي انحرف فعلًا، تتغيّر سرعة التحقيق كثيرًا.
8. التحقيق في mojibake وفروق نهايات السطور بهذه الأسئلة الخمسة
عندما يتعثّر التحقيق، أسرع مسار هو العودة إلى هذه الأسئلة الخمسة:
- ما البايتات في هذا الملفّ الآن؟
- هل هو UTF-8؟
- UTF-8 with BOM؟
- CP932؟
- UTF-16LE؟
- من كتبه أوّلًا، وتحت أيّ افتراض؟
- محرّر
- تطبيق تراثيّ
- تصدير من Excel
- shell / script
- دفعة / middleware
- من يقرأه الآن، وتحت أيّ افتراض؟
- الكشف التلقائيّ في المحرّر
- code page الـ console
- الترميز الافتراضيّ للمكتبة
- مواصفة جانب الاستيراد
- ماذا عن BOM ونهايات السطور؟
- BOM موجود أم غائب
CRLFأمLF
- هل المحتوى المُساء قراءته قد حُفظ بالفعل؟
- هل المسألة لا تزال مجرّد عرض؟
- أم أنّ البايتات قد أُعيدت كتابتها بالفعل وفُقدت معلومات؟
بمجرّد الإجابة على هذه الخمسة، يصبح السبب عادةً مرئيًّا.
9. الخلاصة
تبدو ترميزات النصّ ونهايات السطور في Windows فوضويّة لا لأنّ اليابانيّة في ذاتها صعبة، بل لأنّ البايتات والترميزات و BOM واصطلاحات السطر الجديد والإعدادات الافتراضيّة للأدوات توجد كطبقات منفصلة بينما لا تزال اصطلاحات النصّ القديمة والجديدة متعايشة في Windows.
النقاط المهمّة بشكل خاصّ التي ينبغي تذكّرها هي هذه:
- mojibake نتيجة قراءة نفس البايتات تحت ترميز مختلف
- قضايا السطر الجديد على محور مختلف عن الترميز
- لا تثق بكلمات مثل
Shift_JISوCP932وANSIوUnicodeبسهولة - قول
لقد تحوّلنا إلى UTF-8فقط لا يكفي؛ BOM ونهايات السطور تهمّ أيضًا - العرض المكسور وتلف البيانات المُعاد حفظها بالفعل يجب معاملتهما بصورة منفصلة
- في المواصفات، اكتب
UTF-8 no BOM، LFبدلًا من مجرّدtext
بعبارة أخرى، عند التعامل مع النصّ في Windows، الطريقة العمليّة للتفكير ليست هذه مشكلة سلسلة محارف، بل كيف نوائم العقد حول البايتات؟
10. مقالات ذات صلة
- فهم ترميزات النصّ في Windows - لماذا يحدث mojibake وما الذي ينكسر حين يدخل Linux
- أفضل الممارسات لتقليل حوادث Codex mojibake على Windows - حدِّد “كيف توجِّهه” قبل تعديل البيئة
11. المراجع
- Microsoft Learn، Code Page Identifiers - Win32 apps
https://learn.microsoft.com/en-us/windows/win32/intl/code-page-identifiers - Microsoft Learn، about_Character_Encoding - PowerShell
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_character_encoding?view=powershell-7.6 - Microsoft Learn، Understanding file encoding in VS Code and PowerShell
https://learn.microsoft.com/en-us/powershell/scripting/dev-cross-plat/vscode/understanding-file-encoding?view=powershell-7.6 - W3C Internationalization، Character encodings: Essential concepts
https://www.w3.org/International/articles/definitions-characters/ - Git documentation، gitattributes
https://git-scm.com/docs/gitattributes - Git documentation، git-config
https://git-scm.com/docs/git-config
مقالات ذات صلة
أحدث المقالات التي تشترك في نفس الوسوم. عمّق فهمك بمواضيع مرتبطة.
فهم ترميزات النصّ على Windows - لماذا يحدث mojibake وما الذي ينكسر عند دخول Linux إلى المعادلة
يشرح المقال لماذا يحدث mojibake على Windows عند تبادل الملفّات مع Linux، ويوضّح طبقات الترميز المنفصلة (CP932، UTF-8، PowerShell) لتشخيصه...
أفضل الممارسات لتجنّب mojibake مع Codex على Windows - prompting واضح قبل ضبط البيئة
كيف تستخدم Codex بأمان مع ملفّات نصّيّة يابانيّة على Windows عبر قواعد prompting صريحة لقراءة وكتابة وفحص encoding وBOM ونهايات الأسطر.
دليل المراجعة الشاملة لـ VBA و Excel macro والأدوات الداخليّة استعدادًا لإيقاف VBScript - الجرد / الكشف الساكن / سجلّات التشغيل / اختيار البديل / الاختبار / النشر التدريجيّ
ملخّص عمليّ على صفحة واحدة لمسار الاستعداد لإيقاف VBScript تدريجيًّا: جرد VBA و Excel macro والأدوات الداخليّة، الكشف الساكن، تجميع سجلّا...
كيف نُطيل عمر أنظمة الويب الداخليّة المعتمدة على IE mode وكيف نخرج منها - تنظيم الاستراتيجيّات الميدانيّة من الإدارة المركزيّة لقائمة المواقع، إلى WebView2، والإعادة الهيكليّة التدريجيّة، ووصولًا إلى عزل VDI
نتناول استراتيجيّةً عمليّةً لإطالة عمر أنظمة الويب الداخليّة المعتمدة على IE mode والخروج منها تدريجيًّا عبر إدارة قائمة المواقع وتغليف W...
ما يجب التحقّق منه عندما لا يعمل ActiveX على Office 2024 / Microsoft 365 - الترتيب العمليّ لتغطية التعطيل الافتراضيّ، 32bit / 64bit، تسجيل COM، DLL التابعة، ووصولًا إلى IE mode
دليل عمليّ لتشخيص توقّف ActiveX على Office 2024 و Microsoft 365، يرتّب الفحوص من التعطيل الافتراضيّ إلى تطابق 32bit / 64bit وتسجيل COM وD...
أين يتصل هذا الموضوع
ترتبط هذه المقالة بشكل طبيعي بصفحات الخدمات التالية.
تطوير تطبيقات ويندوز
ندعم تطوير برامج ويندوز للأعمال، وتكامل الأجهزة، وأدوات التواصل.
الملف الشخصي للمؤلف
صفحة الملف الشخصي لمؤلف المقالة.
غو كومورا
مؤسّس شركة كومورا سوفت ذ.م.م.
يركّز على تطوير برامج ويندوز، والاستشارات التقنية، والتحقيق في الأخطاء، ويتميّز في المشاريع التي تبقى فيها الأصول القديمة ناشطة، وفي تشخيص الأعطال التي يصعب تحديد سببها.
روابط عامة