使文件指针读/写到内存中的位置

时间:2011-02-27 20:49:29

标签: c++ c

我可以使用fopen()将文件指针写入文件。但是我可以创建一个文件指针,这样调用fputc或fprintf之类的函数会写入内存中的指针吗?这方面的一个例子是java中的ByteArrayOutputStream。另外:我可以反过来运行它,其中库需要一个文件指针来读取,所以我分配内存,并创建一个新的文件指针,将从该内存位置读取,但当块的大小用完时返回EOF? (如Java中的ByteArrayInputStream)。有没有办法在C中这样做?例如:

FILE *p = new_memory_file_pointer();
fprintf(p, "Hello World!\n");
char *data = get_written_stuff(p);
printf("%s", data); //will print Hello World!

&安培;&安培; / ||

char s[] = "Hello World!\n";
FILE *p = new_memory_file_pointer_read(s, sizeof(s));
char *buffer = (char *)malloc( 1024*sizeof(char) );
fread((void *)buffer, 1, sizeof(s), p);
printf("%s", buffer); //prints Hello World!

编辑:对于那些多年后阅读此问题的人,除了接受的答案外,您应该查看open_memstream(3),其行为更像这些Java类而不是fmemopen确实。

4 个答案:

答案 0 :(得分:24)

如果您的操作系统提供fmemopen, 可能它会满足你的目的。

答案 1 :(得分:4)

在C ++中(并且您添加了C ++标记),您可以编写一个接受任意输入/输出流的函数。由于std::stringstreamstd::ofstream是派生类,因此您可以将它们均等地传递给此函数。一个例子:

#include <iostream> // for std::cout
#include <fstream> // for std::ofstream
#include <sstream> // for std::stringstream

void write_something(std::ostream& stream) {
  stream << "Hello World!" << std::endl;
}

int main() {
  write_something(std::cout); // write it to the screen
  {
    std::ofstream file("myfile.txt");
    write_something(file); // write it into myfile.txt
  }
  {
    std::stringstream stream;
    write_something(stream); // write it into a string
    std::cout << stream.str() << std::endl; // and how to get its content
  }
}

类似于std::istream而不是std::ostream,如果您想要阅读数据:

void read_into_buffer(std::istream& stream, char* buffer, int length) {
  stream.read(buffer, length);
}

int main() {
  char* buffer = new char[255];

  {
    std::ifstream file("myfile.txt");
    read_into_buffer(file, buffer, 10); // reads 10 bytes from the file
  }
  {
    std::string s("Some very long and useless message and ...");
    std::stringstream stream(s);
    read_into_buffer(stream, buffer, 10); // reads 10 bytes from the string
  }
}

答案 2 :(得分:3)

正如Ise恰当地指出的那样,fmemopen中的POSIX 2008有一个函数,并且在Linux上受支持。使用POSIX 2004,可能最接近的是使用临时文件:

// This is for illustration purposes only. You should add error checking to this.
char name[] = "/tmp/name-of-app-XXXXXX";
int temporary_descriptor = mkstemp(name);
unlink(temporary_descriptor);
FILE* file_pointer = fdopen(temporary_descriptor, "r+");
// use file_pointer ...

反向更容易;也就是说,要有一个写入内存的函数,然后使用它来写入内存并写入文件。您可以使用mmap以便一大块内存最终由文件支持,并且写入该内存会将数据写入关联文件。

如果使用std::istreamstd::ostream而不是低级C FILE *对象,那么C ++可以方便地提供std::istringstreamstd::ostringstream来读/写字符串。

你会注意到,C中几乎所有以“f”开头且对文件进行操作的函数都有以“s”开头的等价字符,这些函数以字符串形式运行。一种可能更好的方法是为I / O设计一个非特定于文件或字符串的接口,然后分别提供连接到文件和字符串的实现。然后根据此接口实现核心逻辑,而不是低级C和C ++ I / O。这样做的好处还包括允许未来的扩展,例如支持内置支持压缩,复制等的网络文件。

答案 3 :(得分:0)

使用内存映射文件。这是特定于平台的,因此您需要找到有关在目标系统上创建mem映射文件的信息。我相信posix版本是mmap。无论如何,在谷歌上搜索“内存映射文件”应该会有很多帮助。