Diversas questões sobre a codificação de caracteres do sistema de arquivos no linux

12

Devido a muita troca de arquivos, o Windows ( GBK é codificado) e o Linux ( codificação UTF-8 , encontrará problemas de codificação de caracteres facilmente, como:

  • arquivos zip / tar cujo nome contém caracteres chineses no sistema Windows, descompacte / untar no sistema Linux.
  • execute o aplicativo da web java legado migrado (projetado no sistema Windows, usando a codificação GBK no JSP) que grava arquivos nomeados por codificação GBK no disco.
  • ftp obtém / coloca arquivos nomeados por codificação GBK entre o servidor FTP do Windows e o cliente Linux.
  • muda o ambiente LANG no Linux.

O problema comum do anterior mencionado é a localização / nomeação de arquivos. Depois de googled, eu tenho um artigo Usando o Unicode no Linux link , dizia:

the operating system and many utilities do not realize what characters the bytes in file names represent.

Assim, é possível ter arquivos de 2 中文 .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
中文
中文

Perguntas:

  1. É possível configurar o sistema de arquivos linux usando codificação de caracteres fixos (como NTFS use UTF-16 internamente) para armazenar o arquivo nomes independentemente do ambiente LANG / LC_ALL?
  2. Ou, o que eu realmente quero perguntar é: É possível deixar 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 refere-se ao mesmo arquivo ?
  3. Se não for configurável, será 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 uma implementação de solicitação)? e quanto desempenho tem efeito se for possível?
por LiuYan 刘研 22.06.2011 / 12:09

2 respostas

8

Eu reformulei suas perguntas um pouco, por razões que deveriam aparecem evidentes quando você as lê em sequência.

1. É possível configurar o sistema de arquivos linux usando codificação de caracteres fixos 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 arquivo UNIX nome é apenas uma seqüência de bytes; o kernel não sabe nada sobre a codificação, que é totalmente um espaço do usuário (ou seja, no nível do aplicativo) conceito.

Em outras palavras, o kernel não sabe nada sobre LANG / LC_* , então ele não pode traduzir.

2. É possível permitir que diferentes nomes de arquivos se refiram ao mesmo arquivo?

Você pode ter várias entradas de diretório referentes ao mesmo arquivo; você pode fazer isso através de links físicos ou links simbólicos .

Saiba, entretanto, que os nomes de arquivos que não são válidos no codificação atual (por exemplo, sua cadeia de caracteres GBK quando você está trabalhando em uma localidade UTF-8) será exibido incorretamente, se houver.

3. É possível corrigir o kernel para traduzir a codificação de caracteres entre o sistema de arquivos e o ambiente atual?

Você não pode corrigir o kernel para fazer isso (veja 1.), mas você pode Teoria-patch da biblioteca C (por exemplo, glibc) para executar esta tradução, e sempre converter nomes de arquivos para UTF-8 quando ele chama o kernel, e convertê-los de volta para a codificação atual quando lê um nome de arquivo do kernel.

Uma abordagem mais simples poderia ser escrever um sistema de arquivos de sobreposição com FUSE , que apenas redireciona qualquer solicitação do sistema de arquivos para outro local após convertendo o nome do arquivo para / de UTF-8. Idealmente, você poderia montar este sistema de arquivos em ~/trans , e quando um acesso é feito para ~/trans/a/GBK/encoded/path então o sistema de arquivos FUSE realmente acessa %código%.

No entanto, o problema com essas abordagens é: o que você faz com arquivos que já existem no seu sistema de arquivos e não são codificados em UTF-8? Você não pode simplesmente passar-lhes não traduzido, porque então você não saber convertê-los; você não pode mangle-los, traduzindo seqüências de caracteres inválidos para /a/UTF-8/encoded/path porque isso poderia criar conflitos ...

    
por 22.06.2011 / 14:03
1

O que você pode fazer é limitar a quantidade de localidades suportadas a apenas localidades UTF-8.

link

    
por 22.06.2011 / 14:07