Question

I have to implement a buffered writer with C++ on linux. Now I've got a problem: I can write characters to a file, but in addition, the file is filled with invalid characters (in gedit the file is filled with \00 after the real characters).

Here's a part of the code:

BufferedWriter::BufferedWriter(const char* path) {
    pagesize = getpagesize();
    if ((fd = open(path, O_WRONLY | O_DIRECT | O_CREAT | O_TRUNC, S_IRWXU))
        == -1) {
        perror("BufferedWriter: Error while opening file");
        throw -1;
    }
    if (posix_memalign((void**) &buffer, pagesize, pagesize) != 0) {
        perror("BufferedWriter: Error while allocating memory");
        throw -3;
    }
    for (int i = 0; i < pagesize; i++) {
        buffer[i] = 0;
    }
    charCnt = 0;
}

...

void BufferedWriter::writeChar(char c) {
    buffer[charCnt] = c;
    charCnt++;
    if (charCnt == pagesize) {
        if (write(fd, buffer, pagesize) == -1) {
            perror("BufferedWriter: Error while writing to file");
            throw -5;
        }
        for (int i = 0; i < pagesize; i++) {
            buffer[i] = 0;
        }
        charCnt = 0;
     }
}

When I initialize my buffer e.g. with whitespaces, it all works fine, but is there another way to prevent the "invalid characters"?

Thanks for helping me

Was it helpful?

Solution

Because you're using O_DIRECT, you're apparently forced to write in pagesize increments. However, that implies your file will always be padded out to a multiple of pagesize. In your current code, it will be padded with zeros, because you zero the page each time before filling it.

One way to address this is to track the actual amount of data that should be in the file, and ftruncate() the file to the desired size before closing it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top