Archive: FileWrite Question


FileWrite Question
  Perhaps it is something obvious that I can't get it, though the forum search did not quite help me.
The question is this:
While the FileRead successfully stores in the variable an empty line, the FileWrite assumes that the variable is empty so does not add the empty line to the new file. Examine the example below for details as it become complicated to explain it.
If I don't execute TrimNewLines then the text reproduced correctly in the new text file, but no in the log window where I can see the symbols of return and new line.
If I do execute TrimNewLines then the text displayed correctly in the log window (with empy lines where they exist) but the filewrite does not catch the empty line stored into the variable, so I have to add $\r$\n in order to reproduce the original text structure.
Eh!

!include TextFunc.nsh
!insertmacro TrimNewLines

showinstdetails show
OutFile licopy.exe

Section
SetDetailsPrint none
IfFileExists '$EXEDIR\LicenseCopy.txt' 0 +2
Delete '$EXEDIR\LicenseCopy.txt'
FileOpen $0 "${NSISDIR}\license.txt" r ; file to read
FileOpen $R2 '$EXEDIR\LicenseCopy.txt' w ; file to write
SetDetailsPrint listonly

start:
FileRead $0 $1
StrCmp $1 '' end
;${TrimNewLines} '$1' '$1'
;StrCmp $1 '' 0 +2
;FileWrite $R2 '$\r$\n$\r$\n'
FileWrite $R2 '$1'
FileSeek $R2 '0' END
DetailPrint '$1'
goto start

end:
SetDetailsPrint none
FileClose $0
FileClose $R2
SectionEnd

well, you have a solution, so where's the problem? :)


I have a solution as you said, but, is this the right one?
I mean this is the way supposed to act FileWrite or am I missing something?
And if this is the way, there is a why.
Why FileWrite is not able to manage the empty line that is stored in $var from FileRead? :-)


hmm, i'm wondering if i misunderstood something.

i changed your loop a bit and came with this, plz test:


FileOpen $0 "${NSISDIR}\license.txt" r ; file to read

FileOpen $R0'$EXEDIR\LicenseCopy.txt' w ; file to write
SetDetailsPrint listonly

ClearErrors
loop:
>FileRead $0 $1 ${NSIS_MAX_STRLEN}
>IfErrors end
FileWrite $R0 '$1'
>DetailPrint '$1'
>Goto loop

end:
>SetDetailsPrint none
FileClose$0
FileClose $R0
>

It does exactly the same with my code.
Again the FileWrite does not handle the empty line stored in $1 from FileRead.:-)


Someone plz?!
Someone to explain me why while we are in a loop the FileWrite assumes that the variable $1 has no string, when actually once the variable has not string the loop is terminated. This means that the FileRead detects the empty line as string and it stores it on variable $1, though, the FileWrite does not detect it.


no, that code works fine for me.

the loop i posted above works by 100% fine for me, the file is copied 1:1, just the output in the install log window is crappy.

therefore you'll need to use trimnewlines just for display the license text:


FileOpen $0 "${NSISDIR}\license.txt" r ; file to read

FileOpen $R0'$EXEDIR\LicenseCopy.txt' w ; file to write
SetDetailsPrint listonly

ClearErrors
loop:
>FileRead $0 $1 ${NSIS_MAX_STRLEN}
>IfErrors end
FileWrite $R0 '$1'
>${TrimNewLines} '$1' $2
DetailPrint '$2'
>Goto loop

end:
>SetDetailsPrint none
FileClose$0
FileClose $R0
>

Mine too, works 100% just the output in the install log window is crappy.
If I use TrimNewLines the log window is perfect with the empty lines since FileRead detects these empty lines, though, FileWrite assumes that the variable has no string and therefore the LicenseCopy.txt does not reproduced 100% like the way it is reproduced in log window. In other words DetailPrint and FileWrite they share the same variable at the same time to print the stored string, but, they export different results.


yes, detailprint and filewrite work different regarding line breaks.

but with the code i posted, it works with neither crappy output to the log window nor wrong license file output.


Thanks for the feedback :-)
Well, this is what I'm talking about since I opened this thread. Why FileWrite has different behaviour. I know it's easy to add TrimNewLines either by your way or by my way (examine the script on the top of the thread and uncomment those three lines). Just wanted to know if this happens for some particular reason. That's all. Again thanks a lot for your support :-)


you're welcome :)

i guess, if you want to understand why they work different, you should have a look at the source and find out, through which windows api calls the commands do their work.

this should give us more information :)


Originally posted by Comm@nder21
you're welcome :)

i guess, if you want to understand why they work different, you should have a look at the source and find out, through which windows api calls the commands do their work.

this should give us more information :)
LOL you're right! Certainly I had to do that before. Blame on me!

The difference between DetailPrint and FileWrite is that FileWrite writes exactly what you tell it to. DetailPrint writes one line and adds a line break. If you give FileWrite an empty string, it'll write nothing at all. If you give it a string parsed by TrimNewLines, it won't write a line break and you'll get many lines concatenated.


I think I got it. Allow me to explain it as I understand it.
In order to operate with accuracy, FileRead parses the empty string, so we're able to keep looping. Parses nothing when there is no string, so we're getting out of the loop.
Contrariwise, when the empty string is parsed, FileWrite assumes that there is nothing to write, so if we want to reproduce the line break there is no need for TrimNewLines, otherwise, we do TrimNewLines and then manually add line break where and when it is necessary.

Are these right?

Thanks a lot!


That's about right. Though I wouldn't say FileWrite parses anything. But that's just details.