我可以使用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
确实。
答案 0 :(得分:24)
如果您的操作系统提供fmemopen, 可能它会满足你的目的。
答案 1 :(得分:4)
在C ++中(并且您添加了C ++标记),您可以编写一个接受任意输入/输出流的函数。由于std::stringstream
或std::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::istream
和std::ostream
而不是低级C FILE *对象,那么C ++可以方便地提供std::istringstream
和std::ostringstream
来读/写字符串。
你会注意到,C中几乎所有以“f”开头且对文件进行操作的函数都有以“s”开头的等价字符,这些函数以字符串形式运行。一种可能更好的方法是为I / O设计一个非特定于文件或字符串的接口,然后分别提供连接到文件和字符串的实现。然后根据此接口实现核心逻辑,而不是低级C和C ++ I / O。这样做的好处还包括允许未来的扩展,例如支持内置支持压缩,复制等的网络文件。
答案 3 :(得分:0)
使用内存映射文件。这是特定于平台的,因此您需要找到有关在目标系统上创建mem映射文件的信息。我相信posix版本是mmap
。无论如何,在谷歌上搜索“内存映射文件”应该会有很多帮助。