É seguro converter caminhos de arquivos do Windows em caminhos de arquivos Unix com uma simples substituição?

12

Por exemplo, digamos que eu o possua para que todos os meus arquivos sejam transferidos de uma máquina Windows para uma máquina Unix como tal: C:\test\myFile.txtto {somewhere}/test/myFile.txt(letra da unidade é irrelevante neste momento).

Atualmente, nossa biblioteca de utilitários que escrevemos para nós mesmos fornece um método que substitui todas as barras invertidas por barras invertidas:

public String normalizePath(String path) {
   return path.replaceAll("\\", "/");
}

As barras são reservadas e não podem fazer parte de um nome de arquivo; portanto, a estrutura de diretórios deve ser preservada. No entanto, não tenho certeza se existem outras complicações entre os caminhos do Windows e do Unix que possam me preocupar (por exemplo: nomes não-ascii, etc.)

MxLDevs
fonte
4
Cuidado com os espaços - colocar espaços nos nomes de pastas do Windows é muito mais comum do que nos nomes de diretório unix. Em particular, "\ Arquivos de Programas" me atrai o tempo todo. Dependendo de como você estiver usando os caminhos, talvez você precise escapar de espaços com "\".
21614 Rob Rob
1
@ delnan para simplificar, vamos limitar o escopo dos caminhos para excluir caminhos variáveis.
MxLDevs
2
@MxyL O problema não desaparece quando você codifica o caminho em vez de usar uma variável de ambiente. Se você quer apenas um caminho que não exploda, deve ficar bem. Se você deseja um caminho significativo ou se deseja interagir com outro software (ou expectativas do usuário ...), precisa de chamadas de julgamento por caminho.
1
@ delnan Estou focado principalmente na produção de um caminho válido, mas esse é um bom ponto. Os caminhos que estou convertendo devem ser simples o suficiente para serem significativos por si mesmos.
MxLDevs
3
As barras invertidas são permitidas nos nomes de arquivos no Linux, portanto, a substituição de barras invertidas em um caminho do Linux pode adicionar diretórios inválidos. Por exemplo, /foo\\barnão é equivalente /foo/barno Linux.

Respostas:

7

Sim, se você fizer a substituição apenas no Windows e desligá-lo ao executar em outros sistemas.

A substituição em sistemas do tipo Unix está incorreta porque \é um caractere válido em um nome de arquivo ou diretório em plataformas do tipo Unix. Nessas plataformas, apenas NULe /são proibidos nos nomes de arquivos e diretórios.

Além disso, algumas funções da API do Windows (principalmente as de nível mais baixo) não permitem o uso de barras - as barras invertidas devem ser usadas com elas.

Demi
fonte
4

Sim, mas tudo isso é um ponto discutível. Java converte perfeitamente barras para barras no Windows. Você pode simplesmente usar barras para todos os caminhos codificados ou armazenados na configuração e funcionará para as duas plataformas.

Pessoalmente, eu sempre usar a barra mesmo no Windows, porque é não o caractere de escape. Quer o caminho bruto esteja no código ou seja externalizado em um arquivo de propriedades, eu o codifico da mesma maneira.

Tente! Isso funcionará no Windows. Obviamente, altere o caminho real para algo que exista e seu usuário tenha permissão para ler.

File f = new File("c:/some/path/file.txt");
if (!f.canRead()) {
  System.out.println("Uh oh, Snowman was wrong!");
}

Bônus: você pode até misturar barras no mesmo caminho!

File f = new File("c:/some\\path/file.txt");
if (!f.canRead()) {
  System.out.println("Uh oh, Snowman was wrong again!");
}

fonte
1
Se você ler minha resposta inteira, verá onde digo que sempre o uso do separador de arquivos Unix funcionará corretamente nos dois locais, sem necessidade de conversão.
A pergunta afirma que os arquivos serão transferidos e deixa em aberto como os nomes dos arquivos são armazenados. Eu adicionei um comentário à pergunta pedindo esclarecimentos sobre esse ponto. Com base na resposta, editarei minha resposta conforme apropriado.
É bastante improvável que o programa realmente contenha uma lista inserida manualmente de todos os arquivos que estão sendo transferidos. É muito mais provável que algum mecanismo automatizado esteja sendo usado para enumerar os arquivos. Dados os parâmetros do problema, conforme declarados na pergunta, esse mecanismo fornece caminhos tradicionais no estilo Windows. Em sua forma atual, essa resposta está dizendo ao OP para resolver um problema diferente, sem dizer a eles como ou mesmo que eles devem transformar o seu em um problema diferente.
Eliah Kagan
Por favor, leia meu comentário anterior.
1
O Windows reconhece barras de avanço e barras invertidas e tem sido assim desde o início do MS-DOS. Ou seja, todo kernel do sistema operacional Microsoft teve suporte a separador de barra. Os COMMAND.COMintérpretes antigos tinham uma preferência de tempo de execução: era possível configurar qual barra o intérprete usaria para imprimir e analisar.
Kaz
3

Outra complicação no Windows é que ele também suporta a notação UNC e as letras de unidade tradicionais.

Um arquivo em um servidor de arquivos remoto pode ser acessado como \\server\sharename\path\filename.

Simon B
fonte
1
Penso que esta é a única preocupação citada até agora que é realmente um problema para esta aplicação. Se houver caminhos UNC envolvidos, eles não poderão ser convertidos utilmente em um caminho no estilo Unix.
Jules
2

Não . Há muito mais em que pensar do que apenas o separador de caminho (a coisa "\ vs /"). Como Rob Y menciona, há como os espaços são manipulados e sua alta frequência no uso do Windows. Existem diferentes caracteres ilegais nos dois ambientes. Existe a disposição do Unix de permitir quase qualquer coisa quando escapado por um "\" principal. Existe o uso de '"' no Windows para lidar com espaços incorporados. Há o uso de UCS-16 pelo Windows e o uso de ASCII ou UTF-8 pelo Unix.

etc. , etc. , etc.

Mas , para muitos aplicativos que podem restringir os nomes de caminho que eles precisam manipular, você pode fazê-lo da maneira que sugere. E funcionará em pelo menos um grande número de casos, mas não em todos eles.

Ross Patterson
fonte
1
Não acho que essas preocupações sejam válidas para a pergunta apresentada. A manipulação de espaço é um problema da interface do usuário; Os sistemas Unix podem lidar com espaços nos nomes de arquivos tão bem quanto o Windows. Os caracteres ilegais do Windows são um superconjunto dos caracteres do Unix. Não pode haver barras invertidas nos nomes de arquivos do Windows (exceto os separadores de diretório que serão convertidos). O uso de cotações para espaços incorporados é uma preocupação no nível da interface do usuário, não um problema de manipulação de arquivos. O código de conversão está aparentemente em Java, portanto, deve lidar com a conversão UCS16-> UTF8 automaticamente.
Jules
-1

Todo sistema operacional da Microsoft, começando com o MS-DOS, entendeu, no nível do kernel, barras e barras invertidas .

Portanto, no Windows, você pode converter entre eles livremente; ambos têm status igual como separadores reservados. Em qualquer caminho válido, você pode substituir barras invertidas por barras e vice-versa, sem alterar seu significado, no que diz respeito ao kernel.

Nas versões anteriores do DOS, o command.comintérprete da Microsoft tornava uma preferência configurável qual barra era usada para exibir e analisar caminhos. Isso acabou sendo removido.

Alguns programas de espaço do usuário no Windows, como, oh, o shell do Windows ( explorer.exe), não gostam de barras. Isso é apenas uma programação de má qualidade nesses programas.

Kaz
fonte
1
Embora isso seja verdade, não acredito que seja útil para a pergunta do OP que envolvia a conversão de nomes de caminhos existentes, que já teriam incluído as barras invertidas. Ele é muito útil para escrever código multi-plataforma para perceber que você pode apenas usar barras e tê-los trabalhar na maioria dos contextos, mas neste caso eu não acho que isso ajuda.
Jules
O @Jules OP está transferindo arquivos do Windows. Esta resposta explica que não há barras invertidas a serem substituídas. Eles não estão no próprio sistema de arquivos do Windows. Todos os caminhos são expressos com barras (e até o Windows o entende).
Kaz