The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: Sergiu FUNIERU on February 26, 2010, 10:18:19 PM

Title: I can't concatenate binary files
Post by: Sergiu FUNIERU on February 26, 2010, 10:18:19 PM
I want to concatenate 2 files.

I tried this code:
mov hFile1, fopen ("1.txt")                 
mov flen1, fsize (hFile1)                   
mov hMem1, alloc (flen1)                   
mov bwrt1, fread (hFile1, hMem1, flen1)       
fclose hFile1                             


mov hFile2, fopen ("2.txt")           
mov flen2, fsize (hFile2)                   
mov hMem2, alloc (flen2)                   
mov bwrt2, fread (hFile2, hMem2, flen2)       
fclose hFile2                               


mov hFile3, fcreate ("3.txt")         
mov bwrt1, fwrite (hFile3, hMem1, len (hMem1))   
mov cloc, fseek (hFile3, 0, FILE_END)       
mov bwrt2, fwrite (hFile3, hMem2, len (hMem2))   
fclose hFile3   


It works fine with text files.

When I use a binary file instead of 1.txt, the file 3.txt contains only several dozens of characters, even if 1.txt has over 5 MB.
Is there any reason why the above program will not work with binary files?
Title: Re: I can't concatenate binary files
Post by: ragdog on February 26, 2010, 10:27:16 PM
Hi

Here is an old example what i code for a long time

i hope it help



.data
szArchiv db "archiv.7z",0
szSfx    db "7zSD.sfx",0
szConfig db "config.txt",0
szOutput db "archiv.exe",0
dwBytes dd 0
.data?

hInstance   dd ?
hBuffer   db 0

.code
  invoke CreateFile,offset szOutput,
                   GENERIC_WRITE,FILE_SHARE_READ,
                   NULL,
                   OPEN_ALWAYS,
                   FILE_ATTRIBUTE_NORMAL,
                   NULL
               mov hOutputFile,eax
               
            invoke CreateFile,offset szSfx,
                   GENERIC_READ,FILE_SHARE_READ,
                   NULL,OPEN_EXISTING,
                   FILE_ATTRIBUTE_NORMAL,
                   NULL
               mov hSfx, eax
               
            invoke CreateFile,offset szArchiv,
                   GENERIC_READ,FILE_SHARE_READ,
                   NULL,
                   OPEN_EXISTING,
                   FILE_ATTRIBUTE_NORMAL,
                   NULL

               mov hArchiv,eax
               
            invoke CreateFile,offset szConfig,
                   GENERIC_READ,FILE_SHARE_READ,
                   NULL,
                   OPEN_EXISTING,
                   FILE_ATTRIBUTE_NORMAL,
                   NULL

               mov hConfig ,eax
               
            invoke GetFileSize,hSfx,0                          ;get size of file1 (S1)
               mov edi,eax
            invoke GlobalAlloc,GMEM_ZEROINIT,edi
              mov  esi,eax
            invoke ReadFile,hSfx,esi,edi,offset dwBytes,0
              test eax,eax
               jnz @Next4
            invoke MessageBox,hWnd,0,0,MB_OK
               jmp @ret             
     @Next4:
            invoke WriteFile,hOutputFile,esi,edi,offset dwBytes,0
               
               
            ;#####################################################
             invoke GetFileSize,hConfig ,0                          ;get size of file1 (S1)
               mov edi,eax
            invoke GlobalAlloc,GMEM_ZEROINIT,edi
              mov  esi,eax
            invoke ReadFile,hConfig ,esi,edi,offset dwBytes,0
              test eax,eax
               jnz @Next5
            invoke MessageBox,hWnd,0,0,MB_OK
               jmp @ret             
     @Next5:
            invoke WriteFile,hOutputFile,esi,edi,offset dwBytes,0 
           
            ;########################################################
            invoke GetFileSize,hArchiv ,0                          ;get size of file1 (S1)
               mov edi,eax
            invoke GlobalAlloc,GMEM_ZEROINIT,edi
              mov  esi,eax
            invoke ReadFile,hArchiv ,esi,edi,offset dwBytes,0
              test eax,eax
               jnz @Next6
            invoke MessageBox,hWnd,0,0,MB_OK
               jmp @ret             
     @Next6:
            invoke WriteFile,hOutputFile,esi,edi,offset dwBytes,0 
           
        @ret:       
         invoke CloseHandle,hSfx
         invoke CloseHandle,hArchiv
         invoke CloseHandle,hOutputFile
         invoke GlobalFree,esi
Title: Re: I can't concatenate binary files
Post by: BlackVortex on February 26, 2010, 10:33:04 PM
Is that fopen from the msvcrt ? The real fopen accepts a parameter for the type of file (binary,etc.)
http://www.cplusplus.com/reference/clibrary/cstdio/fopen/
Title: Re: I can't concatenate binary files
Post by: Sergiu FUNIERU on February 26, 2010, 10:36:29 PM
Quote from: BlackVortex on February 26, 2010, 10:33:04 PM
Is that fopen from the msvcrt ? The real fopen accepts a parameter for the type of file (binary,etc.)
http://www.cplusplus.com/reference/clibrary/cstdio/fread/
Because I use this : include \masm32\include\masm32rt.inc, I believe that I'm using the fopen defined in the macros.asm file.
Title: Re: I can't concatenate binary files
Post by: BlackVortex on February 26, 2010, 10:37:19 PM
Doesn't it take any parameters ? (I don't use masm)
You need to open with the "rb" flags
Title: Re: I can't concatenate binary files
Post by: Sergiu FUNIERU on February 26, 2010, 10:50:31 PM
Quote from: BlackVortex on February 26, 2010, 10:37:19 PMDoesn't it take any parameters ? (I don't use masm)
I didn't see any. This is from the manual:
fread

mov bWritten, fread(hFile,lpMemory,bytecount)

Description
Read data from an open file.

Parameters
1. hFile The open file handle.
2. buffer The address of the buffer to write the data to.
3. bcnt The number of bytes to read.

Return Value
The return value is the number of bytes read from the file.

Comments
The buffer must be large enough to handle the number of bytes read into it. Normally the buffer will be allocated to at least that size or larger.

Example
mov bWritten, fread(hFile,lpMemory,bytecount)
Title: Re: I can't concatenate binary files
Post by: qWord on February 26, 2010, 10:53:36 PM
len() isn't a good idea because there is no guarantee that a file ends with a zero. Also you've got the size through fsize:
mov hFile3, fcreate ("3.txt")          
mov bwrt1, fwrite (hFile3, hMem1, flen1)    
;mov cloc, fseek (hFile3, 0, FILE_END)  ; not needed - file pointer is at end     
mov bwrt2, fwrite (hFile3, hMem2, flen2)    
fclose hFile3
free(hMem1) ;do not forget this!
free(hMem2)
Title: Re: I can't concatenate binary files
Post by: BlackVortex on February 26, 2010, 11:06:20 PM
Here is a little cmd bonus for Sergiu, since he likes that stuff :
copy 1.txt+2.txt 3.txt
Title: Re: I can't concatenate binary files
Post by: Sergiu FUNIERU on February 26, 2010, 11:15:00 PM
Quote from: BlackVortex on February 26, 2010, 11:06:20 PM
Here is a little cmd bonus for Sergiu, since he likes that stuff :
copy 1.txt+2.txt 3.txt
You're kind with me. Thank you!

I'm trying to learn the I/O in asm. The code I posted, which is remixed from the \masm32\examples\exampl09\fileio\ppfileio.asm code, seemed like a good point to start.

With asm, I always had the feeling that I left something out. I'm trying to shake that feeling.
Title: Re: I can't concatenate binary files
Post by: clive on February 26, 2010, 11:15:16 PM
Quote from: BlackVortex on February 26, 2010, 11:06:20 PM
Here is a little cmd bonus for Sergiu, since he likes that stuff :
copy 1.txt+2.txt 3.txt

For binaries use

copy /b   1.bin+2.bin  3.bin

The /b stops it truncating on Ctrl-Z (0x1A) EOF markers

-Clive
Title: Re: I can't concatenate binary files
Post by: Sergiu FUNIERU on February 26, 2010, 11:19:00 PM
Quote from: qWord on February 26, 2010, 10:53:36 PMlen() isn't a good idea because there is no guarantee that a file ends with a zero.
1. What is better than len ()?
2. My text files didn't end with zero (I suppose you refer to the binary 0, not the digit 0), yet the program worked for them.
Title: Re: I can't concatenate binary files
Post by: qWord on February 26, 2010, 11:40:32 PM
len is used to determinate the size of an zero-terminated string. If your file does not contain an zero, len() returns some longer value (an access violation is also possible). If there is a zero somewhere before the file end, len() returns a value smaller than real size. The best practise is to use the number of written bytes returned be fread (ReadFile).
Quote from: Sergiu Funieru on February 26, 2010, 11:19:00 PMyet the program worked for them.
luck! - on my machine it doesn't work.
Title: Re: I can't concatenate binary files
Post by: Sergiu FUNIERU on February 26, 2010, 11:59:09 PM
Quote from: qWord on February 26, 2010, 11:40:32 PMThe best practise is to use the number of written bytes returned be fread (ReadFile).
I see. I will allocate the space, then read the entire file into memory. I know this is not the best practice, but it's just an example. How do I know how many bytes to allocate if I don't know the length of the file? Because to find the length of the file I need to read the entire file first.

Quote from: qWord on February 26, 2010, 11:40:32 PMluck! - on my machine it doesn't work.
Some people have luck winning the lottery. Other people manage to write programs that can run on multiple platforms. I am lucky in getting programs that work only on my computer.  :bg
Title: Re: I can't concatenate binary files
Post by: qWord on February 27, 2010, 12:07:44 AM
:bg
Quote from: Sergiu Funieru on February 26, 2010, 11:59:09 PM
How do I know how many bytes to allocate if I don't know the length of the file? Because to find the length of the file I need to read the entire file first.
use the size returned by fsize(). Theoretically (this also depends on the access flags) the file size can change between the call to fsize and fread() - thats why I've said to use the value returned by ReadFile. In your case fsize will work.
Title: Re: I can't concatenate binary files
Post by: Sergiu FUNIERU on February 27, 2010, 12:28:25 AM
Quote from: qWord on February 27, 2010, 12:07:44 AMTheoretically (this also depends on the access flags) the file size can change between the call to fsize and fread() - thats why I've said to use the value returned by ReadFile. In your case fsize will work.
Thank you! I tried what you said and it worked.

I changed
mov bwrt1, fwrite (hFile3, hMem1, len (hMem1))
into
mov bwrt1, fwrite (hFile3, hMem1, bwrt1)
Title: Re: I can't concatenate binary files
Post by: clive on February 27, 2010, 12:34:33 AM
Quote from: Sergiu Funieru on February 26, 2010, 11:59:09 PM
Because to find the length of the file I need to read the entire file first.

Not exactly, you should be able to fseek() to the end, and then use ftell(). It is not necessary to actually pull file data into memory to do this. And there are some more efficient Win32 methods to get the file size by querying the file handle into the file system.

Also as pointed out earlier you don't need the fseek() between the two fwrite()s. With my files systems hat on, I can tell you that fseek() is a very expensive call. It is useful if you are switch between reads and writes to a file stream, but it will act as a "fencing" operation and will flush all buffering to the media.

Ideally you should keep track of where the file pointer is, by tracking any fseek/fread/fwrite operations, and only use fseek() when required. Even a simple operation like :

if (ftell(f) != offset) fseek(f, offset, SEEK_SET);

can improve performance dramatically.

-Clive
Title: Re: I can't concatenate binary files
Post by: jj2007 on February 27, 2010, 09:08:18 AM
Quote from: clive on February 27, 2010, 12:34:33 AM
there are some more efficient Win32 methods to get the file size by querying the file handle into the file system.

see the get file size thread (http://www.masm32.com/board/index.php?topic=13425.0).

P.S.: For the lazybones:
include \masm32\MasmBasic\MasmBasic.inc

.code
start: Open "O", #1, "WinComplete.inc"
Print #1, FileRead$("\Masm32\include\Windows.inc"), FileRead$("\Masm32\include\WinExtra.inc")
Close
Exit
end start

Pure Massemblertm :wink
Title: Re: I can't concatenate binary files
Post by: hutch-- on February 27, 2010, 10:45:32 AM
The task itself is trivial, if the files are not massive (IE: gigabytes) and each file will fit into available memory you create a new file, open the first file and read it into memory then write it to the new file, without closing the new file, open the second and read it into memory and write it to the new file, close the new file handle and wait until the lazy write is finished unless you flush the file and its all done !
Title: Re: I can't concatenate binary files
Post by: aker on February 28, 2010, 03:38:07 AM
ReadFile+OpenFileMapping+SetFilePointer+WriteFile