How to Write to a Memory Buffer With a File*

How to write a file to a buffer memory in C

One way to do it would be to create a buffer that exactly fits the size of the file.
In order to do so, you can write a function to get the size of an openned file like so:

size_t get_file_size(FILE *f)
{
size_t pos = ftell(f); // store the cursor position
size_t size;

// go to the end of the file and get the cursor position
fseek(f, 0L, SEEK_END);
size = ftell(f);

// go back to the old position
fseek(f, pos, SEEK_SET);
return size;
}

Then create and fill your buffer:

FILE *f = fopen("your_file", "r");
size_t size = get_file_size(f);
char *buffer = malloc(size);

if (fread(buffer, 1, size, f) != size) { // bytes read != computed file size
// error handling
}

// use your buffer...

// don't forget to free and fclose
free(buffer);
fclose(f);

It is worth mentioning that you should check if the file was opened correctly, and to check if you have enough memory to store the buffer (the one created with malloc).

Edit:

As Andrew Henle said, fseek()/ftell() to get the size of a file is non-portable. Instead, to get the size of your file, you should use one of these techniques depending on your OS (assuming you are trying to open a 'normal' file):

On Linux / MacOS:

#include <sys/stat.h>

struct stat st;
size_t size;

if (stat("your_file", &st) != 0) {
// error handling...
}
size = st.st_size;

On Windows (as answered here) :

__int64 FileSize(const wchar_t* name)
{
HANDLE hFile = CreateFile(name, GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);

if (hFile == INVALID_HANDLE_VALUE)
return -1; // error condition, could call GetLastError to find out more

LARGE_INTEGER size;
if (!GetFileSizeEx(hFile, &size)) {
CloseHandle(hFile);
return -1; // error condition, could call GetLastError to find out more
}

CloseHandle(hFile);
return size.QuadPart;
}

Make a file pointer read/write to an in-memory location

If your operating system provides fmemopen,
probably it will meet your purpose.

Writing a file from memory in C

you should use 'fwrite' take the place of fpus

Send file writes to in-memory buffer (fopen something, but write to buffer, not disk)

Stdout is a basic file handle, which means its a pointer.

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

int main(int argc, char **argv);

int main (argc,argv)
int argc;
char **argv;
{
stdout = &(*stderr);
fprintf(stdout, "test");
return 0;
}

By declaring stdout to point to a different file handle, this program redirects stdout. To test it, compile it as test, and then type ./test > t and ./test 2> t on the command line.

The redirected stdout pipe will still output the word test, whereas the redirected stderr pipe will not.

Since files are streams, read this section of the GNU C Library for how to create memory streams. This example creates a text buffer to dynamically resize for holding input, and redirects stdout to point to it.

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

int main(int argc, char **argv);

int main (argc,argv)
int argc;
char **argv;
{
char *bp;
size_t size;
FILE *stream;

stream = open_memstream (&bp, &size);
stdout = &(*stream);
fprintf(stdout, "test");
fflush(stdout);
fprintf(stderr, "buf = %s, size = %d\n", bp, size);
fclose (stream);
free(bp);
return 0;
}

Pay careful attention to the sections on flushing the buffers when switching between input and output in the manual.

How to create a virtual file as a memory buffer

In Linux, there are anonymous, in-memory files that behave like regular ones and can be created using os.memfd_create() (Python 3.8 and higher).

>>> fd = os.memfd_create('test_file')
>>> os.write(fd, b'This is a test file\n')
nano /proc/[pid]/fd/[fd]
It automatically disappears if closed.
>>> os.lseek(fd, 0, os.SEEK_SET)
>>> os.read(fd, 0x100)
b'This is a test file\nIt automatically disappears if closed.\n'
>>> os.close(fd)

More information here:

  • man page: memfd_create()
  • python3 os module


Related Topics



Leave a reply



Submit