Que codificação são nomes de arquivos em NTFS armazenados como?

Eu estou apenas começando em alguma programação para lidar com nomes de arquivos com nomes não ingleses em um sistema WinXP. Eu fiz algumas leituras recomendadas no unicode e acho que tenho a idéia básica, mas algumas partes ainda não estão muito claras para mim.

Especificamente, que codificação (UTF-8, UTF-16LE / BE) são os nomes de arquivos (não o conteúdo, mas o nome real do arquivo) armazenados no NTFS? É possível abrir qualquer arquivo usando fopen (), o que leva um char *, ou não tenho outra escolha senão usar wfopen (), que usa um wchar_t *, e presumivelmente usa uma string UTF-16?

Eu tentei manualmente alimentando em uma string codificada UTF-8 para fopen (), por exemplo.

unsigned char filename[] = {0xEA, 0xB0, 0x80, 0x2E, 0x74, 0x78, 0x74, 0x0}; // 가.txt FILE* f = fopen((char*)filename, "wb+"); 

mas isso saiu como “ê ° € .txt”.

Fiquei com a impressão (que pode estar errada) de que uma string codificada em UTF8 seria suficiente para abrir qualquer nome de arquivo no Windows, porque pareço lembrar vagamente algum aplicativo do Windows que passa por aí (char *), não (wchar_t *) e sem problemas.

Alguém pode lançar alguma luz sobre isso?

O NTFS armazena nomes de arquivos em UTF16, no entanto, fopen está usando ANSI (não utf8).

Para usar um nome de arquivo codificado em UTF16, você precisará usar as versões Unicode das chamadas em aberto. Faça isso definindo UNICODE e _UNICODE no seu projeto. Em seguida, use a chamada CreateFile ou a chamada wfopen.

fopen () – no MSVC no windows não (por padrão) pega um char codificado utf-8 *.

Infelizmente, o utf-8 foi inventado recentemente no grande esquema das coisas. As APIs do Windows são divididas em versões Unicode e Ansi. cada API do Windows que recebe ou trata strings está realmente disponível com um sufixo W ou A – W para caractere “Wide” / Unicode e A para Ansi. A magia de macro oculta tudo isso do desenvolvedor, portanto, basta chamar CreateFile com um char * ou um wchar_t *, dependendo de sua configuração de compilation, sem saber a diferença.

A codificação ‘Ansi’ não é realmente uma codificação específica: – Mas significa que a codificação usada para strings “char” é específica da configuração de localidade do PC.

Agora, porque as funções do c-runtime – como o fopen – precisam funcionar por padrão sem o conhecimento do desenvolvedor – nos sistemas Windows, elas esperam receber suas strings na codificação local do windows. msdn indica que o microsoft c-runtime api setlocal pode alterar o código do idioma do thread atual – mas especificamente diz que ele falhará em qualquer local que precise de mais de 2 bytes por caractere – como utf-8.

Portanto, no Windows não há atalho. Você precisa usar wfopen, ou a API nativa CreateFileW (ou criar seu projeto usando as configurações de compilation Unicode e apenas chamar Createfile) com strings wchar_t *.

Como foi respondido por outros, a melhor maneira de manipular strings codificadas em UTF-8 é convertê-las em Unicode e usar APIs Unicode nativas, como _wfopen ou CreateFileW .

No entanto, essa abordagem não ajudará ao chamar bibliotecas que usam fopen() incondicionalmente, porque elas não suportam Unicode ou porque são escritas em C portátil. Nesse caso, ainda é possível fazer uso dos “caminhos curtos” herdados. para converter uma string codificada em UTF-8 em um formato ASCII utilizável com fopen , mas isso requer algum trabalho de campo:

  1. Converta a representação UTF-8 em UTF-16 usando MultiByteToWideChar .

  2. Use GetShortPathNameW para obter um “caminho curto”, que é apenas para ASCII. GetShortPathNameW irá retorná-lo como uma string larga com conteúdo all-ASCII, que você precisará converter trivialmente para uma string estreita por uma cópia sem perda, lançando cada char wchar_t .

  3. Passe o caminho curto para fopen() ou para o código que eventualmente usará fopen() . Esteja ciente de que as mensagens de erro impressas por esse código, se houver, farão referência ao “caminho curto” inestético (por exemplo, KINTO~1 vez de kinto-un-筋斗雲 ).

Embora essa não seja exatamente uma estratégia recomendada de longo prazo, como os caminhos abreviados do Windows são um recurso herdado que pode ser desativado por volume, é provável que a única maneira de passar nomes de arquivos ao código que use fopen() e outros arquivos chamadas de API relacionadas ( stat , access , versões ANSI de CreateFile e similares).