Preciso de uma maneira simples e robusta de remover caracteres ilegais de caminho e arquivo de uma sequência simples. Eu usei o código abaixo, mas ele não parece fazer nada, o que estou perdendo?
using System;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string illegal = "\"M<>\"\\a/ry/ h**ad:>> a\\/:*?\"<>| li*tt|le|| la\"mb.?";
illegal = illegal.Trim(Path.GetInvalidFileNameChars());
illegal = illegal.Trim(Path.GetInvalidPathChars());
Console.WriteLine(illegal);
Console.ReadLine();
}
}
}
GetInvalidFileNameChars()
tira coisas como: \ etc dos caminhos das pastas.Path.GetInvalidPathChars()
não parece despir*
ou?
Respostas:
Tente algo assim;
Mas tenho que concordar com os comentários, provavelmente tentaria lidar com a fonte dos caminhos ilegais, em vez de tentar transformar um caminho ilegal em legítimo, mas provavelmente não intencional.
Edit: ou uma solução potencialmente 'melhor', usando Regex.
Ainda assim, a pergunta precisa ser feita, por que você está fazendo isso em primeiro lugar.
fonte
GetInvalidPathChars()
poderia conter caracteres queGetInvalidFileNameChars()
não. Você não está corrigindo a otimização "prematura". Você está simplesmente usando código incorreto.A pergunta original solicitada para "remover caracteres ilegais":
Você pode substituí-los:
Esta resposta foi em outro tópico de Ceres , eu realmente gosto pura e simples.
fonte
Eu uso o Linq para limpar nomes de arquivos. Você pode facilmente estender isso para verificar também caminhos válidos.
Atualizar
Alguns comentários indicam que esse método não está funcionando para eles, por isso incluí um link para um snippet DotNetFiddle para que você possa validar o método.
https://dotnetfiddle.net/nw1SWY
fonte
var invalid = new HashSet<char>(Path.GetInvalidPathChars()); return new string(originalString.Where(s => !invalid.Contains(s)).ToArray())
. O desempenho provavelmente não é ótimo, mas isso provavelmente não importa.Você pode remover caracteres ilegais usando o Linq assim:
EDIT
É assim que se parece com a edição necessária mencionada nos comentários:
fonte
Todas essas são ótimas soluções, mas todas elas contam
Path.GetInvalidFileNameChars
, que podem não ser tão confiáveis quanto você imagina. Observe a seguinte observação na documentação do MSDN sobrePath.GetInvalidFileNameChars
:Não é melhor com o
Path.GetInvalidPathChars
método. Ele contém exatamente a mesma observação.fonte
Para nomes de arquivos:
Para caminhos completos:
Observe que, se você pretende usá-lo como um recurso de segurança, uma abordagem mais robusta seria expandir todos os caminhos e verificar se o caminho fornecido pelo usuário é realmente filho de um diretório ao qual o usuário deve ter acesso.
fonte
Para iniciantes, o Trim apenas remove os caracteres do início ou do fim da string . Em segundo lugar, você deve avaliar se realmente deseja remover os caracteres ofensivos ou falhar rapidamente e informar ao usuário que seu nome de arquivo é inválido. Minha escolha é a última, mas minha resposta deve mostrar pelo menos como fazer as coisas da maneira certa e errada:
Pergunta StackOverflow mostrando como verificar se uma determinada string é um nome de arquivo válido . Observe que você pode usar o regex desta pergunta para remover caracteres com uma substituição de expressão regular (se você realmente precisar fazer isso).
fonte
A melhor maneira de remover caracteres ilegais da entrada do usuário é substituir caracteres ilegais usando a classe Regex, criar método no código por trás ou validar no lado do cliente usando o controle RegularExpression.
OU
fonte
Eu uso expressões regulares para conseguir isso. Primeiro, construo dinamicamente o regex.
Depois, chamo de removeInvalidChars.Replace para localizar e substituir. Obviamente, isso também pode ser estendido para cobrir os caracteres do caminho.
fonte
new Regex(String.Format("^(CON|PRN|AUX|NUL|CLOCK\$|COM[1-9]|LPT[1-9])(?=\..|$)|(^(\.+|\s+)$)|((\.+|\s+)$)|([{0}])", Regex.Escape(new String(Path.GetInvalidFileNameChars()))), RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.CultureInvariant);
Eu absolutamente prefiro a idéia de Jeff Yates. Funcionará perfeitamente, se você o modificar um pouco:
A melhoria é apenas para escapar do regex gerado automaticamente.
fonte
Aqui está um trecho de código que deve ajudar o .NET 3 e superior.
fonte
A maioria das soluções acima combina caracteres ilegais para o caminho e o nome do arquivo, o que está errado (mesmo quando as duas chamadas retornam o mesmo conjunto de caracteres). Eu primeiro dividiria o caminho + nome do arquivo no caminho e no nome do arquivo, depois aplicaria o conjunto apropriado se eles e depois combinaria os dois novamente.
wvd_vegt
fonte
Se você remover ou substituir por um único caractere os caracteres inválidos, poderá haver colisões:
Aqui está um método simples para evitar isso:
O resultado:
fonte
Lance uma exceção.
fonte
Eu escrevi esse monstro por diversão, ele permite que você ida e volta:
fonte
Eu acho que é muito mais fácil validar usando um regex e especificando quais caracteres são permitidos, em vez de tentar verificar todos os caracteres incorretos. Consulte estes links: http://www.c-sharpcorner.com/UploadFile/prasad_1/RegExpPSD12062005021717AM/RegExpPSD.aspx http://www.windowsdevcenter.com/pub/a/oreilly/windows/news/csharp_0101.html
Além disso, faça uma pesquisa por "editor de expressões regulares", eles ajudam muito. Existem alguns exemplos nos quais até o código em c # é exibido para você.
fonte
Parece ser O (n) e não gasta muita memória em seqüências de caracteres:
fonte
Escaneando as respostas aqui, todas elas ** parecem envolver o uso de uma matriz de caracteres com caracteres inválidos para o nome do arquivo.
Concedido, isso pode ser micro-otimizador - mas, para o benefício de qualquer pessoa que esteja procurando verificar um grande número de valores como nomes de arquivos válidos, é importante notar que a criação de um hashset de caracteres inválidos trará um desempenho notavelmente melhor.
Fiquei muito surpreso (chocado) no passado com a rapidez com que um hashset (ou dicionário) supera a iteração em uma lista. Com strings, é um número ridiculamente baixo (cerca de 5-7 itens de memória). Com a maioria dos outros dados simples (referências a objetos, números etc.), o cruzamento mágico parece estar em torno de 20 itens.
Existem 40 caracteres inválidos na "lista" Path.InvalidFileNameChars. Fiz uma pesquisa hoje e há uma boa referência aqui no StackOverflow que mostra que o hashset levará um pouco mais da metade do tempo de uma matriz / lista para 40 itens: https://stackoverflow.com/a/10762995/949129
Aqui está a classe auxiliar que eu uso para higienizar caminhos. Eu esqueço agora porque eu tinha a opção de substituição sofisticada, mas está lá como um bônus fofo.
Método de bônus adicional "IsValidLocalPath" também :)
(** aqueles que não usam expressões regulares)
fonte
Você pode usar o método claramente.
fonte
O nome do arquivo não pode conter caracteres de
Path.GetInvalidPathChars()
,+
e#
símbolos, e outros nomes específicos. Combinamos todas as verificações em uma classe:O método
GetValidFileName
substitui todos os dados incorretos para_
.fonte
Um alinhador para limpar a string de quaisquer caracteres ilegais para nomeação de arquivos do Windows:
fonte
fonte
Isso vai querer o que você quer e evitar colisões
fonte
Eu acho que a pergunta já não está completa respondida ... As respostas descrevem apenas o nome do arquivo limpo OU o caminho ... não os dois. Aqui está a minha solução:
fonte
Eu criei um método de extensão que combina várias sugestões:
Fonte:
fonte
Aqui está uma função que substitui todos os caracteres ilegais em um nome de arquivo por um caractere de substituição:
Por exemplo, o sublinhado pode ser usado como um caractere de substituição:
fonte
Ou você pode simplesmente fazer
fonte