Omega19

Insert a single Line

4 posts in this topic

#1 ·  Posted (edited)

Hello together,

 

I need to write just one line into a file. The file is generated by an other program and contains some information first and afterwards a PDF-file. FileGetEncoding results in 16 (Binary), and it containes @CRLF, @CR and @LF, which need to stay right where they are. The best results I got so far were _FileWriteToLine, which replaced every  @LF and @CR with @CRLF and destroyed the PDF inside of my file. So the line was added but the file got unusable.

I read the following thread

and made my own example to fit my problem, but they doesn't seem to work:

$sFileName = "test.txt"
prepareFile($sFileName)
;Local $result = FileWriteAtLine($sFileName,"Add in line 3",3)
Local $result = FileWriteAfter($sFileName,"Add in line 3","line3")
If $result = 1 Then
    ConsoleWrite("That seems to work." & @CRLF)
Else
    ConsoleWrite("That didn't work. Read lines: " & -$result & @CRLF)
EndIf

Exit

Func prepareFile($sFileName)
    FileWrite($sFileName, "")
    $hFile = FileOpen($sFileName,2+16)
    FileWrite($hFile,"line1" & @CRLF & "line2" & @CRLF & "line3" & @CRLF & "line4" & @CRLF & "line5" & @CRLF & "etc" & @LF & "etc" & @CR & "etc" & @CR & "etc" & @LF & "etc" & @CRLF)
    FileFlush($hFile)
    FileClose($hFile)
EndFunc

Func FileWriteAtLine($sFileName,$sLine,$iLine)
    $linecount = 0
    Local $iEncoding = FileGetEncoding($sFileName,2)
    ConsoleWrite("Encoding: " &$iEncoding & @CRLF )
    $iEncoding = 16
    Local $sTempName = "tempfile.tmp"
    $file = FileOpen($sFileName, $iEncoding)
    ; Check if file opened for reading OK
    If $file = -1 Then
        MsgBox(0, "Error", "Unable to open file.")
        Exit
    EndIf
    Local $sBuffer = FileRead($file,FileGetSize($sFileName))
    If @error = -1 Then ConsoleWrite("CANNOT READ" & @CRLF)
    FileClose($file)
    ConsoleWrite($sBuffer)
    ; Read in lines of text until the EOF is reached
    FileWrite($sTempName,"")
    Local $hTempfile = FileOpen($sTempName,1 + $iEncoding)
    $iResult = 1
    While 1
        Local $iZeichen = StringInStr($sBuffer, @CRLF)
        If $iZeichen > 0 Then
            $linecount += 1
            If $linecount = $iLine Then
                FileWrite($hTempfile,$sLine)
                FileWrite($hTempfile,$sBuffer);Write everything else
                ExitLoop
            EndIf
            Local $line = StringLeft($sBuffer,$iZeichen + 1)
            $sBuffer = StringTrimLeft($sBuffer, $iZeichen +1)
            FileWrite($hTempfile,$line)
            ;FileFlush($hTempfile)
        Else
            FileWrite($hTempfile,$sBuffer);Write everything else
            $iResult = -$linecount
            ExitLoop
        EndIf
    Wend
    FileClose($hTempfile)
    FileMove($sTempName,$sFileName,1)
    Return $iResult
EndFunc


Func FileWriteAfter($sFileName,$sLine,$sAfter)
    $linecount = 0
    Local $iEncoding = FileGetEncoding($sFileName,2)
    ConsoleWrite("Encoding: " &$iEncoding & @CRLF )
    $iEncoding = 16
    Local $sTempName = "tempfile.tmp"
    $file = FileOpen($sFileName, $iEncoding)
    ; Check if file opened for reading OK
    If $file = -1 Then
        MsgBox(0, "Error", "Unable to open file.")
        Exit
    EndIf
    Local $sBuffer = FileRead($file,FileGetSize($sFileName))
    If @error = -1 Then ConsoleWrite("CANNOT READ" & @CRLF)
    FileClose($file)
    ConsoleWrite($sBuffer)
    ; Read in lines of text until the EOF is reached
    FileWrite($sTempName,"")
    Local $hTempfile = FileOpen($sTempName,1 + $iEncoding)
    $iResult = 1
    Local $iZeichen = StringInStr($sBuffer,$sAfter)
    If $iZeichen > 0 Then
        Local $sFirst = StringLeft($sBuffer,$iZeichen + StringLen($sAfter))
        $sBuffer = StringTrimLeft($sBuffer, $iZeichen + StringLen($sAfter))
        FileWrite($hTempfile,$sFirst)
        FileWrite($hTempfile,$sLine)
        FileWrite($hTempfile,$sBuffer)
    Else
        FileWrite($hTempfile,$sBuffer);Write everything else
        $iResult = $linecount
    EndIf
    FileClose($hTempfile)
    FileMove($sTempName,$sFileName,1)
    Return $iResult
EndFunc

Both function result in 0, so my string or the  @CRLF cannot be found inside of the buffer.

 

What's my mistake?

 

Thanks,

Omega19

Edited by Omega19

Share this post


Link to post
Share on other sites



Try this:

Global $sFileName = @TempDir & "\test.txt"
Local $TestContent = "line1" & @CRLF & "line2" & @CRLF & "line3" & @CRLF & "line4" & @CRLF & "line5" & @CRLF & "etc" & @LF & "etc" & @CR & "etc" & @CR & "etc" & @LF & "etc" & @CRLF

Local $hFile = FileOpen($sFileName, 2 + 8 + 256)
FileWrite($hFile, $TestContent)
FileClose($hFile)
Local $result = AddLineAtOrAfterLine($sFileName, "line3", "Add after line 3", 0)
ConsoleWrite("---" & @CRLF)
ConsoleWrite("" & FileRead($sFileName) & @CRLF)
ConsoleWrite("---" & @CRLF)

Local $hFile = FileOpen($sFileName, 2 + 8 + 256)
FileWrite($hFile, $TestContent)
FileClose($hFile)
Local $result = AddLineAtOrAfterLine($sFileName, "line3", "Replace line 3", 1)
ConsoleWrite("---" & @CRLF)
ConsoleWrite("" & FileRead($sFileName) & @CRLF)
ConsoleWrite("---" & @CRLF)

Exit FileDelete($sFileName)

Func AddLineAtOrAfterLine($sFileName, $sFindLine, $sLineToAddOrReplace, $sType = 0);$sType=1 for Replace ; $sType=0 add after!
    Local $iContent, $iError, $iEncoding = FileGetEncoding($sFileName, 2)
    ConsoleWrite("! File: " & $sFileName & " - Encoding: " & $iEncoding & @CRLF)
    Local $hFile = FileOpen($sFileName, $iEncoding)
    $iError = @error
    If $iError Then Return SetError(1, $iError, 0)
    Local $aLine = FileReadToArray($hFile)
    $iError = @error
    If $iError Then Return SetError(2, $iError, 0)
    FileClose($hFile)
    For $i = 0 To UBound($aLine) - 1
        If ($aLine[$i] = $sFindLine) Then
            ConsoleWrite("+ On line: " & $i + 1 & " " & $aLine[$i] & @CRLF)
            If $sType Then
                $iContent &= $sLineToAddOrReplace & @CRLF
            Else
                $iContent &= $aLine[$i] & @CRLF & $sLineToAddOrReplace & @CRLF
            EndIf
        Else
            $iContent &= $aLine[$i] & @CRLF
        EndIf
    Next
    $hFile = FileOpen($sFileName, 2 + 8 + $iEncoding)
    FileWrite($hFile, $iContent)
    $iError = @error
    If $iError Then Return SetError(3, $iError, 0)
    Return FileClose($hFile)
EndFunc   ;==>AddLineAtOrAfterLine

 


Regards,
 

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

Thanks for the quick answer, unfortunately this script also replaces every @CR and @LF with @CRLF.

FileReadToArray and FileReadLine both accept @CR, @LF and @CRLF as end of line, but they automatically cut it out and I have no idea which one it was in the first place.

[edit]notepad++ will show you if a linebreak is lf, cr or crlf if you press the "Show all Characters" button

Edited by Omega19
Checking correct answer

Share this post


Link to post
Share on other sites

Just solved it by myself:

i forced the encoding 512 (ANSI), which seems to have no idea what cr and lf is. That way, they stay the same. Just edit the lines $iEncoding = 16 with $iEncoding = 512 and it shoudl work

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

  • Similar Content

    • sivaramanm
      By sivaramanm
      From AutoIT script (Pretty much same syntax as VBA), Tried connecting to MySQL Server. While i am able to insert a new row successfully, unable to verify the rowcount (# of inserted row - to verify success or failure).
      Have tried two different methods -
      to use the RecordsAffected variable from Connection Execute function to use the RecordSet and retrieve the rowcount But have been missing something and none of these methods return the actual row count.
      Any help would be appreciated.!!!
      Cross-posted in http://stackoverflow.com/questions/27411599/unable-to-retrieve-inserted-row-count-in-mysql-using-ado-from-autoit
      MySQLConnect() $EVENT_TIME= "2014-12-12 12:12:12" $LSMCName='LSMC1' $NEType='MME0001' $OMTarFile='A_MME0011-60MIN-20141212-12-v.tar' $CSVFile='12-00-S1AP.csv' $KPIType='S1AP_HO' $UpdateStatus='NotUpdated' $ReTries='0' If Not (InsertFileUpdateLog($EVENT_TIME,$LSMCName,$NEType,$OMTarFile,$CSVFile,$KPIType,$UpdateStatus,$ReTries)=1) Then WriteLog("[Error] Record insertion failed for " & $EVENT_TIME & '" ' & $LSMCName & ' ' & $NEType & ' ' & $OMTarFile & ' ' & $CSVFile & ' ' & $KPIType & ' ' & ' NotUpdated 0') EndIf MysqlDisconnect() ;~ ####################### Sub Function Definitions Func MySQLConnect() Local $sDriver="MySQL ODBC 5.3 ANSI Driver" Local $key = "HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\ODBC Drivers", $val = RegRead($key, $sDriver) If @error or $val = "" Then SetError(2) Return -1 EndIf $constrim="DRIVER={MySQL ODBC 5.3 ANSI Driver};SERVER=localhost;DATABASE=pmdemo;uid=rootuser;pwd=rootpass;" $oDBConnect = ObjCreate ("ADODB.Connection") ; <== Create SQL connection $oDBConnect.Open ($constrim) ; <== Connect with required credentials if @error Then WriteLog("[Error] Failed to connect to the database") SetError(2) Return -2 Else ;MsgBox(0, "Success!", "Connection to database successful!") Return 1 EndIf EndFunc Func MySQLDisConnect() $oDBConnect.Close ; ==> Close the database EndFunc Func InsertFileUpdateLog($EVENT_TIME,$LSMCName,$NEType,$OMTarFile,$CSVFile,$KPIType,$UpdateStatus,$ReTries) Local $RowCount = 0 Local $result = ObjCreate("ADODB.Recordset") $sQuery = "INSERT INTO 4gc_fileupdatelog (id,EVENT_TIME,LSMC,NEType,TarFile,CSVFile,KPIFile,UpdateStatus,ReTries) VALUES ('0'," & _ "'" & $EVENT_TIME & "'," & _ "'" & $LSMCName & "'," & _ "'" & $NEType & "'," & _ "'" & $OMTarFile & "'," & _ "'" & $CSVFile & "'," & _ "'" & $KPIType & "'," & _ "'" & $UpdateStatus & "'," & _ "'" & $ReTries & "'" & _ ") ON DUPLICATE KEY UPDATE ReTries=ReTries+1,UpdateStatus='" & $UpdateStatus & "';" $result = $oDBConnect.Execute($sQuery,$RowCount) If @error Then MsgBox(1,1,"Error executing query...") Return -2 EndIf ;# Method-1 : To use records affected from Execute function If $RowCount >= 1 Then MsgBox(1,1,"Success") Else MsgBox(1,1,"Failed, rowcount is:" & $RowCount ) EndIf If Not ($result.bof AND $result.eof) Then WriteLog("[Error] No Rows found") Return 0 EndIf ;# Method-2 : To use recordsset object and retrieve the rows/columns count If IsObj($result) And $result.EOF=False Then $myarray=$result.GetRows() $rows = UBound($myarray,1) $cols = UBound($myarray,2) MsgBox(1,1," rows: " & $rows & " cols: " & $cols) If ($rows = 1) Then WriteLog("[Info] Record inserted successfully") Return 1 ElseIf ($rows = 2) Then WriteLog("[Alert] Record updated successfully. affected row(s) is " & $rows) Return $rows Else > Blockquote WriteLog("[Error] Record insertion failed. affected row(s) is " & $rows) Return 0 EndIf EndIf EndFunc
    • FireFox
      By FireFox
      Hi,
      It sounds quite easy, but I haven't found anything to retrieve a listview item ID.

      I though it was under my noze, until I found this :

      Unfortunately it's not working (function returning 0), and I'm using the native GUICtrlCreateListView.

      As the topic above, I want to retreive the item ID of the inserted item in order to create a context menu on it.

      Thanks for anyhelp.

      Br, FireFox.