“O formato do caminho fornecido não é compatível.”

103

Eu tenho o seguinte código em meu serviço da web:

string str_uploadpath = Server.MapPath("/UploadBucket/Raw/");
FileStream objfilestream = new FileStream(str_uploadpath +
                fileName, FileMode.Create, FileAccess.ReadWrite);

Alguém pode me ajudar a resolver o problema com essa mensagem de erro da linha 2 do código.

O formato do caminho fornecido não é compatível.

A permissão na pasta é definida para acesso total a todos e é o caminho real para a pasta.

O ponto de interrupção me deu o valor de str_uploadpathas C:\\webprojects\\webservices\\UploadBucket\\Raw\\.

O que há de errado com essa string?

Toda loira
fonte
Qual é o valor de fileName?
Justin,
Parece que fileNameestá vazio.
Jeremy McGee,
Justin, você estava certo. O valor do nome do arquivo tinha C: / no nome. Isso é o que estava me matando. Obrigado.
All Blond

Respostas:

125

Em vez de usar str_uploadpath + fileName, tente usar System.IO.Path.Combine:

Path.Combine(str_uploadpath, fileName);

que retorna uma string.

Justin
fonte
Recebi um erro agora: Erro 4 Uma diretiva de uso de namespace só pode ser aplicada a namespaces; 'System.IO.Path' é um tipo, não um namespace
All Blond
2
@All Blond coloque using System.IO;acima, então limpe str_uploadpath + fileNamee escrevaPath.Combine(str_uploadpath, fileName)
o código parece abaixo agora, mesmo erro: O formato do caminho fornecido não é compatível. string str_uploadpath = Server.MapPath (@ "/ UploadBucket / Raw /"); str_uploadpath = Path.Combine (str_uploadpath, fileName); FileStream objfilestream = novo FileStream (str_uploadpath, FileMode.Create, FileAccess.ReadWrite);
All Blond
1
@Todos tentam depurar seu código. Coloque um ponto de interrupção na linha exatamente antes da linha que causa o erro (F9 no Visual Studio). Execute seu programa. Quando o programa para no ponto de interrupção, passe o mouse sobre a variável str_uploadpath. Qual é o seu valor?
1
Estou obtendo um caminho sem suporte no seguinte caminho, por quê? "C: \ Users \ Admin \ AppData \ Local \ Adobe \ Flash CS6 \ en_US \ Configuration \ CodeModel \ cm-cache \ SwcCache \ basemovie3.swc1272273593 \ library.swf" Se eu colar no explorer, ele abre bem, mas. O método System.IO.File.ReadAllBytes da NET gera esse erro. Certamente é um caminho válido e preciso, então por que o erro?
Triynko
51

Vejo que o originador descobriu que o erro ocorreu ao tentar salvar o nome do arquivo com um caminho inteiro. Na verdade, é suficiente ter um ":"no nome do arquivo para obter esse erro. Se houver ":"no nome do arquivo (por exemplo, se você tiver um carimbo de data no nome do arquivo), certifique-se de substituí-lo por outro. Ie:

string fullFileName = fileName.Split('.')[0] + "(" + DateTime.Now.ToString().Replace(':', '-') + ")." + fileName.Split('.')[1];
Daniel Hedenström
fonte
2
Isso corrigiu um problema que estou tendo com meu nome de arquivo. Estou acrescentando a data e hora atuais ao meu arquivo e os valores ":" estavam fazendo com que meu programa gerasse o erro OP referenciado.
acedanger de
1
Isso geralmente acontece usando, Path.GetInvalidPathCharsmas não Path.GetInvalidFileNameChars, como foi o meu caso.
Seph
4
Obrigado! É por isso que postar várias respostas é sempre uma boa ideia.
Nick
31

Para mim, o problema era um personagem de "‪" incorporação da esquerda para a direita invisível ao olho humano .
Ele ficou preso no início da string (logo antes do 'D'), depois que copiei e colei o caminho, na guia de segurança de propriedades do arquivo do Windows.

var yourJson = System.IO.File.ReadAllText(@"D:\test\json.txt"); // Works
var yourJson = System.IO.File.ReadAllText(@"‪D:\test\json.txt"); // Error

Portanto, essas, idênticas à primeira vista, duas linhas são realmente diferentes.

Oleg Grishko
fonte
21

Se você estiver tentando salvar um arquivo no sistema de arquivos. Path.Combine não é à prova de balas, pois não ajudará se o nome do arquivo contiver caracteres inválidos. Aqui está um método de extensão que remove caracteres inválidos de nomes de arquivo:

public static string ToSafeFileName(this string s)
{
        return s
            .Replace("\\", "")
            .Replace("/", "")
            .Replace("\"", "")
            .Replace("*", "")
            .Replace(":", "")
            .Replace("?", "")
            .Replace("<", "")
            .Replace(">", "")
            .Replace("|", "");
    }

E o uso pode ser:

Path.Combine(str_uploadpath, fileName.ToSafeFileName());
ThiagoPXP
fonte
Ou ainda mais curtoreturn string.Concat(s.Split(Path.GetInvalidFileNameChars()));
Yousha Aleayoub
7

Entre outras coisas que podem causar este erro:

Você não pode ter certos caracteres na string PathFile completa.

Por exemplo, esses caracteres travarão a função StreamWriter:

"/"  
":"

pode haver outros caracteres especiais que o travem também. Descobri que isso acontece quando você tenta, por exemplo, colocar um carimbo de data e hora em um nome de arquivo:

AppPath = Path.GetDirectoryName(giFileNames(0))  
' AppPath is a valid path from system. (This was easy in VB6, just AppPath = App.Path & "\")
' AppPath must have "\" char at the end...

DateTime = DateAndTime.Now.ToString ' fails StreamWriter... has ":" characters
FileOut = "Data_Summary_" & DateTime & ".dat"
NewFileOutS = Path.Combine(AppPath, FileOut)
Using sw As StreamWriter = New StreamWriter(NewFileOutS  , True) ' true to append
        sw.WriteLine(NewFileOutS)
        sw.Dispose()
    End Using

Uma maneira de evitar esse problema é substituir caracteres problemáticos em NewFileOutS por caracteres benignos:

' clean the File output file string NewFileOutS so StreamWriter will work
 NewFileOutS = NewFileOutS.Replace("/","-") ' replace / with -
 NewFileOutS = NewFileOutS.Replace(":","-") ' replace : with - 

' after cleaning the FileNamePath string NewFileOutS, StreamWriter will not throw an (Unhandled) exception.

Espero que isso evite algumas dores de cabeça para alguém ...!

Michael Herman
fonte
Ah obrigado! Eu estava salvando um arquivo com uma string de data ISO no nome, mas que contém o ilegal ":"! Obrigado!
Mason
3

Se você receber este erro no PowerShell, provavelmente é porque você está usando Resolve-Pathpara resolver um caminho remoto, por exemplo

 Resolve-Path \\server\share\path

Neste caso, Resolve-Pathretorna um objeto que, ao ser convertido em string, não retorna um caminho válido. Ele retorna o caminho interno do PowerShell:

> [string](Resolve-Path \\server\share\path)
Microsoft.PowerShell.Core\FileSystem::\\server\share\path

A solução é usar a ProviderPathpropriedade no objeto retornado por Resolve-Path:

> Resolve-Path \\server\share\path | Select-Object -ExpandProperty PRoviderPath
\\server\share\path
> (Resolve-Path \\server\share\path).ProviderPath
\\server\share\path
Aaron Jensen
fonte
2

Tente mudar:

Server.MapPath("/UploadBucket/Raw/")

para

Server.MapPath(@"\UploadBucket\Raw\")

JimSTAT
fonte
Os URLs geralmente têm barras normais e MapPathsão inteligentes o suficiente para descobrir de qualquer maneira.
Justin,
@spender Existe um @na frente da string que escapa daqueles.
Justin,
2

Este era o meu problema, o que pode ajudar outra pessoa - embora não fosse o problema do OP:

DirectoryInfo diTemp = new DirectoryInfo(strSomePath);
FileStream fsTemp = new FileStream(diTemp.ToString());

Eu determinei o problema enviando meu caminho para um arquivo de log e descobrindo que ele não estava formatado corretamente. O correto para mim era simplesmente:

DirectoryInfo diTemp = new DirectoryInfo(strSomePath);
FileStream fsTemp = new FileStream(diTemp.FullName.ToString());
omJohn8372
fonte
1

Usar o método Path.Combine ajuda? É uma maneira mais segura de unir caminhos de arquivo. Pode ser que esteja tendo problemas para unir os caminhos

Kurru
fonte
0

Estou usando o (limitado) Construtor de expressões para uma variável para uso em uma tarefa de sistema de arquivos simples para fazer um archive de um arquivo no SSIS.

Este é meu hack rápido e sujo para remover os dois pontos para impedir o erro: @ [User :: LocalFile] + "-" + REPLACE ((DT_STR, 30, 1252) GETDATE (), ":", "-") + ".xml"

Adam Noël
fonte
0

Eu tive o mesmo problema hoje. O arquivo que eu estava tentando carregar no meu código foi aberto para edição no Excel. Depois de fechar o Excel, o código começou a funcionar!

Ryano
fonte
-1

Se o valor for um url de arquivo como file: // C: / qualquer, use a classe Uri para traduzir para um nome de arquivo regular:

var localPath = (new Uri(urlStylePath)).AbsolutePath

Em geral, usar a API fornecida é a prática recomendada.

Chris Bordeman
fonte