2017-03-14 13 views
2

Ich habe ein Verzeichnis, das Millionen von Dateien im Binärformat enthält. Einige dieser Dateien wurden falsch auf die Festplatte geschrieben (keine Ahnung wie). Die Dateien sind nicht leer, sondern enthalten nur Nullen. Hier ein Beispiel http://pastebin.com/5b7jHjgrMit Powershell rekursiv durchsuchen Verzeichnis für Dateien, die nur Nullen

Ich muss dieses Verzeichnis durchsuchen, die Dateien finden, die nur Nullen sind und ihren Pfad in eine Datei schreiben.

Ich habe mit Format-Hex und Get-Content experimentiert, aber meine begrenzte Powershell-Erfahrung stolpert mich aus. Format-Hex liest die gesamte Datei, wenn ich nur die ersten paar Bytes brauche, und Get-Content erwartet Textdateien.

+0

Auf welchem ​​Betriebssystem Ihr Skript ausführen? – Christophe

+0

@Christophe: Ist es wichtig? PowerShell und der BCL sind auf jeden Fall da. – Joey

+0

Je nach Betriebssystem ist die vorinstallierte PowerShell-Version nicht identisch. Meine Antwort bezieht sich auf PowerShell 3.0+. Wenn Zachary Windows 7 verwenden würde, hätte er nur 2.0 und müsste das Windows Management Framework installieren, um seine PowerShell-Version zu aktualisieren. – Christophe

Antwort

1

Sie verwenden ein System.IO.FileStream Objekt das erste n zu lesen Bytes jeder Datei.

Der folgende Code liest die ersten zehn Bytes jeder Datei:

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

Nun, wenn man bedenkt, dass sie Dateien haben wollen, die komplett aus null Bytes bestehen, dann würde das Lesen von _n_ Bytes nicht wirklich ausreichen. – Joey

+0

Zachary sagt "Ich brauche nur die ersten paar Bytes" in seiner Frage. – Christophe

+0

Ich habe verstanden, dass als "Ich brauche nur die ersten paar Bytes zum Ermitteln von Dateien, die nicht aus Nullen bestehen", als eine Art Kurzschluss für Dateien, die gleich von Anfang an sind. – Joey

3

Verwendung 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 der alten Powershell 2.0 statt -File Parameter Sie es zum Filtern von Hand benötigen: kann

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

Gibt es einen besonderen Grund für die Besetzung von BinaryReader in dort? – Joey

+0

Es bietet eine bequeme ReadBytes() -Methode, die ein Array von Bytes zurückgibt, so dass ich keinen Puffer selbst zuweisen muss, noch die Dateilänge überprüfen. – wOxxOm

+0

Oh, richtig, 'OpenRead' gibt einen' FileStream' zurück. Ich bin wirklich überrascht, dass Sie es einfach zu einem 'BinaryReader' _cast_ können. Oder zumindest war mir nicht bewusst, dass dies scheinbar dem Aufruf von [[IO.BinaryReader] :: new (...) 'entsprechen würde. – Joey

Verwandte Themen