C Delete last n characters from file

2019-05-02 12:05发布

问题:

I need to delete the last n characters from a file using C code. At fist I was trying to use '\b', but it returns a Segmentation Fault. I have seen interesting answers to similar questions here and here, but I would prefer to use mmap function to do this, if it's possible. I know it could be simpler to truncate the file by creating a temp file, and writing chars to temp until some offset of the original file. The problem is I don't seem to understand how to use mmap function to do this, can't see what parameters I need to pass to that function, specially address, length and offset. From what I've read, I should use MAP_SHARED in flags and PROT_READ|PROT_WRITE in protect.

The function definition says:

void * mmap (void *address, size_t length, int protect, int flags, int filedes, off_t offset)

Here is my main:

int main(int argc, char * argv[])
{
    FILE * InputFile;
    off_t position;
        int charsToDelete;

    if ((InputFile = fopen(argv[1],"r+")) == NULL)
    {
            printf("tdes: file not found: %s\n",argv[1]);
    }
    else
    {
                charsToDelete = 5;
        fseeko(InputFile,-charsToDelete,SEEK_END);
        position = ftello(InputFile);
        printf("Pos: %d\n",(int)position);
        int i;
        //for(i = 0;i < charsToDelete;i++)
        //{
        //  putc(InputFile,'\b');
        //}
    }
    fclose(InputFile);
    return 0;
}

回答1:

Why not use:

   #include <unistd.h>
   #include <sys/types.h>

   int truncate(const char *path, off_t length);
   int ftruncate(int fd, off_t length);

like for instance:

    charsToDelete = 5;
    fseeko(InputFile,-charsToDelete,SEEK_END);
    position = ftello(InputFile);
    ftruncate(fileno(InputFile), position);


回答2:

Read all but n bytes from the file and write to a temporary file, close the original file, rename temporary file as original file.

Or use e.g. truncate or similar function if you have it.


Also, failure to open the file doesn't have to be that it can't be found, You should check errno on failure to see what the error is. Use e.g. strerror to get a printable string from the error code.



回答3:

Unfortunately, mmap does not allow you to change size of underlying file object.

Instead, I would recommend to simply truncate your file, use something like this:

truncate(filename, new_length);