2017-03-14 44 views
2

我有一个包含数百万个二进制格式文件的目录。其中一些文件被写入磁盘错误(不知道如何)。这些文件不是空的,但它们只包含零。下面是一个例子http://pastebin.com/5b7jHjgr使用PowerShell递归搜索目录中仅包含零的文件

我需要搜索这个目录,找到全部为零的文件并将它们的路径写入文件。

我一直在试验format-h​​ex和get-content,但是我有限的powershell经验让我绊倒了。格式-hex读取整个文件,当我只需要前几个字节时,Get-Content需要文本文件。

+0

哪种操作系统将你的脚本运行? – Christophe

+0

@Christophe:重要吗?无论如何PowerShell和BCL都在那里。 – Joey

+0

根据操作系统的不同,预装的PowerShell版本也不尽相同。我的答案涵盖了PowerShell 3.0+,如果Zachary使用Windows 7,他只有2.0,并且需要安装Windows Management Framework来升级他的PowerShell版本。 – Christophe

回答

1

可以使用System.IO.FileStream对象读取第一n每个文件的字节数。

下面的代码读取第一个10个字节的每个文件:

Get-ChildItem -Path C:\Temp -File -Recurse | ForEach-Object -Process { 

    # Open file for reading 
    $file = [System.IO.FileStream]([System.IO.File]::OpenRead($_.FullName)) 

    # Go through the first ten bytes of the file 
    $containsTenZeros = $true 
    for($i = 0; $i -lt $file.Length -and $i -lt 10; $i++) 
    { 
     if($file.ReadByte() -ne 0) 
     { 
      $containsTenZeros = $false 
     } 
    } 

    # If the file contains ten zeros then add its full path to List.txt 
    if($containsTenZeros) 
    { 
     Add-Content -Path List.txt -Value $_.FullName 
    } 
} 
+0

那么,考虑到他们想要的文件完全由零字节组成,我想只读_n_字节并不足够。 – Joey

+0

Zachary在他的问题中说“我只需要前几个字节”。 – Christophe

+0

我的理解是,“我只需要用于确定文件的前几个字节,它不包含全零”,这是对于从一开始就是正确的文件的短路操作。 – Joey

3

使用IO.BinaryReader

Get-ChildItem r:\1\ -Recurse -File | Where { 
    $bin = [IO.BinaryReader][IO.File]::OpenRead($_.FullName) 
    foreach ($byte in $bin.ReadBytes(16)) { 
     if ($byte) { $bin.Close(); return $false } 
    } 
    $bin.Close() 
    $true 
} 

在旧的PowerShell 2.0,而不是-File参数,你需要手动将其过滤:

Get-ChildItem r:\1\ -Recurse | Where { $_ -is [IO.FileInfo] } | Where { ..... } 
+0

在那里投入BinaryReader是否有特别的原因? – Joey

+0

它提供了一个方便的ReadBytes()方法,它返回一个字节数组,所以我不必自己分配缓冲区,也不必检查文件长度。 – wOxxOm

+0

哦,对,'OpenRead'返回一个'FileStream'。我真的很惊讶,你可以把它播放到'BinaryReader'。或者至少我不知道这显然等同于调用'[IO.BinaryReader] :: new(...)'。 – Joey