今天早上我一直在努力解决一项我不敢相信以前没有人想做的任务 - 将文件、子目录和所有文件的目录复制到另一个位置,但严格复制最大的首先是文件。为什么?因为,据我所见,这将有助于停止将大文件复制到 USB 闪存中,因为它似乎复制文件然后移动它的方式,留下文件大小的间隙。更大的文件无法填补这个空白,所以自己制作。ETc 等最终结果 - 最大的第一个应该希望意味着 1 个间隙用于所有副本,并且生成的文件都在它之后连续排列。我对碎片文件并不执着,而是在 USB 上获取连续文件,如 iso/images。
所以这就是我到目前为止所得到的 - 需要解决的 2 个问题: 1 - 如果目标路径不存在,则只在目标路径上创建 1 级目录 - 我需要它来尽可能多地创建不存在的目录然而 2 - 当第一个副本开始时,它说“没有足够的空间”,即使这个设备上还剩下 30g 来复制一个 4g 的文件。
欢迎大家踊跃投稿!
strPath = "C:\Data\Images\"
strDestPath = "E:\"
Set DataList = CreateObject("ADODB.Recordset")
DataList.Fields.Append "strFilePath", 200, 255 ' adVarChar
DataList.Fields.Append "strFileName", 200, 255 ' adVarChar
DataList.Fields.Append "strFileSize", 3, 4 ' adDouble
DataList.Open
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFSO.GetFolder(strPath)
If Right(strPath, 1) = "\" Then strPath = Left(strPath, Len(strPath) - 1)
If Right(strDestPath, 1) = "\" Then strDestPath = Left(strDestPath, Len(strDestPath) - 1)
'wscript.echo strPath & " " & strDestPath
For Each objFile In objFolder.Files
Call ListFile (objFile, objFolder)
Next
DoSubfolders objFSO.GetFolder(strPath)
DataList.Sort = "strFileSize DESC"
DataList.MoveFirst
Do Until DataList.EOF
strFilePath = DataList.Fields.Item("strFilePath")
strFile = DataList.Fields.Item("strFileName")
strFileName = DataList.Fields.Item("strFileSize")
strFileSizeLG = Len(strFileSize)
intPadding = 15 - strFileSizeLG
strDisplayName = strFile & Space(intPadding)
'wscript.echo strFilePath & "\" & strFile & " == " & strDestPath & Replace(strFilePath,strPath,"") & "\" & strFile
'wscript.echo strFilePath & "\" & strFile & "," & strDestPath & Replace(strFilePath,strPath,"") & "\"
If Not(objFSO.FileExists(strDestPath & Replace(strFilePath,strPath,"") & "\" & strFile)) Then
If Not(objFSO.FolderExists(strDestPath & Replace(strFilePath,strPath,"") & "\")) Then
objFSO.CreateFolder strDestPath & Replace(strFilePath,strPath,"")
End If
wscript.echo strFilePath & "\" & strFile, strDestPath & Replace(strFilePath,strPath,"") & "\"
objFSO.CopyFile strFilePath & "\" & strFile, strDestPath & Replace(strFilePath,strPath,"") & "\",True
End If
DataList.MoveNext
Loop
Sub DoSubFolders(Folder)
For Each Subfolder in Folder.SubFolders
Set objFolder = objFSO.GetFolder(Subfolder.Path)
Set colFiles = objFolder.Files
For Each objFile in colFiles
Call ListFile (objFile, objFolder)
Next
DoSubFolders Subfolder
Next
End Sub
Sub ListFile (objFile, objFolder)
DataList.AddNew
DataList("strFilePath") = objFSO.GetAbsolutePathName(objFolder)
DataList("strFileName") = objFile.Name
DataList("strFileSize") = Int(objFile.Size/1000)
If DataList("strFileSize") = 0 Then DataList("strFileSize") = 1
DataList.Update
End Sub
Set DataList = Nothing : Set objFSO = Nothing : Set objFolder = Nothing
我现在已经使用下面建议的代码工作了,并且在这个新脚本中进行了一些错误检查和修复。但是我仍然遇到无法复制到 USB 的问题。我已将路径更改为 C 驱动器并且它可以工作 - 所以我只能假设这是因为最大的文件是 4.6g,而 USB 是 FAT32,理论上限制为 4G 文件(Windows 可以复制到它吗?)
Dim strRootPath, strDestPath
Const dictKey = 1
Const dictItem = 2
Dim tmp
Dim oFSO, oDict
'------------------- CHANGE PATHS --------------------------
strRootPath = "C:\Data\Images"
strDestPath = "C:\Copy" '"E:\"
'-----------------------------------------------------------
Main
Sub Main()
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oDict = CreateObject("Scripting.Dictionary")
If Right(strRootPath, 1) <> "\" Then strRootPath = strRootPath & "\"
If Right(strDestPath, 1) <> "\" Then strDestPath = strDestPath & "\"
If Not oFSO.FolderExists(strRootPath) Then : wscript.echo "Missing Source : " & strRootPath : wscript.quit
If Not oFSO.FolderExists(strDestPath) Then : wscript.echo "Missing Destination : " & strDestPath : wscript.quit
ProcessFolder strRootPath
CopyBiggestFirst
Set oDict = Nothing
Set oFSO = Nothing
End Sub
Sub ProcessFolder(sFDR)
Dim oFDR, oFile
For Each oFile In oFSO.GetFolder(sFDR).Files
'Wscript.Echo oFile.Size & vbTab & oFile.Path
tmp = Int(oFile.Size/1000)
if tmp = 0 Then tmp = 1
oDict.Add oFile.Path, tmp ' Key: FilePath, Value: Size
Next
For Each oFDR In oFSO.GetFolder(sFDR).SubFolders
ProcessFolder (oFDR.Path)
Next
End Sub
Sub CopyBiggestFirst()
Dim oKeys, oItems, sFileSrc, sFileDst
'Wscript.Echo vbCrLf & "CopyBiggestFirst()"
SortDictionary oDict, dictItem
oKeys = oDict.Keys
oItems = oDict.Items
For i = 0 To oDict.Count - 1
'Wscript.Echo oKeys(i) & " | " & oItems(i)
sFileSrc = oKeys(i)
sFileDst = Replace(sFileSrc, strRootPath, strDestPath)
CreateFolder oFSO.GetFile(sFileSrc).ParentFolder.Path
oFSO.CopyFile sFileSrc, sFileDst
Next
End Sub
Sub CreateFolder(sFDR)
Dim sPath
sPath = Replace(sFDR, strRootPath, strDestPath)
If Not oFSO.FolderExists(sPath) Then
CreateFolder (oFSO.GetFolder(sFDR).ParentFolder.Path)
oFSO.CreateFolder sPath
End If
End Sub
Function GetFolder(sFile)
GetFolder = oFSO.GetFile(sFile).ParentFolder.Path
End Function
Function SortDictionary(oDict, intSort)
Dim strDict()
Dim objKey
Dim strKey, strItem
Dim X, Y, Z
Z = oDict.Count
If Z > 1 Then
ReDim strDict(Z, 2)
X = 0
For Each objKey In oDict
strDict(X, dictKey) = CStr(objKey)
'wscript.echo oDict(objKey)
strDict(X, dictItem) = CLng(oDict(objKey))
X = X + 1
Next
For X = 0 To (Z - 2)
For Y = X To (Z - 1)
If strDict(X, intSort) < strDict(Y, intSort) Then
strKey = strDict(X, dictKey)
strItem = strDict(X, dictItem)
strDict(X, dictKey) = strDict(Y, dictKey)
strDict(X, dictItem) = strDict(Y, dictItem)
strDict(Y, dictKey) = strKey
strDict(Y, dictItem) = strItem
End If
Next
Next
oDict.RemoveAll
For X = 0 To (Z - 1)
oDict.Add strDict(X, dictKey), strDict(X, dictItem)
Next
End If
End Function