PDA

View Full Version : تشخیص ASCII یا Unicode بودن فایل



ICEMAN
یک شنبه 26 اسفند 1386, 15:07 عصر
سلام ...
چطور میشه تشخیص داد که یه فایل Unicode هست یا ASCII !

به جای توابع seek و tell که جزو توابع Standard در C هست ،توی Api های ویندوز چی داریم !
تشکر

BitMap
یک شنبه 26 اسفند 1386, 17:55 عصر
معمولا در ابتدای فایل های غیر ascii ، اگر اشتباه نکنم ، سه بایت وجود دارد که تعیین کننده ی نوع فایل هستند و بعد از اون سه بایت محتویات اصلی فایل قرار داره.اون سه بایت نمایش داده نمیشه

Nima_NF
دوشنبه 27 اسفند 1386, 00:25 صبح
از طریق خواندن فایل و سپس تست آن با تابع IsTextUnicode می توانید بفهمید که آیا Byte order mark یونیکد بودن را دارد یا خیر.

ضمنا در صورتی که می خواهید خودتان فایل یونیکد را بسازید یکی از این علائم باید در فایل وجود داشته باشد که می توانید لیست آن ها را در این صفحه مشاهده کنید:
http://msdn2.microsoft.com/en-us/library/ms776429(VS.85).aspx (http://msdn2.microsoft.com/en-us/library/ms776429%28VS.85%29.aspx)

ICEMAN
دوشنبه 27 اسفند 1386, 08:20 صبح
سلام ...
به جای توابع seek و tell که جزو توابع Standard در C هست ،توی Api های ویندوز چی داریم !
تشکر

.............

Nima_NF
دوشنبه 27 اسفند 1386, 15:32 عصر
SetFilePointer و نسخه EX آن

برای اطلاعات بیشتر به بخش File Management در MSDN مراجعه کنید.

BitMap
سه شنبه 28 اسفند 1386, 07:12 صبح
این یک کلاس هست که من چند وقت پیش نوشتم:



typedef wchar_t* String;
typedef wchar_t Char;

class CMyFileFile
{
enum EFileType {
ASCII,
UTF8,
UTF16_LITTLE_ENDIAN,
UTF16_BIG_ENDIAN,
UTF32_LITTLE_ENDIAN,
UTF32_BIG_ENDIAN
};

EFileType m_Type;
FILE *m_File;

public:
CMyFileFile()
{
}

~CMyFileFile()
{
}

ILRESULT Open( String FileName , bool ForRead)
{
if( ForRead )
{
m_Type = this->IdentifyType( FileName );

m_File = _wfopen( FileName, L"r" );

Jump();
}
else
m_File = _wfopen( FileName, L"w" );

if( !m_File )
return 0;

return 1;
}

ILRESULT Close()
{
if( m_File )
{
fclose(m_File);
return 1;
}

return 0;
}

ILRESULT Jump()
{
switch( m_Type )
{
case ASCII: // 0
break;
case UTF8: // 3
fseek( m_File, 3*sizeof(unsigned char), SEEK_SET);
break;
case UTF16_LITTLE_ENDIAN: // 2
case UTF16_BIG_ENDIAN: // 2
fseek( m_File, 2*sizeof(unsigned char), SEEK_SET);
break;
case UTF32_LITTLE_ENDIAN: // 4
case UTF32_BIG_ENDIAN: // 4
fseek( m_File, 4*sizeof(unsigned char), SEEK_SET);
break;
}

return 1;
}

ILRESULT ReadChar( Char *ch )
{
if( m_Type == ASCII )
*ch = (char)fgetc( m_File );
else
*ch = fgetwc( m_File );

return 1;
}

ILRESULT WriteChar( const Char ch )
{
return fputwc(ch, m_File );
}


static EFileType IdentifyType( String FileName)
{
unsigned char bom[4]={0};
FILE *pf = _wfopen( FileName, L"rb" );
fread( bom, 4*sizeof(unsigned char), 1, pf);
fclose( pf );

if( bom[0]== 0xEF && bom[1]==0xBB && bom[2]==0xBF ) // UTF-8
return UTF8;
else if( bom[0]== 0xFF && bom[1]==0xFE && bom[2]==0x00 && bom[3]==0x00 ) // UTF-32, little endian
return UTF32_LITTLE_ENDIAN;
else if( bom[0]== 0x00 && bom[1]==0x00 && bom[2]==0xFE && bom[3]==0xFF ) // UTF-32, big-endian
return UTF32_BIG_ENDIAN;
else if( bom[0]== 0xFF && bom[1]==0xFE ) // UTF-16, little endian
return UTF16_LITTLE_ENDIAN;
else if( bom[0]== 0xFE && bom[1]==0xFF ) // UTF-16, big endian
return UTF16_BIG_ENDIAN;
else
return ASCII;

}
};

amir_saniyan
یک شنبه 04 فروردین 1387, 14:10 عصر
سلام
یک چیز جالب تو ویندوز ایکس پی:
Notepad رو باز کنید و توش یک j تایپ کنید و سپس یک فاصله هم تایپ کنید. بعد اون رو در قالب ANSI ذخیره کنید(در واقع به شکل عادی) . حالا یک فایل دارید که دو بایته و حاوی رشته «j » است. حالا Notepad رو ببندید و با دو بار کلیک کردن پرونده ذخیره شده را باز کنید. دیگه j رو نمایش نمی‌ده چون اگه اشتباه نکنم دو بایت اول رو به عنوان نشانه‌های فایل جور دیگه‌ای تفسیر کرده. البته این مشکل تو ویندوز ویستا حل شده.
موفق باشید.