2014-09-10 117 views
0

問題: 下面的這個腳本循環播放超過4百萬個文件並檢索文件屬性信息以確定可以清除的內容。目前的過程已經使用20 + GB的RAM,只有一半完成。VBScript - 在循環中使用文件夾名稱創建文本文件

我一直在創建一個大的批處理文件來將每個子文件夾的內容寫入一個新的文本文件。這是不實際的,因爲它耗費時間,這是我將運行此過程的幾臺服務器中的第一臺。

問題: - 是否有可能基於子文件夾循環創建一個新文件來寫入? (使用對象屬性代替文件似乎沒有辦法) - 是可以將內容寫入文件,然後從我的臨時內存中清除以前的數據?

Set objFSO = CreateObject("Scripting.FileSystemObject") 
objStartFolder = "C:\Test" 

Set objFolder = objFSO.GetFolder(objStartFolder) 
Set colFiles = objFolder.Files 

For Each objFile in colFiles 
    On Error Resume Next 
    If Err Then 
     MyFile.Write "Error accessing " & objFile & ": " & Err.Description & vbCrLf 
     Err.Clear 
    Else 
     Q="""" 'Wrap quotes around string 
     strFilePath = Q & objFile.Path & Q 
     strFileName = Q & objFile.Name & Q 
     strFileSize = objFile.Size 
     strFileType = Q & objFile.Type & Q 
     strFileDateCreated = objFile.DateCreated 
     strFileDateLastAccessed = objFile.DateLastAccessed 
     strFileDateLastModified = objFile.DateLastModified 
     Set objWMIService = GetObject("winmgmts:") 
     Set objFileSecuritySettings = _ 
     objWMIService.Get("Win32_LogicalFileSecuritySetting=""" & replace(objFile,  "\", "\\") & """") 
     intRetVal = objFileSecuritySettings.GetSecurityDescriptor(objSD) 
     If intRetVal = 0 Then 
      strFileOwner = Q & objSD.Owner.Domain & "\" & objSD.Owner.Name & Q 
     Else 
      strFileOwner = Q & "Couldn't retrieve security descriptor." & Q 
     End If 

'    CreatedDiff = DateDiff("yyyy",strFileDateCreated,Now) 
'    AccessedDiff = DateDiff("yyyy",strFileDateLastAccessed,Now) 
'    ModifiedDiff = DateDiff("yyyy",strFileDateLastModified,Now) 
'    MaxTime = 3 'Max time in years. For days change "yyyy" to "d" 

'    If (CreatedDiff >= MaxTime) AND (AccessedDiff >= MaxTime) AND  (ModifiedDiff >= MaxTime) Then 

      MyFile.Write strFilePath & "~|~" &_ 
      strFileName & "~|~" &_ 
      strFileSize & "~|~" &_ 
      strFileType & "~|~" &_ 
      strFileDateCreated & "~|~" &_ 
      strFileDateLastAccessed & "~|~" &_ 
      strFileDateLastModified & "~|~" &_ 
      strFileOwner & vbCrLf 
'   End If 
    End If 
Next 

ShowSubfolders objFSO.GetFolder(objStartFolder) 

Sub ShowSubFolders(Folder) 
    For Each Subfolder in Folder.SubFolders 
    On Error Resume Next 
     Set objFolder = objFSO.GetFolder(Subfolder.Path) 
     Set colFiles = objFolder.Files 

    For Each objFile in colFiles 
    On Error Resume Next 
    If Err Then 
     MyFile.Write "Error accessing " & objFile & ": " & Err.Description & vbCrLf 
     Err.Clear 
    Else 
     Q="""" 'Wrap quotes around string 
     strFilePath = Q & objFile.Path & Q 
     strFileName = Q & objFile.Name & Q 
     strFileSize = objFile.Size 
     strFileType = Q & objFile.Type & Q 
     strFileDateCreated = objFile.DateCreated 
     strFileDateLastAccessed = objFile.DateLastAccessed 
     strFileDateLastModified = objFile.DateLastModified 
     Set objWMIService = GetObject("winmgmts:") 
     Set objFileSecuritySettings = _ 
     objWMIService.Get("Win32_LogicalFileSecuritySetting=""" & replace(objFile, "\", "\\") & """") 
     intRetVal = objFileSecuritySettings.GetSecurityDescriptor(objSD) 
     If intRetVal = 0 Then 
      strFileOwner = Q & objSD.Owner.Domain & "\" & objSD.Owner.Name & Q 
     Else 
      strFileOwner = Q & "Couldn't retrieve security descriptor." & Q 
     End If 

'    CreatedDiff = DateDiff("yyyy",strFileDateCreated,Now) 
'    AccessedDiff = DateDiff("yyyy",strFileDateLastAccessed,Now) 
'    ModifiedDiff = DateDiff("yyyy",strFileDateLastModified,Now) 
'    MaxTime = 3 'Max time in years. For days change "yyyy" to "d" 

'    If (CreatedDiff >= MaxTime) AND (AccessedDiff >= MaxTime) AND (ModifiedDiff >= MaxTime) Then 

      MyFile.Write strFilePath & "~|~" &_ 
      strFileName & "~|~" &_ 
      strFileSize & "~|~" &_ 
      strFileType & "~|~" &_ 
      strFileDateCreated & "~|~" &_ 
      strFileDateLastAccessed & "~|~" &_ 
      strFileDateLastModified & "~|~" &_ 
      strFileOwner & vbCrLf 
'    End If 
    End If 
Next 
ShowSubFolders Subfolder 
Next 
End Sub 
+1

有這麼多的數據要存儲,你確定一個文本文件是你最好的選擇?你有沒有考慮過使用數據庫?另外'On Error Resume Next'清除'Err'對象。所以你的'If Err Then'測試總是會是'False'。 – Bond 2014-09-11 12:36:52

+0

感謝您的意見。關於您直接存儲到數據庫的問題,最終我會將這些文件加載​​到MySQL數據庫中。但是,憑藉我有限的VBScript知識,我選擇採用兩步法。任何意見或建議,你可能會不勝感激。 – user3549887 2014-09-11 15:33:12

回答

0

這是一個有點困難,告訴你如何做到這一點,因爲你沒有提供完整的腳本,因爲你引用了未在您提供的代碼實例化對象。

是的,你可以寫每個文件夾的輸出到一個新的文件以及可用內存。儘管你需要改變腳本的結構。我一直在爲你做這件事,直到我遇到更多未定義的對象並放棄了,所以我只是告訴你該怎麼做。

你不需要兩個零件,只要一個就可以。這裏的結構輪廓:

Dim fso, startfolder 
Set fso = CreateObject("Scripting.FileSystemObject") 

startfolder = "C:\temp" 
GetFileInfo startfolder 

Sub GetFileInfo(folderpath) 
    On Error Resume Next 
    Dim file, logpath, logfile, folder 
    logpath = "C:\log\" & fso.GetBaseName(folderpath) & ".log" ' C:\log folder must exist; but of course edit path and file name conventions as desired 
    Set logfile = fso.OpenTextFile(logpath, 2, True) 
    If Err Then EchoAndQuit "Failed to create log " & logpath & ": " & Err.Description 

    ' Write the file info in current folder 
    For Each file In fso.GetFolder(folderpath).Files 
     logfile.WriteLine file.Name ' file/security info 
    Next 

    'Set x = Nothing (Set objects instantiated in this sub to nothing to release memory) 

    ' Now the recursive bit 
    For Each folder In fso.GetFolder(folderpath).SubFolders 
     GetFileInfo(folder.Path) 
    Next 

    On Error GoTo 0 
End Sub 


Sub EchoAndQuit(msg) 
    MsgBox msg, 4096 + 16, "Failed" 
    WScript.Quit 
End Sub 

一個問題是,你會得到一個訪問被拒絕的錯誤,如果你有多個同名的文件夾 - 我會離開它給你制定出一些檢查/命名約定來避免這種情況。 (你可以通過設置logfile = nothing來避開它,但是如果有多個同名的文件夾,你會覆蓋現有的日誌文件,所以你可以設計一些日誌文件檢查/命名約定來避開重複名稱問題,那麼你可以銷燬該對象,如果你想。)

相關問題