简体   繁体   English

带有 fseek 的 open_memstream 以用零结束填充缓冲区

[英]open_memstream with fseek to end pads buffer with zeros

I using some C code that writes binary data to a file.我使用一些将二进制数据写入文件的 C 代码。 In the process, it seeks around to different positions and then finally seeks to the end with fseeko(fp, 0, SEEK_END);在这个过程中,它会四处寻找不同的位置,最后用fseeko(fp, 0, SEEK_END);寻找到最后fseeko(fp, 0, SEEK_END); . .

However, in some cases, I want to work on a stream in memory instead.但是,在某些情况下,我想在内存中处理流。 I use open_memstream for this, but seeking to the end pads the buffer with zeros and it ends up being twice as big as it should be.为此,我使用了open_memstream ,但最终用零open_memstream缓冲区,最终它的大小是应有的两倍。

An example just to demonstrate the effect of the fseek to the end of the stream is below.下面是一个示例,用于演示fseek到流末尾的效果。 In the actual code, we also fseek to different parts of the stream, patching and editing bits of it, etc., as the stream is processed.在实际代码中,随着流的处理,我们还会对流的不同部分进行fseek ,修补和编辑它的位等。 Note also that writing the file at the end to the filesystem is just for demonstration to show the contents of the buffer – otherwise I wouldn't need the memory stream.另请注意,将文件最后写入文件系统只是为了演示以显示缓冲区的内容——否则我将不需要内存流。

#include <stdio.h>
#include <stdlib.h>

#if (defined(BSD) || __APPLE__)
#include "open_memstream.h"
#endif

int main(void) {
    FILE *stream;
    FILE *outfile;
    char *buf;
    size_t buf_len;
    int i;

    stream = open_memstream(&buf, &buf_len);

    for(i = 0; i < 1000; i++) {
        fprintf(stream, "%d\n", i);
    }

    fseeko(stream, 0, SEEK_END);

    fclose(stream);

    outfile = fopen("out.txt", "w");
    fwrite(buf, buf_len, 1, outfile);
    fclose(outfile);

    return 0;
}

I was testing this out on Mac OS X with this implementation of open_memstream and it worked as I expected, but when I run this on Linux the file is twice the size with zeros at the end.我在 Mac OS X 上使用open_memstream实现对此进行了open_memstream ,它按我的预期工作,但是当我在 Linux 上运行它时,文件的大小是open_memstream两倍,最后是零。

What's the best way to deal with this?处理这个问题的最佳方法是什么? I'm not sure if it's reliable to divide the buffer length by two and truncate it.我不确定将缓冲区长度除以二并截断它是否可靠。

I've just ran into the same problem on Linux.我刚刚在 Linux 上遇到了同样的问题。

// It seams that SEEK_END does not work with open_memstream()
fseek(stream, 0, SEEK_END);

I've ended up doing this:我最终这样做了:

off_t o = ftell(stream);
/* do some things with the stream */
fseek(stream, o, SEEK_SET);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM