[comp.lang.c] Truncate a File?

rose@galtee.cs.wisc.edu (Barney Frank) (07/30/90)

I have a requirement to adjust the length of a data file.

1. Open the file for read and write.
2. Archive the earliest information in the file to another file system.
3. Move the latest information to the head of the file.
4. Ask the operating system to adjust the size of the file down to the new
	"high-water" mark.

  It is not sufficient to make a temporary copy of the section of
interest, unlink the original file, and rename the temporary, because
the size of the file is of the same order of that of the file system.
Specifically, what I need to do is

This sounds like a pretty elementary operation to me, but I'll be
damned if I can find a system call to do anything to the size of a
file other than just move it down to zero.  One can envision some
pretty complicated schemes involving reading and writing the FAT
directly, but such schemes lack portability and have the potential to
run afoul of various caching schemes.  Yet I know that it can be done,
because I am aware of at least one program that is able to pack a data
file in-place in this fashion.

Right now, I am thinking of falling back to a fixed file length
scheme- that is, to allocate a file as large as I can afford, never
adjust the size, and use an alternative data structure to keep track
of the high-water point.  I'd be very happy to hear any suggestions
that allow me to avoid this, though.  Thanks in advance.

	-Scott Rose
--
	Scott Rose
	rose@cs.wisc.edu

Ralf.Brown@B.GP.CS.CMU.EDU (07/31/90)

In article <10914@spool.cs.wisc.edu>, rose@galtee.cs.wisc.edu (Barney Frank) wrote:
}I have a requirement to adjust the length of a data file.
}
}4. Ask the operating system to adjust the size of the file down to the new
}        "high-water" mark.
}
}  It is not sufficient to make a temporary copy of the section of
}interest, unlink the original file, and rename the temporary, because
}the size of the file is of the same order of that of the file system.
}This sounds like a pretty elementary operation to me, but I'll be
}damned if I can find a system call to do anything to the size of a
}file other than just move it down to zero.  One can envision some

Ever since DOS 1.00, a WRITE of *zero* bytes has set the file size to the
current file position.	So, for example:

	mov	  ax,4200h
	mov	  bx,handle
	mov	  cx,0
	mov	  dx,1234h
	int	  21h
	mov	  ah,40h
	mov	  bx,handle
	xor	  cx,cx
	int	  21h

will set the size of the file corresponding to 'handle' to 1234h bytes.

--
UUCP: {ucbvax,harvard}!cs.cmu.edu!ralf -=- 412-268-3053 (school) -=- FAX: ask
ARPA: ralf@cs.cmu.edu  BIT: ralf%cs.cmu.edu@CMUCCVMA  FIDO: 1:129/3.1
Disclaimer?    |   I was gratified to be able to answer promptly, and I did.
What's that?   |   I said I didn't know.  --Mark Twain

pabres13@pc.usl.edu (Joubert John V.) (08/01/90)

In article <10914@spool.cs.wisc.edu> rose@galtee.cs.wisc.edu (Barney Frank) writes:
>I have a requirement to adjust the length of a data file.
>
>1. Open the file for read and write.
>2. Archive the earliest information in the file to another file system.
>3. Move the latest information to the head of the file.
>4. Ask the operating system to adjust the size of the file down to the new
>	"high-water" mark.
>
>  It is not sufficient to make a temporary copy of the section of
>interest, unlink the original file, and rename the temporary, because
>the size of the file is of the same order of that of the file system.
>Specifically, what I need to do is
>
>This sounds like a pretty elementary operation to me, but I'll be
>damned if I can find a system call to do anything to the size of a
>file other than just move it down to zero.  One can envision some
>pretty complicated schemes involving reading and writing the FAT
>directly, but such schemes lack portability and have the potential to
>run afoul of various caching schemes.  Yet I know that it can be done,
>because I am aware of at least one program that is able to pack a data
>file in-place in this fashion.
>
>Right now, I am thinking of falling back to a fixed file length
>scheme- that is, to allocate a file as large as I can afford, never
>adjust the size, and use an alternative data structure to keep track
>of the high-water point.  I'd be very happy to hear any suggestions
>that allow me to avoid this, though.  Thanks in advance.
>
>	-Scott Rose
>--
>	Scott Rose
>	rose@cs.wisc.edu


Scott, if you have access to Microsoft C Quick C 2.0, use the following 
program. I have used it myself for the very same reason that you were 
discussing. This is written using the Quick 2.0 libraries, but I would suspect
that there would be equivalent calls in MSC 5.1 and 6.0.

The summary and description of the chsize function were pasted from the on-line
help area of Quick C.


#include <fcntl.h>

main()
{
        int fhandle;
        long fsize=1024L;

        fhandle=open("fname",O_BINARY|O_RDWR);

        if(fhandle<0) {
                printf("\nCould not get file\n");
                exit(0); }
        if(chsize(fhandle,fsize)<0)
                printf("\nCouldn't change size\n");
        else
                printf("FILE CONVERTED TO NEW SIZE \n");
        close(fhandle);
}


SUMMARY OF CHSIZE

Include:    <io.h>

Prototype:  int chsize(int handle, long size);

Returns:    0 if the size change is successful, or -1 if it is not.
            errno:  EACCES, EBADF, ENOSPC

See also:   close, creat, open

DESCRIPTION OF CHSIZE
The chsize function extends or truncates the file associated with handle to
the length specified by size. The file must be open in a mode that permits
writing. Null characters ('\0') are appended if the file is extended. If the
file is truncated, all data from the end of the shortened file to the
original length of the file are lost.

Return Value
The chsize function returns the value 0 if the file size is successfully
changed. A return value of -1 indicates an error, and errno is set to one of
the following values: EACCES, EBADF, ENOSPC



-- 
John Joubert                                      |  /\  |    /\    |     _ 
Internet: pabres13@pc.usl.edu                     |  \|<>|>|> \|<>|>|><`|`|
GENIE: J.JOUBERT                                  |--/|-------/|------------
                                                  |  \/       \/