0

私は以前にこれを投稿しましたが、それをとてもひどく説明したので質問を削除しなければなりませんでした、以前にそれを読んだかもしれない人々に申し訳ありません。もっとはっきりさせておきます。次の3つを指定して、あるディレクトリから別のディレクトリにファイルをコピーできるWinFormアプリケーションを作成する必要があります。

  1. コピー元(txtPath)
  2. コピーするファイル拡張子(指定したものはコピーされたものです)(txtExtensions)
  3. コピー先(txtArchiveTo)

視覚的には次のようになります。

ここに画像の説明を入力してください

txtPathからtxtArchiveToへのコピーは、コピー方法と一致している必要があります。それはtxtPath次のように見える場合です:

c:\temp
  |
   -drivers.exe (file)
   -log.txt (file)
   -\Test1 (directory)
   -\Test2 (directory)

次に、プログラムの実行後に結果が次のようになるtxtArchiveToようなフォルダを選択すると、次のようになります。c:\backup

c:\backup
  |
   -\temp
      |
       -drivers.exe (file)
       -log.txt (file)
       -\Test1 (directory)
       -\Test2 (directory)

コピーされるものはすべて同じ構造に従う必要があります...しかし、参照し続けているように見えるため、これをコーディングするのに苦労していますroot.Parent.Parent。コードを投稿しましょう。

Goボタンは非常に基本的です:

private void btnGo_Click(object sender, EventArgs e)
{
    DirectoryInfo di = new DirectoryInfo(txtPath.Text);
    WalkDirectoryTree(di);
}

これは単にdirectoryinfoオブジェクトを作成するので、txtPathディレクトリへのハンドルがあり、関数を呼び出しますWalkDirectoryTree。その関数は次のようになります。

 private void WalkDirectoryTree(DirectoryInfo root)
        {
            System.IO.FileInfo[] files = null;
            System.IO.DirectoryInfo[] subDirs = null;

            string[] extArray = txtExtensions.Text.Split(' '); //to hold the txtExtensions as an array string { "txt" "tar" "zip" etc.. }
            string ext; //to hold the extension

            // First, process all the files directly under this folder
            try
            {
                files = root.GetFiles("*.*");
            }
            catch (UnauthorizedAccessException e)
            {
                throw; //todo: log this later on...
            }
            catch (System.IO.DirectoryNotFoundException e)
            {
                Console.WriteLine(e.Message);
            }

            if (files != null)
            {
                foreach (System.IO.FileInfo fi in files)
                {
                    string extension = fi.Extension.ToString();
                    if (extension.IndexOf(".") > -1)
                        ext = extension.Substring(1, extension.Length-1);
                    else
                        ext = extension;

                    if (extArray.Any(s => ext.Contains(s)))
                    {    
                        //copy the file
                        if (Directory.Exists(txtArchiveTo.Text + "\\" + fi.Directory.Name))
                            {
                                //directory exists copy the files
                            }
                            else
                            {
                                Directory.CreateDirectory(txtArchiveTo.Text + "\\" + fi.Directory.Name);
                            }

                            File.Copy(fi.FullName, txtArchiveTo.Text + "\\" + fi.Directory.Name + "\\" + fi.Name);                    
                        
                        //create a shortcut pointing back to the file...
                        using (ShellLink shortcut = new ShellLink())
                        {
                            shortcut.Target = fi.FullName;
                            //shortcut.Description = "MY SHORTCUT";
                            shortcut.DisplayMode = ShellLink.LinkDisplayMode.edmNormal;
                            shortcut.ShortCutFile = fi.DirectoryName + "\\" + fi.Name + ".lnk";
                            shortcut.Save();
                        }
                    }

                }

                // Now find all the subdirectories under this directory.
                subDirs = root.GetDirectories();

                foreach (System.IO.DirectoryInfo dirInfo in subDirs)
                {
                    // Resursive call for each subdirectory.
                    WalkDirectoryTree(dirInfo);
                }
            }            
        }

ショートカットなどを作成するコードにはあまり注意を払わないでください。その部分は問題ありません。私が苦労しているのは、次のコード行にぶつかったときです。

 if (extArray.Any(s => ext.Contains(s)))
                        {    
                            //copy the file
                            if (Directory.Exists(txtArchiveTo.Text + "\\" + fi.Directory.Name))
                                {
                                    //directory exists copy the files
                                }
                                else
                                {
                                    Directory.CreateDirectory(txtArchiveTo.Text + "\\" + fi.Directory.Name);
                                }

ファイルのif拡張子がユーザーが入力した拡張子と一致するかどうかを確認するtxtExtensionsだけで、これらの拡張子を持つファイルのみがコピーされますが、見つかったフォルダー内にコピーされます。私の問題はその直後です...私はただ言うことはできません:

Directory.CreateDirectory(txtArchiveTo.Text + "\\" + fi.Directory.Name);

その理由は、アーカイブフォルダがコピーされるものと同じフォルダパスと一致する必要があるためです。たとえば、誰かがコピー元のtxtファイルを検索して見つけるためにc:\ tempを選択し、コピー先のフォルダc:\ backupを選択し、c:\ tempに3つのサブフォルダ(1、2、および3)が含まれている場合、テキストファイル。その結果、プログラムの実行後( "Go"の完了)、アーカイブフォルダーc:\ backupには、txtファイルを含むフォルダー(One、Two、およびThree)が含まれることになります。 、c:\ backup \ One\mytest.txtなど。

これを現在のコードに組み込みたいので、私は本当に親密だと感じていますが、正しいディレクトリ構造を取得するには、いくつかの繰り返しを考え出す必要があると思います。Directory.CreateDirectoryまたはFileInfoクラスの使用方法に関するMSDNに関するリンクに私を投稿しないでください。私はこれらを読み、理解しています。

4

1 に答える 1

2

宛先フォルダーをパラメーターとしてウォーキング関数に渡します。

    private void WalkDirectoryTree(DirectoryInfo root, string DestinationFolder)

次に、ファイルをコピーするときに、fileInfoのCopyToメソッドを使用できます。

     fi.CopyTo(DestinationFolder)

次のメソッドを再帰的に呼び出す場合は、宛先パスに追加するだけです。

    foreach (System.IO.DirectoryInfo dirInfo in subDirs)
    {
        // Resursive call for each subdirectory.
        WalkDirectoryTree(dirInfo, System.IO.Path.Combine(DestinationFolder, dirInfo.Name));
    }

最初の呼び出しを行うときに、出力ディレクトリを計算する必要があります。

string path = txtPath.Text;
string outputDir = txtArchiveTo.Text
string finalDir = System.IO.Path.Combine(outputDir, path.Remove(0, System.IO.Path.GetPathRoot(path).Length));

DirectoryInfo di = new DirectoryInfo(txtPath.Text);
WalkDirectoryTree(di, finalDir);
于 2013-01-15T18:51:29.273 に答える