用于读写 Unicode 文件的 UTF-16 类






4.86/5 (17投票s)
一个从 CStdioFile 派生的 UTF-16 类,用于读写 Unicode 文件。
引言
随着 Unicode 变得越来越流行,程序员会发现自己在使用 Unicode 执行更多基于文件的操作。目前,熟悉的 MFC 类,如 CFile
和 CStdioFile
,并不能正确处理 Unicode 文件的读写。所提供的类文件解决了将文件作为 UTF-16 Unicode 文件读写的需求。
Using the Code
在构造期间或使用 Open()
成员函数时,该类将在适当的大小检查后检查文件的前两个字节。这两个字节序列 (BOM) 0xFE
, 0xFF
表示该文件是 UTF-16 编码的。如果是这种情况,m_bIsUnicode
将被设置为 TRUE
。如果不存在这些字节,该类将执行 CStdioFile::Seek(0, CFile::begin )
以返回已使用的字节。
CStdioFile::Read( &wcBOM, sizeof( WCHAR ) );
if( wcBOM == UNICODE_BOM ) {
m_bIsUnicode = TRUE;
m_bByteSwapped = FALSE;
}
if( wcBOM == UNICODE_RBOM ) {
m_bIsUnicode = TRUE;
m_bByteSwapped = TRUE;
}
// Not a BOM mark - treat it as an ANSI file
// and defer to CStdioFile...
if( FALSE == m_bIsUnicode ) {
CStdioFile::Seek( 0, CFile::begin );
}
ReadString(...)
的执行方式如下:如果 m_bIsUnicode
为 FALSE
,该类将返回相应的 CStdioFile::ReadString(...)
操作。如果文件是 UTF-16 编码的,则该类将从一个内部累加器中提取,直到在使用 CUTF16File::ReadString(CString& rString )
时遇到 "\r"
或 "\n"
。如果使用 CUTF16File::ReadString( LPWSTR lpsz, UINT nMax )
重载,则会复制 CStdioFile::ReadString()
行为。参见来自 fgets()
的底层注释。
上述读取是通过一个累加器完成的。累加器是一个 WCHAR
的 STL 列表。当填充累加器时,如果遇到大端流 (0xFF
, 0xFE
),则会发生字节交换。
写入文件是通过使用 WriteString(LPCTSTR lpsz, BOOL bAsUnicode )
扩展正常函数完成的。CStdioFile
将在内部处理 ANSI 转换,因此 CUTF16File
仅屈服于 CStdioFile
。如果 bAsUnicode
为 TRUE
,程序将写入 BOM(如果文件位置为 0),然后调用 CFile::Write(...)
。
该程序将在硬盘上打开两个文件,写出 Unicode 和 ANSI 文本文件,然后将文件读回。然后,驱动程序使用 OutputDebugString(...)
将消息写入调试器的输出窗口。
CUTF16File output1( L"unicode_write.txt", CFile::modeWrite |
CFile::modeCreate );
output1.WriteString( L"Hello World from Unicode land!", TRUE );
output1.Close();
...
CString szInput;
CUTF16File input1( L"unicode_write.txt", CFile::modeRead );
input1.ReadString( szInput );
图 1 是使用提供的驱动程序编写测试文件的结果。请注意,BOM 字节在磁盘上被交换。
图 2 检查了使用 Windows 2000 上的记事本创建的类似文件,同时将文件另存为 Unicode。
其他阅读
- http://www.unicode.org/
- D. Schmitt 著《Microsoft Windows 国际编程》,ISBN 1-57231-956-9
- J. Prosise 著《使用 MFC 编程 Windows》,ISBN 1-57231-695-0
- J. Richter 和 J. Clark 著《为 Microsoft Windows 2000 编程服务器端应用程序》,ISBN 0-73560-753-2
修订
- 2005 年 2 月 10 日 原始发布
- 2006 年 12 月 23 日 添加了 Jordan Walters 的改进和错误修复
- 2006 年 12 月 23 日 添加了 Jordan Walters 作为作者
- 2008 年 9 月 17 日 修复了第二个构造函数中长期存在的错误
- 2009 年 7 月 13 日 正确处理 Unicode 字符。如果指定了 UNICODE/_UNICODE 项目设置,则写入 ANSI 仍然会生成 Unicode 输出文件。