2009-07-09 12 views
160

文字列URIからファイル名を取得するこの方法があります。もっと頑強にするために私は何ができますか?C#の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; 
} 

答えて

321

あなただけのSystem.Uriオブジェクトを作成し、ファイル名を抽出するためにUri.LocalPathそして、それはファイルの確認するためにISFILEを使用することができます。

これは、URIの妥当性をチェックする手段を提供するので、これはずっと安全です。


コメントに応答して編集:

をちょうど完全なファイル名を取得するには、私が使用したい:

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

これはあなたのためのエラーチェックのすべてを行い、およびプラットフォームです中性。すべての特別なケースが迅速かつ簡単に処理されます。

+0

私は同意します。すでにあなたにこのようなことをしているので、実際にUriクラスを使用するべきです。 +1 –

+0

うん、あなたがロールアップしているように見えるかもしれないほどシンプルなので、Uriクラスにはプレロールされたパース/検証/エンコード用のグッズがたくさんあります。 – STW

+2

右ですが、ファイル名が必要です。完全なファイルパスではありません。私はまだUri.LocalPathでその踏み台をしていますか? – paulwhit

7
using System.IO; 

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

これはもちろん、ファイル名を解析したことを前提としています。

EDIT#2:

using System.IO; 

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

これは、ファイル名にスペースなどを処理する必要があります。

+3

コロンはすべてのプラットフォーム上のパスでは受け入れられないため、この種のハックは、例えば* nixの亜種で動作するMono.NETで失敗するかもしれません。 System.Uriは、OPが必要とすることを行うように特別に設計されているので、使いやすくなります。 – richardtallent

+1

有効なポイントです!私はいつもモノを忘れる。私はスペースなどについて考えましたが、コロンは考えませんでした。 –

51

Uri.IsFileはhttpのURLで動作しません。これは "file://"に対してのみ機能します。 からMSDN: "SchemeプロパティがUriSchemeFileと等しい場合、IsFileプロパティはです。です。" それに依存することはできません。

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

Uri.LocalPathはWindows固有の変換を行い、Windows以外の環境では正しく動作しません。これを行うための移植可能な方法については、私の答えを参照してください。 –

+0

これは動作します。ありがとう – mjb

19

受け入れられる回答は、httpのURLに問題があります。さらに、Uri.LocalPathはWindows固有の変換を行い、誰かがそこにクエリ文字列を残すと指摘しています。

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

'http:// example.com/dir/hello%20world.txt'のようなエスケープされたURLの場合、これは' hello%20world.txt'を返しますが、 'Uri.LocalPath'アプローチは' hello world.txt ' –

23

ほとんどの回答が不完全であるか、またはスタッフが、クエリ文字列/ハッシュ(パスの後に来て対処していない:より良い方法は、http URLのためにこれを行うにはUri.AbsolutePath

正しい方法を使用することです)。

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.xml" 
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/");    // "" 
8

私は、これは何が必要でしょうと思う:

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

これはあなたが使用することができ、私のサンプルです:

 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"); 
関連する問題