Jump to content

Read a part of a file


 Share

Recommended Posts

Hi,

I want to read just a small part of a file. (Let's say: 1024B)

Well, that looks easy; Just read the file and extract it with StringMid.

But no.

I really want to read only a very small piece of a file. And not the rest.

Because i want to read files larger than 1 gig. If you read a file as large like that... :P (AutoIt crashes)

So I want to read 1024B at the end of a file.

How do I do this? :)

Kip

Link to comment
Share on other sites

Hi,

you can give this a try

http://cpan.uwinnipeg.ca/dist/File-ReadBackwards

So long,

Mega

Scripts & functions Organize Includes Let Scite organize the include files

Yahtzee The game "Yahtzee" (Kniffel, DiceLion)

LoginWrapper Secure scripts by adding a query (authentication)

_RunOnlyOnThis UDF Make sure that a script can only be executed on ... (Windows / HD / ...)

Internet-Café Server/Client Application Open CD, Start Browser, Lock remote client, etc.

MultipleFuncsWithOneHotkey Start different funcs by hitting one hotkey different times

Link to comment
Share on other sites

Try this:

#include <WinApi.au3>
Global $sInFilename, $hInFile, $aResult, $hBuffer, $nRead

$sInFilename = "mybigfile.gho"
ConsoleWrite(" " & $sInFilename & @LF)

$hInFile = _WinAPI_CreateFile($sInFilename, 2, 2, 2)
If $hInFile = 0 Then ConsoleWrite("!> [" & _WinAPI_GetLastError() & "] " & _WinAPI_GetLastErrorMessage() & @LF)

$aResult = DllCall("Kernel32.dll", "dword", "SetFilePointer", "hwnd", $hInFile, "int", -1024, "ptr", 0, "dword", 2)
ConsoleWrite(" File pointer position: " & $aResult[0] & @LF)

$hBuffer = DllStructCreate("ubyte buffer[1024]")
$pBuffer = DllStructGetPtr($hBuffer)
If _WinAPI_ReadFile($hInFile, $pBuffer, 1024, $nRead) Then
    ConsoleWrite(" [" & $nRead & "] bytes read" & @LF)
    $sBuffer = StringTrimLeft(DllStructGetData($hBuffer, "buffer"), 2)  
    For $i=0 To 31
        $sTemp = StringLeft($sBuffer, 32)
        $sBuffer = StringTrimLeft($sBuffer, 32)
        ConsoleWrite(" " & $sTemp & @LF)
    Next
Else
    ConsoleWrite("!> [" & _WinAPI_GetLastError() & "] " & _WinAPI_GetLastErrorMessage() & @LF)
EndIf
_WinAPI_CloseHandle($hInFile)
Edited by zorphnog
Link to comment
Share on other sites

Hi,

I want to read just a small part of a file. (Let's say: 1024B)

Well, that looks easy; Just read the file and extract it with StringMid.

But no.

I really want to read only a very small piece of a file. And not the rest.

Because i want to read files larger than 1 gig. If you read a file as large like that... :P (AutoIt crashes)

So I want to read 1024B at the end of a file.

How do I do this? :)

Kip

Search for randallc's APITailRW.au3 UDF. (Just search for "TailRW".)

:P

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

I made a little GUI script for reading file tails for anyone that is interested.

#include <WinApi.au3>
#include <GuiConstants.au3>

$gMain = GUICreate("FileReadTail", 625, 482, 193, 125)
GUICtrlCreateLabel("Filename:", 8, 12, 49, 17)
$inFilename = GUICtrlCreateInput("", 64, 10, 281, 21)
$btBrowse = GUICtrlCreateButton("Browse...", 360, 8, 75, 25, 0)
$cbOffset = GUICtrlCreateCombo("128", 480, 10, 137, 25)
GUICtrlSetData(-1, "256|512|1024|2048", "512")
GUICtrlCreateLabel("Offset:", 440, 12, 35, 17)
$edResults = GUICtrlCreateEdit("", 16, 56, 593, 377)
GUICtrlSetFont(-1, 8.5, Default, Default, "Courier New")
$btRead = GUICtrlCreateButton("Read", 264, 448, 75, 25, 0)
GUICtrlSetState(-1, $GUI_DISABLE)
$bRead = False
GUISetState(@SW_SHOW)

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
        Case $btBrowse
            $sFilename = FileOpenDialog("Select file to read...", "", "All (*.*)")
            If @error <> 1 Then GUICtrlSetData($inFilename, $sFilename)
        Case $btRead
            _ReadFileTail(GUICtrlRead($inFilename), GUICtrlRead($cbOffset))
    EndSwitch
    If FileExists(GUICtrlRead($inFilename)) Then
        If Not $bRead Then
            GUICtrlSetState($btRead, $GUI_ENABLE)
            $bRead = True
        EndIf
    Else
        If $bRead Then
            GUICtrlSetState($btRead, $GUI_DISABLE)
            $bRead = False
        EndIf
    EndIf
WEnd

Func _ReadFileTail ($sInFilename, $nBytes)
    Local $hInFile, $aResult, $hBuffer, $nRead

    ; Open file for reading
    $hInFile = _WinAPI_CreateFile($sInFilename, 2, 2, 2)
    If $hInFile = 0 Then 
        GUICtrlSetData($edResults, "!> [" & _WinAPI_GetLastError() & "] " & _WinAPI_GetLastErrorMessage() & @CRLF)
        Return
    EndIf

    ; Move file pointer to desired position
    $aResult = DllCall("Kernel32.dll", "dword", "SetFilePointer", "hwnd", $hInFile, "int", Int("-" & $nBytes), "long_ptr", 0, "dword", 2)
    $nPosition = $aResult[0]
    $nOffset = Int("0x" & StringRight(Hex($nPosition), 1))
    $nPosition -= $nOffset
    
    ; Create file read buffer
    $hBuffer = DllStructCreate("ubyte buffer[" & $nBytes & "]")
    $pBuffer = DllStructGetPtr($hBuffer)
    
    If _WinAPI_ReadFile($hInFile, $pBuffer, $nBytes, $nRead) Then
        GUICtrlSetData($edResults, StringFormat("%17s: %s\r\n", "Filename", $sInFilename))
        GUICtrlSetData($edResults, StringFormat("%17s: %s\r\n", "Pointer position", Hex($nPosition)), 1)
        GUICtrlSetData($edResults, StringFormat("%17s: %s\r\n", "Pointer offset", $nOffset), 1)
        GUICtrlSetData($edResults, StringFormat("%17s: %s\r\n\r\n", "Bytes read", $nRead), 1)
        $sBuffer = StringTrimLeft(DllStructGetData($hBuffer, "buffer"), 2)  
        For $i=0 To ($nRead/16)+1
            $sHex = ""
            $sWord = ""
            If $sBuffer = "" Then ExitLoop
            $sTemp = StringLeft($sBuffer, 32-($nOffset*2))
            $sBuffer = StringTrimLeft($sBuffer, 32-($nOffset*2))
            For $j=$nOffset To 15
                $sHex &= StringLeft($sTemp, 2)
                If Mod($j, 2)=1 Then $sHex &= " "
                $nCode = Int("0x" & StringLeft($sTemp, 2))
                If $nCode > 31 And $nCode < 127 Then
                    $sWord &= Chr($nCode)
                Else
                    $sWord &= "."
                EndIf
                $sTemp = StringTrimLeft($sTemp, 2)
                If $sTemp = "" Then ExitLoop
            Next
            If $i=0 Then
                GUICtrlSetData($edResults, StringFormat(" %s: %40s  %16s\r\n", Hex($nPosition), $sHex, $sWord), 1)
                $nOffset = 0
            Else
                GUICtrlSetData($edResults, StringFormat(" %s: %-40s  %-16s\r\n", Hex($nPosition), $sHex, $sWord),1)
            EndIf
            $nPosition += 32
        Next
        _WinAPI_CloseHandle($hInFile)
        Return StringTrimLeft(DllStructGetData($hBuffer, "buffer"), 2)
    Else
        GUICtrlSetData($edResults, "!> [" & _WinAPI_GetLastError() & "] " & _WinAPI_GetLastErrorMessage() & @CRLF)
        _WinAPI_CloseHandle($hInFile)
    EndIf
EndFunc
Link to comment
Share on other sites

  • 11 months later...

I made a little GUI script for reading file tails for anyone that is interested.

#include <WinApi.au3>
#include <GuiConstants.au3>

$gMain = GUICreate("FileReadTail", 625, 482, 193, 125)
GUICtrlCreateLabel("Filename:", 8, 12, 49, 17)
$inFilename = GUICtrlCreateInput("", 64, 10, 281, 21)
$btBrowse = GUICtrlCreateButton("Browse...", 360, 8, 75, 25, 0)
$cbOffset = GUICtrlCreateCombo("128", 480, 10, 137, 25)
GUICtrlSetData(-1, "256|512|1024|2048", "512")
GUICtrlCreateLabel("Offset:", 440, 12, 35, 17)
$edResults = GUICtrlCreateEdit("", 16, 56, 593, 377)
GUICtrlSetFont(-1, 8.5, Default, Default, "Courier New")
$btRead = GUICtrlCreateButton("Read", 264, 448, 75, 25, 0)
GUICtrlSetState(-1, $GUI_DISABLE)
$bRead = False
GUISetState(@SW_SHOW)

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
        Case $btBrowse
            $sFilename = FileOpenDialog("Select file to read...", "", "All (*.*)")
            If @error <> 1 Then GUICtrlSetData($inFilename, $sFilename)
        Case $btRead
            _ReadFileTail(GUICtrlRead($inFilename), GUICtrlRead($cbOffset))
    EndSwitch
    If FileExists(GUICtrlRead($inFilename)) Then
        If Not $bRead Then
            GUICtrlSetState($btRead, $GUI_ENABLE)
            $bRead = True
        EndIf
    Else
        If $bRead Then
            GUICtrlSetState($btRead, $GUI_DISABLE)
            $bRead = False
        EndIf
    EndIf
WEnd

Func _ReadFileTail ($sInFilename, $nBytes)
    Local $hInFile, $aResult, $hBuffer, $nRead

    ; Open file for reading
    $hInFile = _WinAPI_CreateFile($sInFilename, 2, 2, 2)
    If $hInFile = 0 Then 
        GUICtrlSetData($edResults, "!> [" & _WinAPI_GetLastError() & "] " & _WinAPI_GetLastErrorMessage() & @CRLF)
        Return
    EndIf

    ; Move file pointer to desired position
    $aResult = DllCall("Kernel32.dll", "dword", "SetFilePointer", "hwnd", $hInFile, "int", Int("-" & $nBytes), "long_ptr", 0, "dword", 2)
    $nPosition = $aResult[0]
    $nOffset = Int("0x" & StringRight(Hex($nPosition), 1))
    $nPosition -= $nOffset
    
    ; Create file read buffer
    $hBuffer = DllStructCreate("ubyte buffer[" & $nBytes & "]")
    $pBuffer = DllStructGetPtr($hBuffer)
    
    If _WinAPI_ReadFile($hInFile, $pBuffer, $nBytes, $nRead) Then
        GUICtrlSetData($edResults, StringFormat("%17s: %s\r\n", "Filename", $sInFilename))
        GUICtrlSetData($edResults, StringFormat("%17s: %s\r\n", "Pointer position", Hex($nPosition)), 1)
        GUICtrlSetData($edResults, StringFormat("%17s: %s\r\n", "Pointer offset", $nOffset), 1)
        GUICtrlSetData($edResults, StringFormat("%17s: %s\r\n\r\n", "Bytes read", $nRead), 1)
        $sBuffer = StringTrimLeft(DllStructGetData($hBuffer, "buffer"), 2)  
        For $i=0 To ($nRead/16)+1
            $sHex = ""
            $sWord = ""
            If $sBuffer = "" Then ExitLoop
            $sTemp = StringLeft($sBuffer, 32-($nOffset*2))
            $sBuffer = StringTrimLeft($sBuffer, 32-($nOffset*2))
            For $j=$nOffset To 15
                $sHex &= StringLeft($sTemp, 2)
                If Mod($j, 2)=1 Then $sHex &= " "
                $nCode = Int("0x" & StringLeft($sTemp, 2))
                If $nCode > 31 And $nCode < 127 Then
                    $sWord &= Chr($nCode)
                Else
                    $sWord &= "."
                EndIf
                $sTemp = StringTrimLeft($sTemp, 2)
                If $sTemp = "" Then ExitLoop
            Next
            If $i=0 Then
                GUICtrlSetData($edResults, StringFormat(" %s: %40s  %16s\r\n", Hex($nPosition), $sHex, $sWord), 1)
                $nOffset = 0
            Else
                GUICtrlSetData($edResults, StringFormat(" %s: %-40s  %-16s\r\n", Hex($nPosition), $sHex, $sWord),1)
            EndIf
            $nPosition += 32
        Next
        _WinAPI_CloseHandle($hInFile)
        Return StringTrimLeft(DllStructGetData($hBuffer, "buffer"), 2)
    Else
        GUICtrlSetData($edResults, "!> [" & _WinAPI_GetLastError() & "] " & _WinAPI_GetLastErrorMessage() & @CRLF)
        _WinAPI_CloseHandle($hInFile)
    EndIf
EndFunc
the function return part of the file as a string variable? can we re-write the string variable into a new file? and the file still works like the way it used to be?

i'm thinking about file sending through TCP/UDP socket...

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...