2016-03-31 77 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)