Jump to content

Recommended Posts

Posted (edited)

I've been having trouble reading lines from my ini file - here is my code below. The code below successfully creates and appends a line to the file, it even successfully counts the lines - but when my For loop tries to read the lines it just prints blank lines in my output. Why?

 

#include <StaticConstants.au3>
#include <File.au3>

Local $listFileLocation = @ScriptDir & "\thisFile.ini"

;OpenFile
$listFile = FileOpen($listFileLocation, 9)
LogCheck($listFile,-1,"Failed to open file :"&$listFileLocation)
;WriteLine
$status = FileWriteLine($listFile,"This line!"&@CRLF)
LogCheck($status,0,"Failed to write to $listfile:"&$listFile)
;CountLines
Local $fileLines= _FileCountLines($listFileLocation)
LogCheck(@error,1,"Can't count lines for:"&$listFile)
LogCheck($fileLines,0,"No lines found for counting in:"&$listFile)
Local $string
;Read Lines
For $i=1 to $fileLines
    $string = FileReadLine($listFile,$i)
    LogCheck(@error,1,"Cannot read line #"&$i)
    ConsoleWrite($i&":" & $string & @CRLF)
Next
;CloseFile
$status = FileClose($listFile)
LogCheck($status,0,"Failed to save $listfile::"&$listFile)


;Used for consoleWriting errors.
Func LogCheck($sendCode,$passValue,$errorString)
    Local $negate, $exit
    $negate = StringRegExp($passValue,"^\!.*") ? 0:1
    Switch $negate
        Case 0 ;Negated statement
            $passValue = StringTrimLeft($passValue,1)
            If NOT($sendCode=$passValue) Then
                $exit=1
            EndIf
        Case 1;Positive statement
            If $sendCode=$passValue Then
                $exit=1
            EndIf
    EndSwitch
    If $exit=1 Then
        ConsoleWrite($errorString&@CRLF)
        If NOT ($sendCode = "") Then
            ConsoleWrite("    Passed code: " & $sendCode & @CRLF)
        EndIf
    EndIf
EndFunc

 

Edited by DoubleMcLovin
Posted

First things first, if you're using a file handle, returned by FileOpen, and you're reading the lines one after the other from the file, you don't need the line number in your FileRead, and you don't need the FileCountLines function to count the lines in the file beforehand.

Second, you can't read from a file with a file handle opened for writing, you need to open it for reading, and you need to open it again, with a different handle for writing.

See below.

#include <StaticConstants.au3>
#include <File.au3>
Global $i = 1
Local $listFileLocation = @ScriptDir & "\thisfile.ini"

;OpenFile
$listFilewrite = FileOpen($listFileLocation, 9) ; Opened in write mode
LogCheck($listFilewrite, -1, "Failed to open file :" & $listFileLocation)
$listFileRead = FileOpen($listFileLocation) ; Opened in read mode
LogCheck($listFileRead, -1, "Failed to open file :" & $listFileLocation)
;WriteLine
$status = FileWriteLine($listFilewrite, "This line!" & @CRLF)
LogCheck($status, 0, "Failed to write to $listfile:" & $listFileLocation)
; This whole section isn't needed
;CountLines
;~ Local $fileLines = _FileCountLines($listFileLocation)
;~ LogCheck(@error, 1, "Can't count lines for:" & $listFile)
;~ LogCheck($fileLines, 0, "No lines found for counting in:" & $listFile)
Local $string
;Read Lines
While 1
    $string = FileReadLine($listFileRead)
    If @error = -1 Then ExitLoop
    LogCheck(@error, 1, "Cannot read line #" & $i) ; unnecessary, you should be checking for EOF and not for anything else.
    ConsoleWrite($i & ": " & $string & @CRLF)
    $i += 1
WEnd
;CloseFile
$status = FileClose($listFilewrite) ; This should NEVER give you an error
LogCheck($status, 0, "Failed to save $listfile::" & $listFileLocation)

$status = FileClose($listFileRead) ; This should NEVER give you an error
LogCheck($status, 0, "Failed to save $listfile::" & $listFileLocation)

;Used for consoleWriting errors.
Func LogCheck($sendCode, $passValue, $errorString)
    Local $negate, $exit
    $negate = StringRegExp($passValue, "^\!.*") ? 0 : 1
    Switch $negate
        Case 0 ;Negated statement
            $passValue = StringTrimLeft($passValue, 1)
            If Not ($sendCode = $passValue) Then
                $exit = 1
            EndIf
        Case 1;Positive statement
            If $sendCode = $passValue Then
                $exit = 1
            EndIf
    EndSwitch
    If $exit = 1 Then
        ConsoleWrite($errorString & @CRLF)
        If Not ($sendCode = "") Then
            ConsoleWrite("    Passed code: " & $sendCode & @CRLF)
        EndIf
    EndIf
EndFunc   ;==>LogCheck

BTW, if you're using a real INI file, you should be using the Ini* functions instead of this.

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Posted (edited)

Oh wow, I didn't know any of that - very informative. Thank you, that clears up a lot of confusion in my greater script that I was debugging I think. This fixed my problem and I will mark this thread as solved.

Question: Do I have to close a file explicitly before I can open it again, eg: will calling FileOpen on a file with a currently open handle save and open with the new permissions specified, or will this simply open a second handle through FileOpen and introduce save/close errors later?

Edited by DoubleMcLovin
Posted

If you notice in my script I opened the same file twice at the same time. Once in read more and once in write mode. You won't cause an error by opening it more than once.

 

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Posted (edited)

If you notice in my script I opened the same file twice at the same time. Once in read more and once in write mode. You won't cause an error by opening it more than once.

 

But does this explicitly force a 1) save of the file, 2)closing of the previous file handle, or 4) creation of a secondary handle while leaving first handle open also... or any combination of the above?

Edited by DoubleMcLovin
Posted

Second, you can't read from a file with a file handle opened for writing, you need to open it for reading, and you need to open it again, with a different handle for writing.

Of course you can even read with a write handle. The reason why a fileread doesn't get an result if you use $FO_APPEND is that the file gets opened and the file pointer is setted to the end of the file. There ist nothing more to read. If you handle this you can write and read in the file even with one handle:

$s_FilePath = "test.txt"
$h_File = FileOpen($s_FilePath, 1) ; open in write append mode

; set file pointer to the begin of the file (because write append has set the file pointer to the end)
FileSetPos($h_File, 0, 0)

; read the previous content line by line and write it to the console
Do
    $s_Line = FileReadLine($h_File)
    If @error Then ExitLoop
    ConsoleWrite($s_Line & @CRLF)
Until 0

; now append new data to the file:
FileSetPos($h_File, 0, 2) ; be sure that the file pointer is at the end again
FileWriteLine($h_File, @CRLF & "A new line")

; close the File handle
FileClose($h_File)

 

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...