Jump to content
Sign in to follow this  
BruceCopperField

Read From the Middle of a File

Recommended Posts

BruceCopperField

I want to extract a few bytes from the middle of a big file (e.g. 4GB). Say, the 2MB from offset 1GB. In FileRead(), there is no offset parameter. How should I skip to the middle of a file efficiently?

Share this post


Link to post
Share on other sites
Kickassjoe

try using FileReadLine(), with _FileCountLines in a For Next loop.

or, if the file is only 1 line (although not likely if it is 4GB...) use StringLen() and StringLeft(), StringRight(), or StringMid()...


What goes around comes around... Payback's a bitch.

Share this post


Link to post
Share on other sites
BruceCopperField

try using FileReadLine(), with _FileCountLines in a For Next loop.

or, if the file is only 1 line (although not likely if it is 4GB...) use StringLen() and StringLeft(), StringRight(), or StringMid()...

The problem is the file is a binary file (say .avi), so i guess line number doesn't apply. By the way, is it really possible to read a single line (assume it is) of 4GB in length and at the same time passing it to StringLen(), StringLeft(), etc without causing any problem?

Share this post


Link to post
Share on other sites
cppman

try using FileReadLine(), with _FileCountLines in a For Next loop.

or, if the file is only 1 line (although not likely if it is 4GB...) use StringLen() and StringLeft(), StringRight(), or StringMid()...

That's loading 4GB into memory. (I doubt AutoIt allows strings that large anyways)

This probably isn't the best way, but heh, it works.

Func _FileReadBytes($sFileName, $nStart, $nEnd)
    Local $nBytesToRead = $nEnd - $nStart
    Local $ResultBuffer = DLLStructCreate("byte[" & $nBytesToRead & "]")
    Local $BytesRead = 0
    Local $OverlappedStruct = DLLStructCreate($tagOVERLAPPED)
    Local $ResultString = ""
    DLLStructSetData($OverlappedStruct, "Offset", $nStart)
    
    $hFile = _WinAPI_CreateFile($sFileName, 2, 2, 2, 4, 0)
    if ($hFile == 0) Then return ""
    
    if (_WinAPI_ReadFile($hFile, DLLStructGetPtr($ResultBuffer), $nBytesToRead, $BytesRead, DLLStructGetPtr($OverlappedStruct)) <> true) then 
        _WinAPI_CloseHandle($hFile)
        Return ""
    EndIf
    
    For $i = 1 to $nBytesToRead + 1
        $ResultString &= Chr(DLLStructGetData($ResultBuffer, 1, $i))
    Next
    
    _WinAPI_CloseHandle($hFile)
    
    Return $ResultString
EndFunc

(If you are reading binary data, I think you might need to return the $ResultBuffer variable because AutoIt might cut the string off after the first NULL character, or call StringToBinary.)

Edited by cppman

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×