2014-09-10 3 views
0

Задача: Этот скрипт, приведенный ниже, перебирает 4 миллиона файлов и извлекает информацию о свойствах файла, чтобы определить, что можно очистить. В текущем процессе уже используется 20 + ГБ ОЗУ и только половина завершена.VBScript - Создайте текстовый файл, используя имя папки во время цикла

Я создаю большой пакетный файл для записи каждого содержимого подкаталогов в новый текстовый файл. Это непрактично, потому что это занимает много времени, и это первый из нескольких серверов, на которых я буду запускать этот процесс.

Вопросы: -Можно создать новый файл для записи на основе цикла подпапки? (использование свойства объекта вместо файла не похоже на трюк) -Or можно записать содержимое в файл, а затем удалить предыдущие данные из моей временной памяти?

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

+0

Благодарим вас за ввод. Что касается вашего вопроса относительно хранения непосредственно в базе данных, в конечном итоге я буду загружать эти файлы в базу данных MySQL. Однако, с моими ограниченными знаниями VBScript, я выбираю выбор для двухэтапного подхода. Любой вход или совет, который у вас есть, будут очень признательны. – user3549887

ответ

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 = ничего, но вы будете перезаписывать существующие файлы журналов, если есть несколько папок с тем же именем. Таким образом, это то, что вы могли бы выработать, какое-либо правило проверки файла/названия журнала, чтобы обойти дубликат имя вопроса, тогда вы можете уничтожить объект, если хотите.)

Смежные вопросы