Truncating a binary file?
Moderators:Administrator, Global Moderator
-
- Jr. Member
- Posts:10
- Joined:Sat Feb 14, 2009 3:26 pm
- Location:New York, U.S.
This is for a VBDOS program but should work under QB4.5: How do I truncate a binary-mode file opened using OPEN?
HOW TO TRUNCATE A FILE USING MS-DOS INTERRUPTS FROM
BASIC (68159)
THE INFORMATION IN THIS ARTICLE APPLIES TO:
MICROSOFT VISUAL BASIC FOR MS-DOS 1.0
MICROSOFT QUICKBASIC FOR MS-DOS 4.0
MICROSOFT QUICKBASIC FOR MS-DOS 4.0B
MICROSOFT QUICKBASIC FOR MS-DOS 4.5
MICROSOFT BASIC COMPILER FOR MS-DOS AND OS/2 6.0
MICROSOFT BASIC COMPILER FOR MS-DOS AND OS/2 6.0B
MICROSOFT BASIC PROFESSIONAL DEVELOPMENT SYSTEM (PDS)
FOR MS-DOS 7.0
MICROSOFT BASIC PROFESSIONAL DEVELOPMENT SYSTEM (PDS)
FOR MS-DOS 7.1
THIS ARTICLE WAS PREVIOUSLY PUBLISHED UNDER Q68159
SUMMARY
THE FOLLOWING BASIC CODE SHOWS HOW TO TRUNCATE A
FILE USING MS-DOS FUNCTIONS. A MORE CLUMSY APPROACH
IN BASIC WOULD BE TO READ A SPECIFIED AMOUNT OF
RECORDS ONE AT A TIME, WRITING THESE RECORDS TO
ANOTHER FILE, DELETING THE FIRST FILE, AND THEN
RENAMING THE NEW FILE TO THE OLD FILE.
THE APPROACH USING MS-DOS FUNCTIONS (BELOW) IS
QUICKER AND MORE EFFICIENT. THE INFORMATION IN
THIS ARTICLE IS ALSO INCLUDED IN THE HELP FILE
PROVIDED WITH THE STANDARD AND PROFESSIONAL
EDITIONS OF MICROSOFT VISUAL BASIC FOR MS-DOS,
VERSION 1.0.
MORE INFORMATION
YOU CAN INVOKE MS-DOS SERVICE FUNCTIONS USING THE
CALL INTERRUPT STATEMENT IN BASIC.
YOU CAN SET THE SIZE OF ANY FILE TO ANY ARBITRARY
VALUE BY EXECUTING MS-DOS INTERRUPT 21H WITH
SERVICE 40H USING CX = 00H. THE USUAL TECHNIQUE
IS TO CALL SERVICE 42H TO SET THE FILE POINTER
LOCATION AND THEN IMMEDIATELY CALL SERVICE 40H
WITH CX = 00H TO UPDATE THE NEW FILE SIZE.
THE PROGRAM BELOW IS WRITTEN SO THAT THE TRUNCATE%
FUNCTION IS GENERIC AS POSSIBLE AND WORKS WITH ANY
FILE. PROCESSFILE() SETS UP THE FILE-SPECIFIC
INFORMATION, WHICH IN TURN CALLS THE TRUNCATE%
FUNCTION. TRUNCATE% GENERATES THE SPECIFIC INTERRUPT
CALLS TO TRUNCATE THE FILE AT THE SPECIFIED RECORD.
THE TWO SUB PROGRAMS PRINTFILE() AND CREATEFILE()
ARE ONLY NEEDED AS AN EXAMPLE.
PROGRAM EXAMPLE
TO TRY THIS EXAMPLE IN VBDOS.EXE:
FROM THE FILE MENU, CHOOSE NEW PROJECT.
COPY THE CODE EXAMPLE TO THE CODE WINDOW.
PRESS F5 TO RUN THE PROGRAM.
TO RUN THIS PROGRAM IN THE VBDOS.EXE ENVIRONMENT,
YOU MUST INVOKE THE VBDOS.EXE ENVIRONMENT WITH
THE /L SWITCH TO LOAD THE DEFAULT QUICK LIBRARY.
FOR EXAMPLE:
VBDOS.EXE /L
YOU MUST RUN QB OR QBX WITH THE /L OPTION TO LOAD
THE QB.QLB OR QBX.QLB QUICK LIBRARY WHICH CONTAINS
THE INTERRUPT ROUTINE USED IN THIS PROGRAM.
YOU MUST LINK WITH QB.LIB OR QBX.LIB WHEN MAKING
AN .EXE PROGRAM WHICH USES THE CALL INTERRUPT STATEMENT.
CONST NUMREC = 10
TYPE THETYPE
I AS INTEGER
END TYPE
DIM SHARED THEDIM AS THETYPE
' USE THE FOLLOWING INCLUDE FILE FOR VISUAL BASIC FOR MS-DOS:
REM $INCLUDE: 'VBDOS.BI'
' USE THE FOLLOWING INCLUDE FILE FOR QUICKBASIC FOR MS-DOS:
'$INCLUDE: 'QB.BI'
' USE THE FOLLOWING INCLUDE FILE FOR BASIC PDS FOR MS-DOS:
'$INCLUDE: 'QBX.BI'
CALL CREATEFILE
CALL PRINTFILE
CALL PROCESSFILE(7)
CALL PRINTFILE
'################### FILE SPECIFIC SUB #############################
SUB PROCESSFILE (LASTREC%)
' GET THE INFORMATION ABOUT "TEST.DAT" AND ALSO THE INFORMATION
' ABOUT THE LOCATION OF THE LASTREC% WHERE THE FILE WILL BE TRUNCATED.
OPEN "TEST.DAT" FOR RANDOM AS #1 LEN = LEN(THEDIM)
FILEPOINTER% = LASTREC% * LEN(THEDIM)
IF FILEPOINTER% <> TRUNCATE%(FILEATTR(1, 2), FILEPOINTER%) THEN
PRINT "ERROR..."
END IF
CLOSE
END SUB
'################## GENERIC INT FILE TRUNCATOR ####################
FUNCTION TRUNCATE% (HANDLE%, FILEPOINTER%)
' GENERIC FUNCTION THAT WILL TRUNCATE ANY FILE AT SPECIFIED OFFSET.
'
' RECEIVES:
' 1. A MS-DOS FILE HANDLE;
' 2. A FILE POINTER OFFSET IN BYTES, POINTING WHERE TO TRUNCATE
' RETURNS:
' 1. IF SUCCESSFUL, POSITION OF FILE POINTER; OR
' 2. IF ERROR, FLAGS REGISTER
'
DIM REGS AS REGTYPE
REGS.AX = &H4200 ' INT 21H, SERVICE 42H
REGS.BX = HANDLE% ' MS-DOS HANDLE
REGS.DX = FILEPOINTER% ' OFFSET IN BYTES FROM START.
CALL INTERRUPT(&H21, REGS, REGS)
IF REGS.AX <> FILEPOINTER% THEN ' AX RETURNS POINTER POSITION.
TRUNCATE% = REGS.FLAGS ' IF ERROR, RETURN FLAG.
END IF
REGS.AX = &H4000 ' INT 21H, SERVICE 40H
REGS.BX = HANDLE% ' MS-DOS HANDLE
REGS.CX = &H0
CALL INTERRUPT(&H21, REGS, REGS)
IF REGS.AX <> 0 THEN ' MUST BE ZERO BYTES WRITTEN.
TRUNCATE% = REGS.FLAGS ' IF ERROR, RETURN FLAG.
END IF
TRUNCATE% = FILEPOINTER% ' RETURN OFFSET LOCATION.
END FUNCTION
'############ CREATE SAMPLE FILE USING RANDOM ACCESS ################
SUB CREATEFILE
KILL "TEST.DAT"
OPEN "TEST.DAT" FOR RANDOM AS #1 LEN = LEN(THEDIM)
FOR J = 1 TO NUMREC
THEDIM.I = J
PUT #1, J, THEDIM
NEXT J
CLOSE #1
END SUB
'########### PRINT CONTENTS OF TEST.DAT ##################
SUB PRINTFILE
OPEN "TEST.DAT" FOR RANDOM AS #1 LEN = LEN(THEDIM)
MAX = LOF(1) / LEN(THEDIM)
FOR J = 1 TO MAX
GET #1, J, THEDIM
PRINT THEDIM.I
NEXT J
CLOSE
END SUB
REFERENCES
MORE INFORMATION ON THE USE OF CALL INTERRUPT
STATEMENT CAN BE FOUND UNDER THE CALL STATEMENT
IN THE LANGUAGE REFERENCE MANUAL OR ONLINE HELP.
FOR MORE INFORMATION ON HOW TO USE CALL INTERRUPT
STATEMENT, QUERY ON THE FOLLOWING WORDS IN THE
MICROSOFT KNOWLEDGE BASE:
CALL AND INTERRUPT AND APPLICATION AND NOTE AND QUICKBASIC
MODIFICATION TYPE: MINOR
LAST REVIEWED: 1/9/2003
KEYWORDS: KB68159
(C)2002 MICROSOFT CORPORATION. ALL RIGHTS RESERVED.
BASIC (68159)
THE INFORMATION IN THIS ARTICLE APPLIES TO:
MICROSOFT VISUAL BASIC FOR MS-DOS 1.0
MICROSOFT QUICKBASIC FOR MS-DOS 4.0
MICROSOFT QUICKBASIC FOR MS-DOS 4.0B
MICROSOFT QUICKBASIC FOR MS-DOS 4.5
MICROSOFT BASIC COMPILER FOR MS-DOS AND OS/2 6.0
MICROSOFT BASIC COMPILER FOR MS-DOS AND OS/2 6.0B
MICROSOFT BASIC PROFESSIONAL DEVELOPMENT SYSTEM (PDS)
FOR MS-DOS 7.0
MICROSOFT BASIC PROFESSIONAL DEVELOPMENT SYSTEM (PDS)
FOR MS-DOS 7.1
THIS ARTICLE WAS PREVIOUSLY PUBLISHED UNDER Q68159
SUMMARY
THE FOLLOWING BASIC CODE SHOWS HOW TO TRUNCATE A
FILE USING MS-DOS FUNCTIONS. A MORE CLUMSY APPROACH
IN BASIC WOULD BE TO READ A SPECIFIED AMOUNT OF
RECORDS ONE AT A TIME, WRITING THESE RECORDS TO
ANOTHER FILE, DELETING THE FIRST FILE, AND THEN
RENAMING THE NEW FILE TO THE OLD FILE.
THE APPROACH USING MS-DOS FUNCTIONS (BELOW) IS
QUICKER AND MORE EFFICIENT. THE INFORMATION IN
THIS ARTICLE IS ALSO INCLUDED IN THE HELP FILE
PROVIDED WITH THE STANDARD AND PROFESSIONAL
EDITIONS OF MICROSOFT VISUAL BASIC FOR MS-DOS,
VERSION 1.0.
MORE INFORMATION
YOU CAN INVOKE MS-DOS SERVICE FUNCTIONS USING THE
CALL INTERRUPT STATEMENT IN BASIC.
YOU CAN SET THE SIZE OF ANY FILE TO ANY ARBITRARY
VALUE BY EXECUTING MS-DOS INTERRUPT 21H WITH
SERVICE 40H USING CX = 00H. THE USUAL TECHNIQUE
IS TO CALL SERVICE 42H TO SET THE FILE POINTER
LOCATION AND THEN IMMEDIATELY CALL SERVICE 40H
WITH CX = 00H TO UPDATE THE NEW FILE SIZE.
THE PROGRAM BELOW IS WRITTEN SO THAT THE TRUNCATE%
FUNCTION IS GENERIC AS POSSIBLE AND WORKS WITH ANY
FILE. PROCESSFILE() SETS UP THE FILE-SPECIFIC
INFORMATION, WHICH IN TURN CALLS THE TRUNCATE%
FUNCTION. TRUNCATE% GENERATES THE SPECIFIC INTERRUPT
CALLS TO TRUNCATE THE FILE AT THE SPECIFIED RECORD.
THE TWO SUB PROGRAMS PRINTFILE() AND CREATEFILE()
ARE ONLY NEEDED AS AN EXAMPLE.
PROGRAM EXAMPLE
TO TRY THIS EXAMPLE IN VBDOS.EXE:
FROM THE FILE MENU, CHOOSE NEW PROJECT.
COPY THE CODE EXAMPLE TO THE CODE WINDOW.
PRESS F5 TO RUN THE PROGRAM.
TO RUN THIS PROGRAM IN THE VBDOS.EXE ENVIRONMENT,
YOU MUST INVOKE THE VBDOS.EXE ENVIRONMENT WITH
THE /L SWITCH TO LOAD THE DEFAULT QUICK LIBRARY.
FOR EXAMPLE:
VBDOS.EXE /L
YOU MUST RUN QB OR QBX WITH THE /L OPTION TO LOAD
THE QB.QLB OR QBX.QLB QUICK LIBRARY WHICH CONTAINS
THE INTERRUPT ROUTINE USED IN THIS PROGRAM.
YOU MUST LINK WITH QB.LIB OR QBX.LIB WHEN MAKING
AN .EXE PROGRAM WHICH USES THE CALL INTERRUPT STATEMENT.
CONST NUMREC = 10
TYPE THETYPE
I AS INTEGER
END TYPE
DIM SHARED THEDIM AS THETYPE
' USE THE FOLLOWING INCLUDE FILE FOR VISUAL BASIC FOR MS-DOS:
REM $INCLUDE: 'VBDOS.BI'
' USE THE FOLLOWING INCLUDE FILE FOR QUICKBASIC FOR MS-DOS:
'$INCLUDE: 'QB.BI'
' USE THE FOLLOWING INCLUDE FILE FOR BASIC PDS FOR MS-DOS:
'$INCLUDE: 'QBX.BI'
CALL CREATEFILE
CALL PRINTFILE
CALL PROCESSFILE(7)
CALL PRINTFILE
'################### FILE SPECIFIC SUB #############################
SUB PROCESSFILE (LASTREC%)
' GET THE INFORMATION ABOUT "TEST.DAT" AND ALSO THE INFORMATION
' ABOUT THE LOCATION OF THE LASTREC% WHERE THE FILE WILL BE TRUNCATED.
OPEN "TEST.DAT" FOR RANDOM AS #1 LEN = LEN(THEDIM)
FILEPOINTER% = LASTREC% * LEN(THEDIM)
IF FILEPOINTER% <> TRUNCATE%(FILEATTR(1, 2), FILEPOINTER%) THEN
PRINT "ERROR..."
END IF
CLOSE
END SUB
'################## GENERIC INT FILE TRUNCATOR ####################
FUNCTION TRUNCATE% (HANDLE%, FILEPOINTER%)
' GENERIC FUNCTION THAT WILL TRUNCATE ANY FILE AT SPECIFIED OFFSET.
'
' RECEIVES:
' 1. A MS-DOS FILE HANDLE;
' 2. A FILE POINTER OFFSET IN BYTES, POINTING WHERE TO TRUNCATE
' RETURNS:
' 1. IF SUCCESSFUL, POSITION OF FILE POINTER; OR
' 2. IF ERROR, FLAGS REGISTER
'
DIM REGS AS REGTYPE
REGS.AX = &H4200 ' INT 21H, SERVICE 42H
REGS.BX = HANDLE% ' MS-DOS HANDLE
REGS.DX = FILEPOINTER% ' OFFSET IN BYTES FROM START.
CALL INTERRUPT(&H21, REGS, REGS)
IF REGS.AX <> FILEPOINTER% THEN ' AX RETURNS POINTER POSITION.
TRUNCATE% = REGS.FLAGS ' IF ERROR, RETURN FLAG.
END IF
REGS.AX = &H4000 ' INT 21H, SERVICE 40H
REGS.BX = HANDLE% ' MS-DOS HANDLE
REGS.CX = &H0
CALL INTERRUPT(&H21, REGS, REGS)
IF REGS.AX <> 0 THEN ' MUST BE ZERO BYTES WRITTEN.
TRUNCATE% = REGS.FLAGS ' IF ERROR, RETURN FLAG.
END IF
TRUNCATE% = FILEPOINTER% ' RETURN OFFSET LOCATION.
END FUNCTION
'############ CREATE SAMPLE FILE USING RANDOM ACCESS ################
SUB CREATEFILE
KILL "TEST.DAT"
OPEN "TEST.DAT" FOR RANDOM AS #1 LEN = LEN(THEDIM)
FOR J = 1 TO NUMREC
THEDIM.I = J
PUT #1, J, THEDIM
NEXT J
CLOSE #1
END SUB
'########### PRINT CONTENTS OF TEST.DAT ##################
SUB PRINTFILE
OPEN "TEST.DAT" FOR RANDOM AS #1 LEN = LEN(THEDIM)
MAX = LOF(1) / LEN(THEDIM)
FOR J = 1 TO MAX
GET #1, J, THEDIM
PRINT THEDIM.I
NEXT J
CLOSE
END SUB
REFERENCES
MORE INFORMATION ON THE USE OF CALL INTERRUPT
STATEMENT CAN BE FOUND UNDER THE CALL STATEMENT
IN THE LANGUAGE REFERENCE MANUAL OR ONLINE HELP.
FOR MORE INFORMATION ON HOW TO USE CALL INTERRUPT
STATEMENT, QUERY ON THE FOLLOWING WORDS IN THE
MICROSOFT KNOWLEDGE BASE:
CALL AND INTERRUPT AND APPLICATION AND NOTE AND QUICKBASIC
MODIFICATION TYPE: MINOR
LAST REVIEWED: 1/9/2003
KEYWORDS: KB68159
(C)2002 MICROSOFT CORPORATION. ALL RIGHTS RESERVED.
MY PAGE: HTTP://BASIC.PHATCODE.NET
Re: Truncating a binary file?
The easiest way would be to open as binary, read in the entire file or the part you want to put out as the file, close the file, reopen as output and print to the file (ending with a semicolon) then, of course, close the file.