0

So i got my function here that works to write back any file

    int write_file(FILE *f_write) {

    // Temp variables
    FILE *img = fopen("test.pdf", "wb");
    unsigned char buffer[255];
    
    while ( (bytes_read = fread(buffer, 1, sizeof(buffer), f_write) ) > 0) {
        fwrite(buffer, 1, bytes_read, img);
    }

    fclose(img);
    return 1;
}

So this works perfecly ive tried with pnj / pdf / jpg etc..

But now i want to stock what ive writen in the memory so i can use it later and not write right away

like an array of uint8_t (maybe) that will contain all the bytes ive writen and that i can send later with sockets to my server and store the file

no idea how to do it

Or maybe i'm making it too complicated and i can just

send(client_socket, FILE, sizeof(FILE), 0); ?

CPPSauce
  • 31
  • 5
  • 1
    Aside: it is initially confusing that you have the identifier of the file you are reading as `f_write`. – Weather Vane Jul 18 '22 at 13:10
  • Yeah ill change the identifier later, i was just checking if the function was writting properly at the start by writing to a new file but i need this function to store the data now and not write it – CPPSauce Jul 18 '22 at 13:16
  • 1
    Allocate a 0 sized buffer, reallocate it with each block, and copy the data to it. On success return the buffer pointer, on failure free what you have and return NULL. – Weather Vane Jul 18 '22 at 13:22
  • ...you would also need to know the size of the data in the buffer, so you might need a `struct` to contain the buffer base, its size, and the amount used. – Weather Vane Jul 18 '22 at 13:26
  • 1
    memory map the file – 0___________ Jul 18 '22 at 13:31
  • Do you know how to create an array; do you know how to read data from the file into the array? – user253751 Jul 18 '22 at 13:35

1 Answers1

1

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;
}
qdesmettre
  • 123
  • 6
  • 4
    `fseek()`/`ftell()` to get the size of a file is non-portable. Per [**7.21.9.4 The ftell function**, p2](http://www.port70.net/~nsz/c/c11/n1570.html#7.21.9.4p2): "... For a text stream, its file position indicator contains unspecified information, usable by the fseek function for returning the file position indicator for the stream to its position at the time of the ftell call; **the difference between two such return values is not necessarily a meaningful measure of the number of characters written or read.**" So you can't `ftell()` to get the size of a text file, like this answer is doing. – Andrew Henle Jul 18 '22 at 14:16
  • 4
    (cont) And for a binary stream, [**7.21.9.2 The fseek function**, p3:](http://www.port70.net/~nsz/c/c11/n1570.html#7.21.9.2p3): "A binary stream need not meaningfully support fseek calls with a whence value of SEEK_END." Per [footnote 268](http://www.port70.net/~nsz/c/c11/n1570.html#note268): "**Setting the file position indicator to end-of-file, as with fseek(file, 0, SEEK_END), has undefined behavior for a binary stream** (because of possible trailing null characters) or for any stream with state-dependent encoding that does not assuredly end in the initial shift state." – Andrew Henle Jul 18 '22 at 14:19