2016-03-31 85 views
2

我在Windows應用程序中創建基本文件複製操作。我注意到System.IO File.Copy隨機複製文件。 有沒有辦法控制應該先複製哪些文件。例如,如果我們想從最小文件大小開始複製文件。或按字母順序,讓我們說開始複製文件的文件名[從[開始]]到Z,或通過數字順序與文件名[從] 1至100.使用.NET System.IO文件按順序複製文件。複製

我使用這個簡單的代碼來複制文件夾中的文件,但這會「隨機」複製文件。如下所示:

Private Sub btnCopy_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCopy.Click 
    Dim source as string = "c:\copyfiles" 
    Dim destination as string = "d:\backup" 
    Dim filepath as string = destination & "\" 

     For Each filename As String In Directory.GetFiles(source) 
      If File.Exists(filename) Then 
       Dim dFile As String = String.Empty 
       Dim dFilePath As String = String.Empty 

       dFile = Path.GetFileName(filename) 'get filenames from source 
       dFilePath = filepath & dFile 'concatenate filepath and filename 

       File.Copy(filename, dFilePath, True) 'copy files from "c:\copyfiles" folder to destination 
      End If 

     Next 
     MsgBox("Copy Successful", vbOKOnly, "Message") 
End Sub 
+1

使用LINQ順序'目錄的結果。 GetFiles'你想如何訂購複製。 – crashmstr

+0

由於'System.IO File.Copy'只爲每個調用複製一個文件,因此不能隨機進行。 – crashmstr

+0

@crashmstr如果可以從最小到最大的文件大小進行復制。 –

回答

3

如果你想比其他名字的東西(smallest to largest file size,或者是最新的還是最早的),那麼你應該使用DirectoryInfo這樣你就可以在那些FileInfo性能得到處理它們。

' simple ordering by size 
Dim dix As New DirectoryInfo(_your_file_path) 
For Each f As FileInfo In dix.EnumerateFiles. 
       OrderByDescending(Function(o) o.Length) 
    ' do stuff 
Next 

如果你認爲你可能還需要過濾器(即只複製文件自上一次運行),那麼,EnumerateFiles而不是GetFiles()一些LINQ的效率會更高。在這種情況下,.NET會評估你的過濾器,只返回匹配您的過濾器(S),而不是的那些所有的人都爲你在代碼中手動排除:

' process only TXT files in order of size 
For Each f As FileInfo In dix.EnumerateFiles. 
       Where(Function(w) w.Name.EndsWith(".txt")). 
       OrderByDescending(Function(o) o.Length) 
    ' do stuff 
Next 
1

而不是在Directory.GetFiles()中使用foreach將結果獲取到列表中並對該列表進行排序。如果您想基於其他值進行排序,請使用FileInfo數據塊檢索文件信息並根據這些值進行排序。

使用您的排序列表,然後使用Foreach迭代它。列表<>保證提供一個迭代器,它按照它們插入的順序返回列表中的項目。

public void GetOrderedFiles() 
{ 
    // Get unsorted list of file names 
    List<string> fileNames = System.IO.Directory.GetFiles(strPath); 

    List<System.IO.FileInfo> fileInformationList = new List<System.IO.FileInfo>(); 
    // For each file name, get a full file information block 
    fileNames.ForEach(fileName => fileInformationList.Add(new System.IO.FileInfo(fileName))); 
    // Order by CreationTime. Could be any FileInfo data item. 
    IOrderedEnumerable<System.IO.FileInfo> sortedFileInformation = fileInformationList.OrderBy(item => item.CreationTime); 

    // Iterate round the sorted collection 
    foreach(System.IO.FileInfo fileInformation in sortedFileInformation) 
    { 
     System.IO.File.Copy(fileInformation.FullName, /* Destination file name */) 
    } 
} 
+0

這是一個好主意。但對我來說似乎很難。如果你能提供一個簡單的工作例子。我一定會接受你的回答。 –

1

你需要對它們進行排序第一

For Each filename As String In Directory.GetFiles(source) 

更改上述行來:

Dim filenames() as String 
filenames = filenames.OrderBy(Function(f) f.CreationTime) //by time 
filenames = filenames.OrderBy(Function(f) f) //alphabetical, not sure of that one 
filenames = filenames.OrderBy(Function(f) New FileInfo(f).Length) // by size 
    For Each filename As String In filenames 
+0

這是一個簡單的解決方案。我希望這可以工作。感謝buddy –

+0

試試看,讓我知道 – Claudius

+0

上面的代碼會拋出一個錯誤:「類型'System.Linq.IOrderedEnumerable(Of String)'的值不能被轉換爲'String'的一維數組。 –

1

按名稱排序:

For Each filename As String In Directory.GetFiles(source).OrderBy(Function(f) f) 

按大小排序:

For Each filename As String In Directory.GetFiles(source).OrderBy(Function(f) New FileInfo(f).Length)