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?
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
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/
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.
Doesn't it take any parameters ? (I don't use masm)
You need to open with the "rb" flags
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)
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)
Here is a little cmd bonus for Sergiu, since he likes that stuff :
copy 1.txt+2.txt 3.txt
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.
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
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.
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.
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
: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.
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)
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
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 Massembler
tm :wink
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 !
ReadFile+OpenFileMapping+SetFilePointer+WriteFile