Re: how do I shorten a file?

new topic     » goto parent     » topic index » view thread      » older message » newer message

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

new topic     » goto parent     » topic index » view thread      » older message » newer message

Search



Quick Links

User menu

Not signed in.

Misc Menu