C #의 URI 문자열에서 파일 이름 가져 오기


206

문자열 URI에서 파일 이름을 가져 오는이 방법이 있습니다. 더 강력하게하려면 어떻게해야합니까?

private string GetFileName(string hrefLink)
{
    string[] parts = hrefLink.Split('/');
    string fileName = "";

    if (parts.Length > 0)
        fileName = parts[parts.Length - 1];
    else
        fileName = hrefLink;

    return fileName;
}

답변:


388

System.Uri 개체를 만들고 IsFile을 사용하여 파일인지 확인한 다음 Uri.LocalPath 를 사용하여 파일 이름을 추출하면됩니다.

URI의 유효성도 검사 할 수있는 방법을 제공하므로 훨씬 안전합니다.


의견에 대한 답변으로 수정 :

전체 파일 이름을 얻으려면 다음을 사용하십시오.

Uri uri = new Uri(hreflink);
if (uri.IsFile) {
    string filename = System.IO.Path.GetFileName(uri.LocalPath);
}

이것은 모든 오류 검사를 수행하며 플랫폼 중립적입니다. 모든 특수 사례가 빠르고 쉽게 처리됩니다.


동의합니다. 이미 Uri 클래스를 사용해야합니다. +1
닥터 존스

2
그렇습니다.하지만 전체 파일 경로가 아닌 파일 이름 만 있으면됩니다. 여전히 Uri.LocalPath에서 해당 단계를 수행하지 않았습니까?
paulwhit

2
@paulwhit :이 경우 Uri.LocalPath 결과에 Path.GetFileName을 사용해야합니다. 이것은 완전히 안전하고 철저하게 처리하는 방법입니다. 이것을 포함하도록 답변을 편집하겠습니다. 참조 : msdn.microsoft.com/en-us/library/…
Reed Copsey

49
isFile은 구성표 만 보는 것처럼 보입니다. 따라서 " www / myFile.jpg "는 false를 반환하고 "file : //www/something.jpg"는 true를 반환하므로이 경우 쓸모가 없습니다.
dethSwatch

6
쿼리 문자열도주의하십시오. http://www.test.com/file1.txt?a=b결과 :file1.txt?a=b
Julian

76

Uri.IsFile은 http URL에서 작동하지 않습니다. "file : //"에서만 작동합니다. 에서 MSDN :는 "ISFILE 속성입니다 진정한 예탁 자산이 UriSchemeFile 같을 때." 따라서 당신은 그것에 의존 할 수 없습니다.

Uri uri = new Uri(hreflink);
string filename = System.IO.Path.GetFileName(uri.LocalPath);

Uri.LocalPath는 Windows 전용 변환을 수행하며 Windows 이외의 환경에서는 올바르게 작동하지 않습니다. 이 작업을 수행하는 휴대용 방법은 아래 답변을 참조하십시오.
Kostub Deshmukh

Uri.IsFilehttp URL / 구성표를 테스트하는 데 사용할 수는 없지만 다음을 사용 하여 http URL에서 파일 이름을 성공적으로 추출 할 수 있습니다.System.IO.Path.GetFileName(url);
Alex Pandrea

50

대부분의 다른 답변은 불완전하거나 경로 뒤에 오는 것들 (쿼리 문자열 / 해시)을 다루지 않습니다.

readonly static Uri SomeBaseUri = new Uri("http://canbeanything");

static string GetFileNameFromUrl(string url)
{
    Uri uri;
    if (!Uri.TryCreate(url, UriKind.Absolute, out uri))
        uri = new Uri(SomeBaseUri, url);

    return Path.GetFileName(uri.LocalPath);
}

시험 결과:

GetFileNameFromUrl("");                                         // ""
GetFileNameFromUrl("test");                                     // "test"
GetFileNameFromUrl("test.xml");                                 // "test.xml"
GetFileNameFromUrl("/test.xml");                                // "test.xml"
GetFileNameFromUrl("/test.xml?q=1");                            // "test.xml"
GetFileNameFromUrl("/test.xml?q=1&x=3");                        // "test.xml"
GetFileNameFromUrl("test.xml?q=1&x=3");                         // "test.xml"
GetFileNameFromUrl("http://www.a.com/test.xml?q=1&x=3");        // "test.xml"
GetFileNameFromUrl("http://www.a.com/test.xml?q=1&x=3#aidjsf"); // "test.xml"
GetFileNameFromUrl("http://www.a.com/a/b/c/d");                 // "d"
GetFileNameFromUrl("http://www.a.com/a/b/c/d/e/");              // ""

7
왜 것입니다 GetFileNameFromUrl("test")결과 "test.xml" 또는 그 그냥 오타인가?
ckittel

27

허용 된 답변은 http URL에 문제가 있습니다. 또한 Uri.LocalPathWindows 특정 변환이 수행되며 누군가 지적한 것처럼 쿼리 문자열이 남아 있습니다. 더 좋은 방법은 사용하는 것입니다Uri.AbsolutePath

http url에 대한 올바른 방법은 다음과 같습니다.

Uri uri = new Uri(hreflink);
string filename = System.IO.Path.GetFileName(uri.AbsolutePath);

7
이스케이프 처리 된 URL의 http://example.com/dir/hello%20world.txt경우이 방법이 반환 hello%20world.txt되지만 Uri.LocalPath접근 방식은 반환됩니다hello world.txt
Jeff Moser

22

나는 이것이 당신이 필요한 것을 할 것이라고 생각합니다 :

var uri = new Uri(hreflink);
var filename = uri.Segments.Last();

2
이것은 실제로는 우아한 솔루션처럼 보이지만 절대 URI에서만 작동하고 인코딩 / 이스케이프 된 값을 반환합니다 ( Uri.UnescapeDataString()% 20 및 +를 공백으로 변경 하는 데 사용 ).
Ronald

8
using System.IO;

private String GetFileName(String hrefLink)
{
    return Path.GetFileName(hrefLink.Replace("/", "\\"));
}

물론 파일 이름을 파싱했다고 가정합니다.

편집 # 2 :

using System.IO;

private String GetFileName(String hrefLink)
{
    return Path.GetFileName(Uri.UnescapeDataString(hrefLink).Replace("/", "\\"));
}

파일 이름에서 공백 등을 처리해야합니다.


3
콜론은 모든 플랫폼의 경로에서 허용되지 않으므로 이러한 종류의 핵은 * nix 변형에서 실행되는 Mono.NET에서 실패 할 수 있습니다. OP가 필요로하는 것을 수행하도록 특별히 설계되었으므로 System.Uri를 사용하는 것이 좋습니다.
richardtallent

1
유효한 포인트! 나는 항상 모노를 잊어 버립니다. 나는 공백 등을 생각했지만 콜론은 아닙니다.
Mike Hofer

2

이것은 당신이 사용할 수있는 내 샘플입니다.

        public static string GetFileNameValidChar(string fileName)
    {
        foreach (var item in System.IO.Path.GetInvalidFileNameChars())
        {
            fileName = fileName.Replace(item.ToString(), "");
        }
        return fileName;
    }

    public static string GetFileNameFromUrl(string url)
    {
        string fileName = "";
        if (Uri.TryCreate(url, UriKind.Absolute, out Uri uri))
        {
            fileName = GetFileNameValidChar(Path.GetFileName(uri.AbsolutePath));
        }
        string ext = "";
        if (!string.IsNullOrEmpty(fileName))
        {
            ext = Path.GetExtension(fileName);
            if (string.IsNullOrEmpty(ext))
                ext = ".html";
            else
                ext = "";
            return GetFileNameValidChar(fileName + ext);

        }

        fileName = Path.GetFileName(url);
        if (string.IsNullOrEmpty(fileName))
        {
            fileName = "noName";
        }
        ext = Path.GetExtension(fileName);
        if (string.IsNullOrEmpty(ext))
            ext = ".html";
        else
            ext = "";
        fileName = fileName + ext;
        if (!fileName.StartsWith("?"))
            fileName = fileName.Split('?').FirstOrDefault();
        fileName = fileName.Split('&').LastOrDefault().Split('=').LastOrDefault();
        return GetFileNameValidChar(fileName);
    }

용법:

var fileName = GetFileNameFromUrl("http://cdn.p30download.com/?b=p30dl-software&f=Mozilla.Firefox.v58.0.x86_p30download.com.zip");

0

간단하고 똑바로 :

            Uri uri = new Uri(documentAttachment.DocumentAttachment.PreSignedUrl);
            fileName = Path.GetFileName(uri.LocalPath);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.