pwrite()在C / C ++中对文件的问题

时间:2011-05-21 11:18:38

标签: c++ linux

我的问题很糟糕。我正在尝试通过filedescriptor和memalign写入文件。我可以写它,但只有像错误的编码字符一样写入文件。

这是我的代码:

fdOutputFile = open(outputFile, O_CREAT | O_WRONLY | O_APPEND | O_DIRECT, 0644)

void writeThis(char* text) {
    while (*text != '\0') {
        // if my internal buffer is full -> write to disk
        if (buffPositionOutput == outputbuf.st_blksize) {
            posix_memalign((void **)&bufferO, outputbuf.st_blksize, outputbuf.st_blksize);

            cout << "wrote " << pwrite(fdOutputFile, bufferO, outputbuf.st_blksize, outputOffset*outputbuf.st_blksize) << " Bytes to disk." << endl;
            buffPositionOutput = 0;
            ++outputOffset;
        }

        // buffer the incoming text...
        bufferO[buffPositionOutput] = *text;
        ++text;
        ++buffPositionOutput;
    }
}

我认为这是一致的 - 有人可以帮助我吗? 它写入文件但不是正确的文本,只是一堆'[]' - 字符。

提前感谢您的帮助!

3 个答案:

答案 0 :(得分:1)

查看您的计划,会发生以下情况:

  1. 你填充buffer0+buffPositionOutput最初指向的内存(确切地说是哪里?我根据你提供的代码不知道。)最多buffer0+outputbuf.st_blksize包含数据。
  2. buffer0指针的地址传递给posix_memalign,忽略其当前值并用指向新outputbuf.st_blksize字节的新分配内存的指针覆盖它。
  3. 您将数据从新分配的块写入磁盘;这可能是任何事情,因为你刚刚分配了内存并且还没有写任何内容。
  4. 显然这不起作用。您可能希望通过函数顶部的posix_memalign初始化缓冲区,然后在使用对齐缓冲区重复将数据写入文件时覆盖块中的数据。 (每次写入数据后,将buffpositionoutput重置为零,但不要重新分配。)确保在完成后free缓冲区。

    另外,为什么使用pwrite代替write

    以下是我将如何实施writeThis(保留您的变量名称,以便您可以将其与您的版本相匹配):

    void writeThis(char *text) {
        char *buffer0;
        size_t buffPositionOutput = 0;
        posix_memalign(&buffer0, outputbuf.st_blksize, outputbuf.st_blksize);
        while (*text != 0) {
            ++text; ++buffPositionOutput;
            if (buffPositionOutput == outputbuf.st_blksize) {
                write(fdOutputFile, buffer0, outputbuf.st_blksize);
                buffPositionOuput = 0;
            }
        }
        if (buffPositionOutput != 0) {
            // what do you want to do with a partial block of data?  Not sure.
        }
    }
    

    (为了速度,您可以考虑使用memcpy调用而不是循环。您需要知道要提前写入的数据的长度。在您有一个可行的解决方案之后担心这个问题没有泄漏记忆。)

答案 1 :(得分:1)

每次尝试输出时都会重新分配buffer0,而不是释放它。这真的不高效(并且泄漏内存)。我建议你稍微重构一下你的代码,因为很难确定你检查缓冲区的边界是否正确。

仅在某个位置分配buffer0一次(形成该片段,将其存储在outputbuf听起来像个好主意)。还将buffPositionOutput存储在该结构中(或在另一个结构中,但接近该缓冲区)。

// in setup code
int rc = posix_memalign(&(outputbuf.data), outputbuf.st_blksize,
                                           outputbuf.st_blksize);
// check rc!
outputbuf.writePosition = 0;
// in cleanup code
free(outputbuf.data);

然后你可以像这样重写你的功能:

void writeThis(char *text) {
   while (*text != 0) {
     outputbuf.data[outputbuf.writePosition] = *text;
     outputbuf.writePosition++;
     text++;
     if (outputbuf.writePosition == outputbuf.block_size) {
        int rc = pwrite(...);
        // check rc!
        std::cout << ...;
        outputbuf.writePosition = 0;
     }
 }

答案 2 :(得分:0)

我不认为C / C ++有编码。仅限ASCII。 除非你使用wchar http://en.wikipedia.org/wiki/Wide_character