Zachary Bonjour
Zachary Bonjour

Reputation: 23

Using Powershell to recursively search directory for files that only contain zeros

I have a directory that contains millions of files in binary format. Some of these files were written to the disk wrong (no idea how). The files are not empty, but they only contain zeros. Heres an example http://pastebin.com/5b7jHjgr

I need to search this directory, find the files that are all zeros and write their path out to a file.

I've been experimenting with format-hex and get-content, but my limited powershell experience is tripping me up. Format-Hex reads the entire file, when I only need the first few bytes, and Get-Content expects text files.

Upvotes: 2

Views: 1070

Answers (2)

Chris
Chris

Reputation: 1009

You can use a System.IO.FileStream object to read the first n bytes of each file.

The following code reads the first ten bytes of each file:

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
    }
}

Upvotes: 1

woxxom
woxxom

Reputation: 73616

Use 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
}

In the old PowerShell 2.0 instead of -File parameter you'll need to filter it manually:

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

Upvotes: 3

Related Questions