Devido a muitas trocas de arquivos entre o Windows ( codificação GBK ) e o Linux ( codificação UTF-8 ), ele encontrará facilmente problemas de codificação de caracteres, como:
- arquivos zip / tar cujo nome contenha caracteres chineses no sistema Windows, descompacte / descompacte-o no sistema Linux.
- execute o aplicativo da web java herdado migrado (projetado no sistema Windows, usando a codificação GBK no JSP) que grava arquivos nomeados pela codificação GBK no disco.
- O ftp obtém / coloca arquivos com o nome de codificação GBK entre o servidor FTP do Windows e o cliente Linux.
- alternar o ambiente LANG no Linux.
O problema comum do mencionado anteriormente é a localização / nomeação de arquivos. Após pesquisar no Google, recebi um artigo Usando o Unicode no Linux http://www.linux.com/archive/feed/39912 , que dizia:
o sistema operacional e muitos utilitários não percebem quais caracteres os bytes nos nomes de arquivo representam.
Portanto, é possível ter 2 arquivos .txt com codificação diferente:
[root@fedora test]# ls
???? 中文
[root@fedora test]# ls | iconv -f GBK
中文
涓iconv: illegal input sequence at position 7
[root@fedora test]# ls 中文 && ls $'\xd6\xd0\xce\xc4'|iconv -f gbk
中文
中文
Questões:
- É possível configurar o sistema de arquivos linux usando codificação de caracteres fixa (como o NTFS usa UTF-16 internamente) para armazenar nomes de arquivos, independentemente do ambiente LANG / LC_ALL?
- Ou o que realmente quero perguntar é: É possível permitir que o nome do arquivo 中文 .txt (
$'\xe4\xb8\xad\xe6\x96\x87.txt'
) no ambiente zh_CN.UTF-8 e o nome do arquivo 中文 .txt ($'\xd6\xd0\xce\xc4.txt'
) no ambiente zh_CN.GBK se refiram ao mesmo arquivo ? - Se não for configurável, é possível corrigir o kernel para converter a codificação de caracteres entre o sistema de arquivos e o ambiente atual (apenas uma pergunta, não solicitar implementação)? e quanto desempenho afeta, se possível?
linux
filesystems
filenames
character-encoding
LiuYan 刘 研
fonte
fonte
Respostas:
Eu reformulei suas perguntas um pouco, por razões que devem aparecer evidentes quando você as lê em sequência.
1. É possível configurar o sistema de arquivos linux usando codificação de caracteres fixa para armazenar nomes de arquivos, independentemente do ambiente LANG / LC_ALL?
Não, isso não é possível: como você mencionou na sua pergunta, um nome de arquivo UNIX é apenas uma sequência de bytes; o kernel não sabe nada sobre a codificação, que é inteiramente um conceito de espaço do usuário (ou seja, no nível do aplicativo).
Em outras palavras, o kernel não sabe nada sobre
LANG
/LC_*
, portanto não pode traduzir.2. É possível permitir que nomes de arquivos diferentes se refiram ao mesmo arquivo?
Você pode ter várias entradas de diretório referentes ao mesmo arquivo; você pode fazer isso por meio de links físicos ou simbólicos .
Esteja ciente, no entanto, de que os nomes de arquivo que não são válidos na codificação atual (por exemplo, sua cadeia de caracteres GBK quando você está trabalhando em um código de idioma UTF-8) serão exibidos incorretamente, se houver.
3. É possível corrigir o kernel para converter a codificação de caracteres entre o sistema de arquivos e o ambiente atual?
Você não pode corrigir o kernel para fazer isso (consulte 1.), mas poderia, em teoria, corrigir a biblioteca C (por exemplo, glibc) para executar esta tradução e sempre converter nomes de arquivos em UTF-8 quando ele chama o kernel, e converta-os novamente para a codificação atual quando ler um nome de arquivo do kernel.
Uma abordagem mais simples poderia ser escrever um sistema de arquivos de sobreposição com o FUSE , que apenas redireciona qualquer solicitação do sistema de arquivos para outro local depois de converter o nome do arquivo para / de UTF-8. Idealmente, você pode montar esse sistema de arquivos
~/trans
e, quando um acesso é feito~/trans/a/GBK/encoded/path
, o sistema de arquivos FUSE realmente acessa/a/UTF-8/encoded/path
.No entanto, o problema com essas abordagens é: o que você faz com os arquivos que já existem no seu sistema de arquivos e não são codificados em UTF-8? Você não pode simplesmente passá-los sem tradução, porque então você não sabe como convertê-los; você não pode modificá-los traduzindo seqüências de caracteres inválidas,
?
pois isso pode criar conflitos ...fonte
O que você pode fazer é limitar a quantidade de códigos de idioma suportados a apenas códigos de idioma UTF-8.
http://www.fifi.org/cgi-bin/man2html/usr/share/man/man5/locale.gen.5
fonte