为什么GetPrivateProfileSection会将每个字符检索为两个字节的值,并用NULL字符填充它们?

问题描述

给出这段代码

Private Declare Auto Function GetPrivateProfileSection Lib "kernel32" _
        (ByVal lpAppName As String,_
         ByVal lpszReturnBuffer As Byte(),_
         ByVal nSize As Integer,ByVal lpFileName As String) As Integer

Public Class IniClassReader
    Public Function readWholeSection(iniFile as String,section as String) as String()
        Dim buffer As Byte() = New Byte(SECTIONLENGTH) {}
        GetPrivateProfileSection(section,buffer,SECTIONLENGTH,iniFile)
        Dim sectionContent As String = Encoding.Default.GetString(buffer)
        ' Skipped code embedded in the function below,not the point of the question
        return processSectionContent(sectionContent)
    End Function
End Class

我发现buffer包含一个NULL个字符(\0)散布的字节序列。因此,间谍变量功能sectionContent的值视为'e n t r i e 1 = v a l u e 1 e n t r i e 2 = v a l u e 2'。每对键/值均符合预期,后跟两个NULL个字符,而不是一个

我不明白为什么每个字符都存储为两个字节的值。 Default替换UTF8会得到相同的结果。我尝试使用以UTF8和Windows-1252(Microsoft称为“ ANSI”)编码的INI文件

我知道如何利用这些多余的字节:

Dim sectionContent As String = Encoding.Default.GetString(buffer)
sectionContent = sectionContent.Replace(Chr(0) & Chr(0),vbNewLine).Replace(Chr(0),"")

但是我想了解应用最佳解决方案所发生的情况,而不是仅在某些情况下会出现一些草率的黑客行为。

解决方法

字节是UTF-16编码的文本。看起来好像是空字符填充,因为您的所有文本均由其编码适合低字节的字符组成。

Windows API公开了该函数的“ A”和“ W”版本,其中“ A”版本使用窄字符串,而“ W”版本使用宽字符串。 Windows NT家族树的默认值(因此是XP之后的所有Windows)的宽度都很大,因为UCS-2 / UTF-16是Windows的“本机”字符编码。