2016-02-26 90 views
1

如何檢查String值是文件夾還是文件?我使用FileSystemWatcher以檢查文件的變化或文件夾,然後我這個代碼將其存儲在List(Of String)檢查字符串是文件還是文件夾VB.NET

Private Sub logrename(ByVal source As Object, ByVal e As System.IO.RenamedEventArgs) 
    oldfldrnme.Add(e.OldName) 
    newfldrnme.Add(e.Name) 
End Sub 

使用此代碼:

Dim dest As String = Label6.Text 

    For i = 0 To oldfldrnme.Count - 1 And newfldrnme.Count - 1 
     Dim attri As FileAttribute = File.GetAttributes(i) 
     If ((attri And FileAttribute.Directory) = FileAttribute.Directory) Then 
      Microsoft.VisualBasic.FileIO.FileSystem.RenameDirectory(dest & "\" & oldfldrnme(i), newfldrnme(i)) 
     Else 
      Microsoft.VisualBasic.FileIO.FileSystem.RenameFile(dest & "\" & oldfldrnme(i), newfldrnme(i)) 
     End If 
    Next 

FileNotFound Exception拋出,這條線Visual Studio 2010\Projects\File Sync2\File Sync\bin\Debug\0'.

但此代碼:

For i = 0 To oldfldrnme.Count - 1 And newfldrnme.Count - 1 
     Dim ex As String = Path.HasExtension(i) 
     If ex = False Then 
      Microsoft.VisualBasic.FileIO.FileSystem.RenameDirectory(dest & "\" & oldfldrnme(i), newfldrnme(i)) 
     Else 
      Microsoft.VisualBasic.FileIO.FileSystem.RenameFile(dest & "\" & oldfldrnme(i), newfldrnme(i)) 
     End If 
    Next 

使用目錄的工作,但與文件,它告訴它是一個目錄,扔DirectoryNotFoundException這一行Could not find directory 'D:\Test2\New Text Document.txt'.

+0

'對於i = 0到oldfldrnme.Count - 1和newfldrnme.Count - 1' - 這是什麼?如果計數是相等的,那麼你會得到這個計數作爲結果,否則我懷疑你實際上是想要他們按位「和」。 – GSerg

+0

[更好的方法來檢查路徑是文件還是目錄?]的可能的重複(http://stackoverflow.com/questions/1395205/better-way-to-check-if-path-is-a-file-或者一個目錄) – GSerg

+0

呃我不明白,但這就是我從'List'獲取文件的方式,它的工作方式只有一行。我的意思是在'RenameDirectory'和'RenameFile'之間選擇,所以我必須使用'IF',但我不知道如何驗證它們。 – Dhan

回答

3

首先,你不能在For Next語句中使用And。這會導致你按位組合你的兩個整數。

其次,有一種可能性,即文件不具有擴展名,因此檢查Path.HasExtension()可能在某個時刻拋出異常。

第三,以連接路徑的同時你使用IO.Path.Combine()的更好。

所以首先我們要關注按位組合語句。使用Math.Min()你會得到兩個值中最小的一個(你必須這麼做,因爲如果由於某種原因而有一個比另一個更多的項目,你的代碼會拋出一個IndexOutOfRangeException)。

For i = 0 To Math.Min(oldfldrnme.Count, newfldrnme.Count) - 1 

現在讓我們檢查,如果路徑是一個文件或沒有。你不能這樣做Directory.Exists(i),因爲i是你的Integer變量,而不是一個完整的路徑。要正確檢查它,你必須做Directory.Exists(<path to be renamed>)。我們使用IO.Path.Combine()正確獲取目的地路徑。

For i = 0 To Math.Min(oldfldrnme.Count, newfldrnme.Count) - 1 
    Dim DestPath As String = Path.Combine(dest, oldfldrnme(i)) 'This is the file/directory to be renamed. 
    If File.Exists(DestPath) Then 

    ElseIf Directory.Exists(DestPath) Then 

    End If 
Next 

最後,我們做了重新命名。

For i = 0 To Math.Min(oldfldrnme.Count, newfldrnme.Count) - 1 
    Dim DestPath As String = Path.Combine(dest, oldfldrnme(i)) 'This is the file/directory to be renamed. 
    If File.Exists(DestPath) Then 
     Microsoft.VisualBasic.FileIO.FileSystem.RenameFile(DestPath, newfldrnme(i)) 
    ElseIf Directory.Exists(DestPath) Then 
     Microsoft.VisualBasic.FileIO.FileSystem.RenameDirectory(DestPath, newfldrnme(i)) 
    End If 
Next 

編輯:

隨着科迪灰色指出,很可能需要添加一些異常處理代碼中的其他東西進行I/O操作的文件/目錄的情況下。

因此,我們將在重命名操作周圍添加一條Try Catch聲明。如果發生錯誤,將會執行Catch塊,這意味着您沒有停止整個應用程序的問題。

For i = 0 To Math.Min(oldfldrnme.Count, newfldrnme.Count) - 1 
    Dim DestPath As String = Path.Combine(dest, oldfldrnme(i)) 'This is the file/directory to be renamed. 
    If File.Exists(DestPath) Then 
     Try 
      Microsoft.VisualBasic.FileIO.FileSystem.RenameFile(DestPath, newfldrnme(i)) 
     Catch ex As Exception 
      'Log error using ex.Message. For example "Could not rename file: " & ex.Message 
     End Try 
    ElseIf Directory.Exists(DestPath) Then 
     Try 
      Microsoft.VisualBasic.FileIO.FileSystem.RenameDirectory(DestPath, newfldrnme(i)) 
     Catch ex As Exception 
      'Log error using ex.Message. For example "Could not rename folder: " & ex.Message 
     End Try 
    End If 
Next 
+1

一個不錯的完整答案。在'For Next'語句中使用'And'的好處。我沒有仔細閱讀代碼。不過,你仍然有競爭條件。在下一行執行重命名操作仍然不能確保您要重命名的文件不會被移動或刪除。代碼應該智能地處理異常。沒有人說編程很容易。 :-) –

+0

@CodyGray:然後我們添加一些異常處理! –

+0

@CodyGray:我不知道你對處理'智能'有什麼期望,但它應該完成工作,並且他可以分開文件夾和文件的錯誤。 –

0

用於檢查路徑/文件在VB.NET存在,

If File.Exists(strPath) Then 
    ' yes this is a file 
Else 
    ' oh no 
End If 
+0

這隻適用於文件,即使我把'如果Directory.Exist(i)然後'並沒有做任何事情。 – Dhan

1

GetAttributes功能將拋出如果在不存在的項目上調用,則會發生異常。它怎麼可能做不到?不存在的東西沒有屬性。因此,檢查是否存在某種東西並不是一個通用的解決方案。

您將需要使用Exists方法。例如:

Public Enum FileSystemObject 
    InvalidPath 
    Directory 
    File 
End Enum 

Public Function WhatIsThisThing(String path) As FileSystemObject 
    If Directory.Exists(path) Then 
     Return FileSystemObject.Directory 
    Else If File.Exists(path) 
     Return FileSystemObject.File 
    Else 
     Return FileSystemObject.InvalidPath 
    End If 
End Function 

但是,你仍然有可能的競爭條件在這裏,當你執行文件I/O時,總是這樣。事先執行檢查是好的,但你需要處理您嘗試重命名對象時可能會引發的異常。您無法確保文件或文件夾在您檢查其存在與發出重命名命令的時間之間沒有被刪除或重命名。

+0

這沒有錯誤,但它爲什麼不執行重命名?這就是我做的 'For i = 0 To oldfldrnme.Count - 1 and newfldrnme.Count - 1 If WhatIsThisThing(i)= FileSystemObject.Directory Then' – Dhan

+0

@Dhan:停止檢查'i',並開始檢查'oldfldrnme (ⅰ)'。查看我的答案以獲得更正/改進列表。 –

0

你可以試試這個:

Imports System.IO 

Public Class Form1 
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 
     ListBox1.Items.Clear() 
     Listfolders(TextBox1.Text) 'Call Public Sub ListFolders 
    End Sub 

    Public Sub Listfolders(ByVal Path As String) 'Path is Texbox1.Text 
     Dim DirInfo As New IO.DirectoryInfo(Path) 'C:\!Testfolder 
     Dim FileObject As IO.FileSystemInfo 
     For Each FileObject In DirInfo.GetFileSystemInfos 'fileobject is file or folder 
      If FileObject.Attributes = IO.FileAttributes.Directory Then 
       'Fileobject is Folder 
       Listfolders(FileObject.FullName) 'Use public Sub again to find folders and files in subfolders     
       ListBox1.Items.Add(FileObject.Name) 'Add folder to listbox 
      Else 
       'Fileobject is file 
       ListBox1.Items.Add(FileObject.Name) 'Add file to listbox 
      End If 
     Next 
    End Sub 
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load 
     TextBox1.Text = "C:\!TestFolder" 'Give initial text to Textbox1 
    End Sub 
End Class 
相關問題