Jump to content

Recommended Posts

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
Posted

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,
 

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
Posted

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

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
×
×
  • Create New...