Writing to a file without overwriting the existing data

Started by Trasher, July 29, 2005, 10:29:48 PM

Previous topic - Next topic

Trasher

Hello,
I have a problem with masm32 by writing a *.txt file. There's no problem when i try to Create and Write to that file, but when i try to write again the old text gets overwritten by the new one. I don't terminate the exe and use the same Handle. Anybody who can tell me how to do this?
Thanks,

Greetz

Trasher

Ghirai

MASM32 Project/RadASM mirror - http://ghirai.com/hutch/mmi.html

hutch--

Trasher,

I moved your post to the Campus so you will get more answers. As long as you have left the file open, set the file pointer to the end of the file if you want to append data to the file. Same if you open it again to do the same, set the pointer at te end of the file then write to it.


invoke SetFilePointer,hFile,0,0,FILE_END
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

tenkey

If you are reopening a file, do not use CREATE_ALWAYS or CREATE_NEW.

Use OPEN_ALWAYS or OPEN_EXISTING.

Then use SetFilePointer to skip past the existing data.
A programming language is low level when its programs require attention to the irrelevant.
Alan Perlis, Epigram #8

PBrennick

Trasher,
Are you appending data to the existing text file or are you also modifying the existing text?  It makes a difference in terms of how you should proceed.  I did not see you specifically say you are appending.  If you are not appending then you need to load the entire text file into a buffer and do your work there and then save the contents of the buffer, this will preserve your existing data and give you greater versatility.  This is the way a file editor functions.  Using this method you would not use the SetFilePointer API at all.

Paul
The GeneSys Project is available from:
The Repository or My crappy website

Trasher

Thanks for the moving into "Campus"   :U
No i am not modifying the existing text. I only want to add a new one after ne old one. The old text is the same.
I already tried to use SetFilePointer, but when i used that nothing was written to the text file. I use

.data
Filename               db 'myfile.txt',0
hFile                     dd 00
Speicher               db 10 dup (0)
lpNumberOfBytesWritten  dd 0
counter                 dd 0
.code
invoke CreateFile, addr Filename, GENERIC_WRITE, NULL, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL
mov hFile, eax
xor ecx, ecx
@@: mov al, byte ptr [Speicher+ecx]
test al, al
je WriteJump
inc ecx
jmp @B
invoke SetFilePointer, hFile, 10, 0, FILE_END
invoke WriteFile, hFile, addr Speicher, ecx, offset lpNumberOfBytesWritten, NULL
invoke CloseHandle, hFile
invoke ExitProcess,0

I don't know what a do wrong. Perhaps somebody of you see it.
Thanks,

Greetz Trasher

Ghirai

Why do you have the lDistanceToMove 10?

Do as hutch suggested, invoke SetFilePointer,hFile,0,0,FILE_END.

Now everything you write in the file will be appended.
MASM32 Project/RadASM mirror - http://ghirai.com/hutch/mmi.html

Trasher

i also tried invoke SetFilePointer,hFile,0,0,FILE_END ... But then nothing is written to the file, too. :(

Ghirai

ECX gets overwritten when calling SetFilePointer, you should either preserve it or use a var/another register.
You're using it one line below.
MASM32 Project/RadASM mirror - http://ghirai.com/hutch/mmi.html

Trasher

i tried to use EDX as another register but then there's nothing written to the file. Only when i use the SetFilePoiner after the Write API the 10 bytes are written to the textfile but they get overwritten by the new 10 bytes..

hutch--

Trasher,

What you need to do is preserve and restore the correct registers and you will not have the problem. Try this in your procedure.


push ebx
push esi
push edi

; write your code here

pop edi
pop esi
pop ebx
ret


By doing this you can then use any of the 3 preserved registers knowing that they don't get modified in any of the API calls you may make.

What is happening is that EAX ECX and EDX can be modified inside a Windows API call and if you have values in any of them, they will be changed when the API returns.

Now with the file, you have been given the advice to set the style to OPEN_EXISTING which means the file is not overwritten when it is opened and then you set the file pointer to the end of the file so you can append to it. Just get all of the styles right and this technique works fine.

When you get it up and working properly, if you don't use all of the three preserved registers, you can remove the matching push/pop for the unused ones.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

Trasher

i also tried this, because Ghirai already said this, but it has the same effect. I don't know why it doesn't work.

hutch--

Trasher,

Here is a working example of the file IO. Each time you run it, it appends the 10 bytes in the .DATA section to the end of the file. What you need to work out next is what you want to write to it and the loop code you are trying to use to do it.


; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    include \masm32\include\masm32rt.inc
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

comment * -----------------------------------------------------
                        Build this  template with
                       "CONSOLE ASSEMBLE AND LINK"
        ----------------------------------------------------- *

    .data
      Filename      db 'myfile.txt',0
      txt           db "1234567890"

    .data?
      pWritten      dd ?
      hFile         dd ?

    .code

start:
   
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

    call main

    exit

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

main proc

    invoke CreateFile, ADDR Filename,GENERIC_WRITE,NULL,
                       NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL
    mov hFile, eax

    invoke SetFilePointer,hFile,0,0,FILE_END
    invoke WriteFile, hFile,ADDR txt,LENGTHOF txt,ADDR pWritten,NULL
    invoke CloseHandle, hFile

    ret

main endp

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

end start


Here is how you write this type of example using MASM's preprocessor (macro) code.


; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    include \masm32\include\masm32rt.inc
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

comment * -----------------------------------------------------
                        Build this  template with
                       "CONSOLE ASSEMBLE AND LINK"
        ----------------------------------------------------- *

    .code

start:
   
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

    call main

    exit

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

main proc

    LOCAL cloc  :DWORD
    LOCAL wcnt  :DWORD
    LOCAL fname :DWORD
    LOCAL txt   :DWORD
    LOCAL hFile :DWORD

    sas fname,"MyFile.txt"
    sas txt,"1234567890"

    push esi
    mov esi, 50                         ; use ESI as a loop counter

    .if rv(exist,fname) != 0            ; test if file exists
      mov hFile, fopen(fname)           ; open it if it does
    .else
      mov hFile, fcreate(fname)         ; otherwise create a new file
    .endif

    mov cloc, fseek(hFile,0,FILE_END)   ; set the file pointer to the end

  @@:
    mov wcnt, fwrite(hFile,ADDR txt,len(txt))
    sub esi, 1
    jnz @B

    fclose hFile

    ret

main endp

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

end start

Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

Trasher

thank you very much. Now it works! i think it was the "LENGTHOF" i use now. it's better then the way i used before.
Thanks to all


Greetz Trasher

FlySky

Hey guys,

The above examples are working perfectly although I am wondering the following.
With the above examples text strings are appended in at .txt file.
Meaning it is saved like test1 test1 test1 etc...
Is there a way to get the output on a new line like:
test1
test1
test1