2017-03-14 8 views
0

名またはパス:私は必要なものC#コンソール文字列の解析:私だけのような線でテキストファイルを読み込み、C#アプリケーション持って

c:\ecpg\BL_Publish_Staging_CFCS_PSC_Outage_Notification_16\myfile2.cfm 
c:\ecpg\BL_Publish_Staging_CFCS_PSC_Outage_Notification_16\includes\my file1.blahh4 

は、このような方法で、各ラインからの二つの値ですが。 1行目から

: "" として 'myfile2.cfm' とfilepath変数として評価 filename変数[空] 2行目から

: '私のfile1.blahh4' と012として評価 filename変数「を含む」として[も可能\は、\サブフォルダ]私はこれまでindexofsubstringしかし、誰成功のようなコードを試してみました

。私はRegExが助けなければならないと思う?基本的には、ファイル名やフォルダ名が始まる前に、スラッシュは常に3になります。

ありがとうございます!

+0

なぜdownvoteですか?私はindexOfと部分文字列を試してみましたが、このスペースを乱雑にするだけのコードが12行以上ありました。 – IrfanClemson

答えて

1

あなたがパスを解析したPathを使用することができます。
詳細については、以下のコードを参照してください。

var path = @"c:\ecpg\BL_Publish_Staging_CFCS_PSC_Outage_Notification_16\myfile2.cfm"; 
var pathFileName = Path.GetFileName(path); // "myfile2.cfm" 

var baseDirectory = @"c:\ecpg\BL_Publish_Staging_CFCS_PSC_Outage_Notification_16"; 
var pathDirectory = Path.GetDirectoryName(path).Replace(baseDirectory, ""); // "" 

編集期待通りに置き換える作業を確実にするためにLowerInvariantへのパスを設定し、それ以下のコードを参照してください。

var baseDirectory = @"c:\ecpg\BL_Publish_Staging_CFCS_PSC_Outage_Notification_16".ToLowerInvariant(); 
var paths = new string[] { 
    @"c:\ecpg\BL_Publish_Staging_CFCS_PSC_Outage_Notification_16\myfile2.cfm", 
    @"c:\ecpg\BL_Publish_Staging_CFCS_PSC_Outage_Notification_16\includes\my file1.blahh4" 
}; 

var sanitizedPaths = new List<Tuple<string,string>>(); 
foreach(var path in paths.Select(p => (p ?? String.Empty).ToLowerInvariant())) 
{ 
    var fileName = Path.GetFileName(path); 
    var directory = Path.GetDirectoryName(path).Replace(baseDirectory, String.Empty); 

    sanitizedPaths.Add(new Tuple<string, string>(fileName, directory)); 
} 

// sanitizedPaths[0] -> "myfile2.cfm" | "" 
// sanitizedPaths[1] -> "my file1.blahh4" | "\includes" 

は編集2お使いのベースディレクトリは、常に3つのセグメントであるという事実に基づいてUriとを使用しては、次のように実行する必要があります。

var paths = new string[] { 
    @"c:\ecpg\BL_Publish_Staging_CFCS_PSC_Outage_Notification_16\myfile2.cfm", 
    @"c:\ecpg\BL_Publish_Staging_CFCS_PSC_Outage_Notification_16\includes\my file1.blahh4", 
    @"c:\ecpg\BL_Publish_Staging_CFCS_PSC_Outage_Notification_16\includes\subFolder\other file.extension" 
}; 

var sanitizedPaths = new List<Tuple<string, string>>(); 
foreach (var path in paths.Select(p => (p ?? String.Empty).ToLowerInvariant())) 
{ 
    var uri = new Uri(path); 
    var pathWithoutBaseDirectory = String.Join("/", uri.Segments.Skip(4)); 

    var fileName = Path.GetFileName(pathWithoutBaseDirectory); 
    var directory = Path.GetDirectoryName(pathWithoutBaseDirectory); 

    sanitizedPaths.Add(new Tuple<string, string>(fileName, directory)); 
} 
+0

ありがとう。 pathFileNameは正しいですが、pathDirectoryはまだ完全なパスに達しています。それらは "include"や "includes \ subfolder"のようなものでなければなりません。注:サブフォルダは 'includes'や 'images'などになる可能性があります。 – IrfanClemson

+0

編集内容を見ると、LowerInvariantを使って期待どおりに動作するはずです – StfBln

+0

ありがとうございます。私はすでにラインが読み込まれているループに入っています。 finalParts [0]変数は、行ごとに完全なパス名を持ちます。あなたのコードのオリジナルは正しいパス名ではなくファイル名を正しく抽出しています。 – IrfanClemson

0

はこれを試してみてください:

var s1 [email protected]"c:\ecpg\BL_Publish_Staging_CFCS_PSC_Outage_Notification_16\myfile2.cfm"; 
var s2 [email protected]"c:\ecpg\BL_Publish_Staging_CFCS_PSC_Outage_Notification_16\includes\my file1.blahh4"; 

var filename = Path.GetFileName(s1); 
var p1 = Path.GetDirectoryName(s1); 
if (!p1.ToLowerInvariant().Contains(@"\includes")) 
    p1 = ""; 
var p2 = Path.GetDirectoryName(s2); 
if (!p2.ToLowerInvariant().Contains(@"\includes")) 
    p2 = ""; 
+0

こんにちは、サブフォルダは '画像'または '含む'とすることができますサブサブフォルダ '画像\サブフォルダのようにすることができます – IrfanClemson

1

使用Pathクラスファイル名とファイルディレクトリを取得するには:

var baseDirectory = @"c:\ecpg\BL_Publish_Staging_CFCS_PSC_Outage_Notification_16\"; 
var files = new[] 
{ 
    @"c:\ecpg\BL_Publish_Staging_CFCS_PSC_Outage_Notification_16\myfile2.cfm", 
    @"c:\ecpg\BL_Publish_Staging_CFCS_PSC_Outage_Notification_16\includes\my file1.blahh4" 
}; 

そしてここでは、LINQクエリ

を行きます
var query = from file in files 
      let directoryName = Path.GetDirectoryName(file) 
      select new 
      { 
       filename = Path.GetFileName(file), 
       filepath = directoryName.StartsWith(baseDirectory) 
         ? directoryName.Substring(baseDirectory.Length) : "" 
      }; 

出力:

[ 
    { 
    filename: "myfile2.cfm", 
    filepath: "" 
    }, 
    { 
    filename: "my file1.blahh4", 
    filepath: "includes" 
    } 
] 
+0

ありがとうございます。あなたの出力は良いですが、私はすでに大ファイルread Whileループに入っています。あなたのロジックをループに組み込む必要があります。時間がかかります。 – IrfanClemson

+0

@Meenglaファイル名が大きなファイルの行である場合、自分のコードに 'files'配列の代わりに' File.ReadLines( "fileName") 'を使うことができます。 LINQクエリ(ファイル名とファイルパスだけでなく)でさらにデータを選択することもできます。または、ループ内で同じコードを使用できます。 'var directoryName = Path.GetDirectoryName(file);'をローカル変数として定義し、ファイルパスを得るためにそれを使用してください。 –

+0

ありがとう。これは各行のファイル名を超えています - 1行に4つの値があります。最初の完全なファイルパスです。そして私はその最初の値からファイル名と必要なパスを抽出しようとしています。 – IrfanClemson

1

私はどうなるのかは、すべてのファイルのリストを取得するには再帰ループでのFileInfoクラスを使用しています。 FileInfoを使用してパスとファイル名を区切ることができます。次に、あなたが作業しているベースフォルダの文字列長を使用し、各ファイルのパスからその文字列を部分文字列にします。

このような何か?

using System; 
using System.Collections.Generic; 
using System.IO; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      RelativePaths p = new RelativePaths(@"u:\test"); 
      foreach (var str in p.MyFiles) 
      { 
       Console.WriteLine(str); 
      } 
      Console.ReadKey(); 
     } 
    } 

    class MyFileInfo 
    { 
     public MyFileInfo(string path, string filename) 
     { 
      Path = path; 
      Filename = filename; 
     } 

     public string Path { get; private set; } 
     public string Filename { get; private set; } 

     public override string ToString() => $"{Path}, {Filename}"; 
    } 

    class RelativePaths 
    { 
     List<MyFileInfo> myPaths = new List<MyFileInfo>(); 

     public RelativePaths(string startingPath = @"U:\test") 
     { 
      DirectoryInfo dir = new DirectoryInfo(startingPath); 
      PathSeparator(dir.FullName, dir); 
     } 

     public MyFileInfo[] MyFiles => myPaths.ToArray(); 

     public void PathSeparator(string originalPath, DirectoryInfo dir) 
     { 
      // Files in dir 
      foreach (var file in dir.GetFiles()) 
      { 
       myPaths.Add(new MyFileInfo(file.DirectoryName.Substring(originalPath.Length), 
              file.Name)); 

      } 

      foreach (var folder in dir.GetDirectories()) 
      { 
       PathSeparator(originalPath, folder); 
      } 
     } 
    } 
} 

オリジナルパス:

U:\テスト\のサブフォルダ

U:\テスト\のtestfile1.txt

U:\テスト\サブフォルダの\ fileinsub1。TXT

U:\テスト\のサブフォルダ\ subfolder2

U:\テスト\サブフォルダ\ subfolder2 \ 2 deep.txt結果が

、testfile1.txt

\ subfolder、fileinsub1.txt

\ subfolder \ subfolder2、two deep.txt

結果はMyFileInfoタイプのリストにあるので、データ出力を使用することができます。これは単なる例である。代わりに拡張メソッドを使用して静的クラスを作成することもできますが、再帰的メソッドを使用して各フォルダを調べることが有用な概念です。ソースコードを新しいコンソールプロジェクトに直接コピーし、Visual Studioで起動するには開始パスを変更するだけです。

+1

PathSeparatorは再帰的なメソッドであることに注意してください。 – James

+0

あなたのコードはパスを ""または "includes \ subfolder"または "includes"、 "images"または "images \ subfolder"にしますか? – IrfanClemson

+1

私はanwserでサンプルを追加します。 – James

関連する問題