‫قالب فایل CSV و یونیکد

CSV CSV یا همان Comma Seperated Values یک قالب فایل معروف و خیلی قدیمی (از حدود ۴۵ سال پیش!) است که در محیط‌ها و نرم افزارهای بسیار مختلفی مورد استفاده قرار می‌گیرد. در این قالب هر رکورد از اطلاعات در یک سطر فایل ذخیره می‌شود. و در هر سطر هم فیلدها به وسیله کاراکتر کاما «,» از هم جدا می‌شوند.

برای CSV هیچ استاندارد واحدی وجود ندارد. حتی RFC 4180 هم به صورت Informational ارائه شده است یعنی استاندارد واحدی را مشخص نکرده و صرفا قالبی که در بیشتر پیاده‌سازی‌ها مورد استفاده قرار گرفته را معرفی می‌کند. این یعنی اینکه CSV که از اکسل می‌گیرید لزوما با CSV که ممکن است از Gmail Contacts یا MySQL بگیرید یکی نخواهد بود. مثلا در یکی از header استفاده شده و در دیگری نه و یا مقدار فیلدها در یکی با double qution محصور شده و در دیگری نه. بدترین قسمت این ماجرا این است که در بیشتر پیاده سازی هیچ اهمیتی به Enocding داده نشده و فرض همه به ASCII بودن فایل است و بدتر از این از آنجا که به نظر می‌رسد CSV از Byte Order استفاده نمی‌کند (پاراگراف بعدی را ببینید) در نتیجه فایل آن حتما باید تک بایتی باشد مثل ASCII و UTF-8 و باز هم در نتیجه نمی‌توان از قالب‌های ۲ بایتی (یعنی هر کاراکتر در ۲ بایت ذخیره شود) مثل فایل‌های متنی یونیکد ویندوز در آن استفاده کرد. البته در حال تک بایتی هم Encoding را خود استفاده کننده باید بفهمد و نوع Encoding مورد استفاده از هیچ جای یک فایل CSV قابل استخراج نیست. در بعضی جاهای خاص مثل وقتی که قرار است فایل CSV به عنوان یک MIME TYPE به اسم text/csv رد و بدل شود یک header به نام charset هست که می‌توان Encoding را در آن معرفی نمود. فراموش نشود که این header خارج از خود فایل CSV قرار دارد.

در بعضی حالات به نظر می‌رسد که CSV از Byte Order استفاده می‌کند یعنی مثل فایل‌های متنی داخل ویندوز می‌شود یک یا چند بایت خاص را به منظور تعیین Encoding مورد استفاده در ابتدای فایل قرار داد و  سپس هر کاراکتر را با توجه به Encoding انتخابی ۱ یا ۲ بایت در نظر گرفت. البته در یکی دو آزمایش معلوم شد که خیلی برنامه‌ها از جمله Excel 2007 با فایل‌های متنی ۲ بایتی (ذخیره هر کاراکتر در ۲ بایت) مشکل دارند و این روش خیلی قابل اطمینان نیست.

نظر نگارنده این است که هر فایل CSV به صورت یک فایل متنی خالص تک بایتی بدون Byte Order ذخیره شده ولی برای ذخیره مقادیر یونیکد آنها را به قالب UTF-8 در آورده و در جای فیلدها ذخیره شود. برای خواندن این CSV هم همه فیلدها از UTF-8 به متن معمولی decode شود. به جای UTF-8 از هر روش دیگری هم که کاراکترهای یونیکد را به رشته‌ای از کاراکترهای تک بایت تبدیل می‌کنند هم می‌شود استفاده کرد. مثلا مثل این روش در صفحات HTML که کاراکتر «ن» فارسی با کد «#1606;» نمایش داده می‌شود. فقط باید دقت شود که استفاده کننده فایل CSV هم از روش Encoding مورد استفاده ما با خبر باشد.

 

منابع:

Comments

  1. Mir Hossein Hosseinioun

    سلام
    من یک مشکل دارم که شاید بتونید حل کنید برام.
    من می خوام از طریق ASP یک فایل CSV رو برای دانلود به کاربر بفرستم و از تنظیمات زیر استفاده کردم:
    Response.Clear();
    Response.ContentEncoding = System.Text.Encoding.UTF8;
    Response.ContentType = "application/vnd.ms-excel";
    Response.AddHeader("content-encoding", "utf-8");
    Response.AddHeader("Content-Disposition", "attachment;filename=file1.csv");
    buffer = System.Text.Encoding.UTF8.GetBytes(dates[i] + "," + data+"," + lname+ "," + System.Environment.NewLine);
    Response.BinaryWrite(buffer);
    در این تنظیمات مشکلی وجود داره که نمی تونم با excell محتوای فارسی رو ببینم ولی با notepad میشه؟
    ممنون

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *