CStdioFile 派生类,用于多字节和 Unicode 的读写






4.91/5 (63投票s)
一个从 CStdioFile 派生的类,可以透明地读取和写入 Unicode 和多字节文件。版本 1.5。
引言
这是一个从 CStdioFile
派生的类,它透明地处理 Unicode 文本文件以及普通多字节文本文件的读取和写入。
该代码可以编译为多字节和 Unicode。在 Unicode 中,多字节文件将被读取,其内容将使用当前代码页转换为 Unicode。在多字节编译中,Unicode 文件将被读取并转换为多字节文本。
Unicode 文本文件的识别完全取决于 Unicode 字节顺序标记 (0xFEFF) 的存在。它的缺失并不能绝对保证文件不是 Unicode,但这是我在这里使用的唯一方法。欢迎提出改进建议。
默认情况下,该类写入多字节文件,但可以选择写入 Unicode。
背景
能够透明地处理多字节和 Unicode 似乎是一个基本要求,我确信已经有类似的东西了,但什么也没找到。我错过了什么吗?
我需要在编写的翻译工具中使用它,并拼凑了一个足够满足我需求的实现。这只是一个清理过的版本,所以请期待错误和各种缺陷。我已经用基本组合测试了演示应用程序 -- 多字节编译中的 Unicode 文件、Unicode-Unicode、多字节-Unicode 和多字节-多字节,它们似乎都能工作。
使用代码
该类的使用非常简单。它覆盖了 CStdioFile
的三个函数:Open()
、ReadString()
和 WriteString()
。要写入 Unicode 文件,请在调用 Open()
函数时将标志 CStdioFileEx::modeWriteUnicode
添加到标志中。
在其他方面,用法与 CStdioFile
相同。
要了解您打开的文件是否是 Unicode,您可以调用 IsFileUnicodeText()
。
要获取文件中的字符数,您可以调用 GetCharCount()
。但对于多字节/UTF-8,这是不可靠的。
写入 Unicode 的示例
// Test writing
CStdioFileEx fileWriteUnicode;
if (fileWriteUnicode.Open(_T("c:\\testwrite_unicode.txt"),
CFile::modeCreate | CFile::modeWrite | CStdioFileEx::modeWriteUnicode))
{
fileWriteUnicode.WriteString(_T("Unicode test file\n"));
fileWriteUnicode.WriteString(_T("Writing data\n"));
fileWriteUnicode.Close();
}
现在您还可以指定多字节文件读取或写入的代码页。只需在读取之前调用 SetCodePage()
来告诉 CStdioFileEx
文件以哪种代码页编码,或在写入之前调用来告诉它您希望以哪种代码页写入。将 CP_UTF8
指定为代码页允许您读取或写入 UTF-8 文件。
演示应用程序是一个对话框,它打开一个文件,告诉您它是否是 Unicode,以及它包含多少个字符,并显示前十五行。在最近的几次迭代中,我添加了将 Unicode 文件转换为多字节文件,以及将多字节文件转换为 Unicode 的选项,以及一个用于在读取时指定代码页的组合框。
从 v1.6 开始,对可以在任何模式(多字节/Unicode,Unicode/多字节等)中读取的行长度没有限制。
我很乐意听取人们的经验,以及关于错误、问题、改进等的报告。
哦,如果我不小心在演示对话框中包含了一些冒犯性的东西,请告诉我。我的阿拉伯语和中文不太好。
历史
- v1.0 - 发布于 2003 年 5 月 14 日
- v1.1 - 2003 年 8 月 23 日。合并了 Dennis Jeryd 的修复
- v1.2 - 2005 年 1 月 6 日。修复了文件末尾的垃圾错误 (Howard J Oh)
- v1.3 - 2005 年 2 月 19 日。Howard J Oh 的修复程序莫名其妙地未能进入上一个版本。改进了测试程序。修复了其他错误
非常重要:在此版本中,以 ANSI 写入的 ANSI 文件不再使用WriteString
写入。这意味着\n
将不再被“解释”为\r\n
。你写的是你得到的 - v1.4 - 2005 年 2 月 26 日。修复了提交错误
- v1.5 - 2005 年 11 月 18 日。可以为读取和写入指定代码页(包括 UTF-8)。正确计算多字节缓冲区。来自 Andy Goodwin 的修复
- v1.6 - 2007 年 7 月 19 日。重大重写:删除了最大行长度限制;消除了
strlen
/lstrlen
的使用。始终使用转换函数来计算所需的缓冲区;不再丢失\r
或\n
字符;BOM 写入现在是可选的;UTF-8 读取和写入工作正常;现在演示项目中包含系统测试