If you start reading bytes from the end of the file you will find the last ACK (if there is one). Knowing its position, you can now truncate the file.
I'm not good at PowerShell, so there might be some cmdlet I don't know about, but this achieves what you want:
$filename = "C:\temp\FindAck.txt"
$file = Get-Item $filename
$len = $file.Length
$blockSize = 32768
$buffer = new-object byte[] $blockSize
$found = $false
$blockNum = [math]::floor($len / $blockSize)
$mode = [System.IO.FileMode]::Open
$access = [System.IO.FileAccess]::Read
$sharing = [IO.FileShare]::Read
$fs = New-Object IO.FileStream($filename, $mode, $access, $sharing)
$foundPos = -1
while (!$found -and $blockNum -ge 0) {
$fs.Position = $blockNum * $blockSize
$bytesRead = $fs.Read($buffer, 0, $blocksize)
if ($bytesRead -gt 0) {
for ($i = $bytesRead -1; $i -ge 0; $i--) {
if ($buffer[$i] -eq 6) {
$foundPos = $blockNum * $blockSize + $i
$found = $true
break
}
}
}
$blockNum--
}
$fs.Dispose()
if ($foundPos -ne -1) {
$mode = [System.IO.FileMode]::Open
$access = [System.IO.FileAccess]::Write
$sharing = [IO.FileShare]::Read
$fs = New-Object IO.FileStream($filename, $mode, $access, $sharing)
$fs.SetLength($foundPos)
$fs.Dispose()
}
Write-Host $foundPos
The idea of reading in 32KB blocks is to get a reasonable size chunk from the disk to process rather than reading one byte at a time.
References: