65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.86/5 (17投票s)

2005 年 2 月 10 日

CPOL

2分钟阅读

viewsIcon

555712

downloadIcon

1590

一个从 CStdioFile 派生的 UTF-16 类,用于读写 Unicode 文件。

引言

随着 Unicode 变得越来越流行,程序员会发现自己在使用 Unicode 执行更多基于文件的操作。目前,熟悉的 MFC 类,如 CFileCStdioFile,并不能正确处理 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_bIsUnicodeFALSE,该类将返回相应的 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。如果 bAsUnicodeTRUE,程序将写入 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 字节在磁盘上被交换。

图 1:测试程序的结果。

图 2 检查了使用 Windows 2000 上的记事本创建的类似文件,同时将文件另存为 Unicode。

图 2:在记事本中创建的 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 输出文件。
© . All rights reserved.