用MultiByteToWideChar将文件编码从UTF8转为UTF16

·

bool utf8_to_utf16(const char *fpath)
{
    bool ret = false;
    HANDLE fileHandle;
    DWORD fileSize;
    PCHAR fileBuffer = nullptr;
    char16_t* utf16Buffer = nullptr;
    DWORD numberOfBytesRead;
    DWORD numberOfBytesWritten;
    fileHandle = ::CreateFileA(fpath,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
    if (fileHandle == INVALID_HANDLE_VALUE)
        return false;
    do
    {
        fileSize = ::GetFileSize(fileHandle,NULL);
        if (fileSize == 0)
            break;
        fileBuffer = new (std::nothrow) CHAR[fileSize];
        if (fileBuffer == nullptr)
            break;
        if (::ReadFile(fileHandle,fileBuffer,fileSize,&numberOfBytesRead,NULL) == FALSE)
            break;
        int result = ::MultiByteToWideChar(
          CP_UTF8,       // Source string is in UTF-8
          MB_PRECOMPOSED | MB_ERR_INVALID_CHARS,        // Conversion flags
          fileBuffer,   // Source UTF-8 string pointer
          fileSize,    // Length of source UTF-8 string, in chars
          NULL,     // Pointer to destination buffer
          0    // Size of destination buffer, in wchar_ts
        );
        if (result == 0)
            break;
        utf16Buffer = new (std::nothrow) char16_t[result];
        if (utf16Buffer == nullptr)
            break;
        result = ::MultiByteToWideChar(
          CP_UTF8,       // Source string is in UTF-8
          MB_PRECOMPOSED | MB_ERR_INVALID_CHARS,        // Conversion flags
          fileBuffer,   // Source UTF-8 string pointer
          fileSize,    // Length of source UTF-8 string, in chars
          (LPWSTR)utf16Buffer,     // Pointer to destination buffer
          result    // Size of destination buffer, in wchar_ts
        );
        if (result == 0)
            break;
        if (::SetFilePointer(fileHandle,0,NULL,FILE_BEGIN) == FALSE)
            break;
        if (::WriteFile(fileHandle,"\xFF\xFE",2,&numberOfBytesWritten,NULL) == FALSE || numberOfBytesWritten !=2 )
            break;
        if (::WriteFile(fileHandle,utf16Buffer,result * sizeof(char16_t),&numberOfBytesWritten,NULL) == FALSE || numberOfBytesWritten != result * sizeof(char16_t))
            break;
        if (::SetEndOfFile(fileHandle) == FALSE)
            break;
        ret = true;
    }while(0);
    if (utf16Buffer)
        delete utf16Buffer;
    if (fileBuffer)
        delete fileBuffer;
    ::CloseHandle(fileHandle);
    return ret;
}

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注