Re: how do I shorten a file?
- Posted by Kat <gertie at PELL.NET> Feb 08, 2002
- 498 views
On 8 Feb 2002, at 8:34, Irv Mullins wrote: > > On Friday 08 February 2002 07:13 am, Derek Parnell wrote: > > > daryl_vdb at HOTMAIL.COM wrote: > > > How can I delete bytes from the end of a file opened for update (or > > > write)? > > > > Unfortunately you can't do that in DOS/Windows/Linux systems. Instead, > > you have to copy the parts of the file you want to a new file, then > > delete the old file and then rename the new file with the original name. > > > > The seek() and where() statements help you navigate around a file but > > they don't influence shortening it, though seek() can be used to extend > > a file, I think. I haven't used so much file handling in Eu, so i really don't know how Eu does seek() and where(). I used way more file pointer manipulation in TP because it took forever to load big files in TP, leaving them in a ramdrive and manipulating pointers in dos was faster (80386DX, 4megs ram, circa 1994?). > Some languages (Pascal is one, I think) reserve a byte to indicate EOF. > You could do the same thing with Euphoria, but it's probably better to > do as Derek suggested. Yes, in dos, writing the EOF to the file at a position and then closing it. On subsequent reads, dos would stop at the new EOF (^Z). For this to work 100%, you must also flush all write buffers. However, turbo pascal for some time didn't allow using seek() in both text and binary files open for reading and writing, unless, of course, you wrote some assy language to get around that, using dos interrupts. Just another example of being throttled by the higher level language, and the extent some will go to make life easier in the long run.... it was like a goto for text file seeks in Turbo Pascal. { this unit is used to 1) determine the file position in a TEXT FILE ! 2) position the file pointer in a TEXT FILE ! } UNIT Textpos; (**) INTERFACE (**) USES Dos; FUNCTION TextfilePos(VAR F : Text) : LongInt; PROCEDURE TextSeek(VAR F : Text; SeekLoc : LongInt); FUNCTION TextFileSize(var F : Text) : LongInt; (**) IMPLEMENTATION (**) FUNCTION TextfilePos(VAR F : Text) : LongInt; VAR Adjust : Word; CurrPos : LongInt; BEGIN IF TextRec(F).Mode = fmclosed THEN BEGIN InOutRes := 103; {file not open} Exit; END; ASM MOV AH, 42h {move file pointer} MOV AL, 01h {relative to current position} XOR CX, CX XOR DX, DX {zero offset in CX:DX} LES DI, F MOV BX, ES:[DI] {first word is handle} INT 21h JNC @ok MOV InOutRes, AX RET @ok: MOV Word(@Result), AX MOV Word(@Result+2), DX {result is ready} LES DI, F {subtract unread portion of buffer from result} MOV BX, TextRec(ES:[DI]).BufEnd SUB BX, TextRec(ES:[DI]).BufPos SUB Word(@Result), BX SBB Word(@Result+2), 0 END; END; PROCEDURE TextSeek(VAR F : Text; SeekLoc : LongInt); VAR CurrPos : LongInt; BEGIN IF TextRec(F).Mode = fmclosed THEN BEGIN InOutRes := 103; { file not open } Exit; END; ASM MOV AH, 42h {"move file pointer"} MOV AL, 01h {relative to current position} XOR CX, CX XOR DX, DX {zero offset in CX:DX} LES DI, F MOV BX, ES:[DI] {first word is handle} INT 21h JNC @ok MOV InOutRes, AX RET @ok: MOV Word(CurrPos), AX MOV Word(CurrPos+2), DX {got current position} END; {-- IF the position we want is already --} {-- in the TextRec's buffer, use it! --} {-- Otherwise, seek to the desired spot --} Dec(CurrPos, TextRec(F).BufEnd); CurrPos := SeekLoc - CurrPos; IF (CurrPos >= 0) AND (CurrPos < TextRec(F).BufEnd) THEN TextRec(F).BufPos := CurrPos ELSE BEGIN ASM MOV AH, 42h {move file pointer} MOV AL, 0h {absolute from start of file} MOV CX, Word(SeekLoc+2) MOV DX, Word(SeekLoc) {location in CX:DX} LES DI, F MOV BX, ES:[DI] {first word is handle} INT 21h JNC @ok MOV InOutRes, AX RET @ok: END; TextRec(F).BufPos := 0; {must re-read buffer} TextRec(F).BufEnd := 0; END; END; FUNCTION TextFileSize(var F : Text) : LongInt; VAR CurrPos : LongInt; BEGIN IF TextRec(F).Mode = fmclosed THEN BEGIN InOutRes := 103; {file not open for input} Exit; END; {FIRST get current position} ASM MOV AH, 42h {move file pointer} MOV AL, 01h {relative to current position} XOR CX, CX XOR DX, DX {zero offset in CX:DX} LES DI, F MOV BX, ES:[DI] {first word is handle} INT 21h JNC @ok MOV InOutRes, AX RET @ok: MOV Word(CurrPos), AX MOV Word(CurrPos+2), DX {got current position} END; {SECOND move to end of file} ASM MOV AH, 42h {move file pointer} MOV AL, 02h {relative to end of file} XOR CX, CX XOR DX, DX {zero offset in CX:DX} LES DI, F MOV BX, ES:[DI] {first word is handle} INT 21h JNC @ok MOV InOutRes, AX RET @ok: MOV Word(@Result), AX MOV Word(@Result+2), DX {result is ready} END; {THIRD go back to where you were} ASM MOV AH, 42h {move file pointer} MOV AL, 0h {absolute from start of file} MOV CX, Word(CurrPos+2) MOV DX, Word(CurrPos) {location in CX:DX} LES DI, F MOV BX, ES:[DI] {first word is handle} INT 21h JNC @ok MOV InOutRes, AX RET @ok: END; END; END. Kat