C++ Make a file of a specific size
Asked Answered
T

3

12

Here is my current problem: I am trying to create a file of x MB in C++. The user will enter in the file name then enter in a number between 5 and 10 for the size of the file they want created. Later on in this project i'm gonna do other things with it but I'm stuck on the first step of creating the darn thing.

My problem code (so far):

        char empty[1024];
        for(int i = 0; i < 1024; i++)
        {
            empty[i] = 0;
        }

        fileSystem = fopen(argv[1], "w+");


        for(int i = 0; i < 1024*fileSize; i++){
            int temp = fputs(empty, fileSystem);
            if(temp > -1){
                //Sucess!
            }
            else{
                cout<<"error"<<endl;
            }
        }

Now if i'm doing my math correctly 1 char is 1byte. There are 1024 bytes in 1KB and 1024KB in a MB. So if I wanted a 2 MB file, i'd have to write 1024*1024*2 bytes to this file. Yes?

I don't encounter any errors but I end up with an file of 0 bytes... I'm not sure what I'm doing wrong here so any help would be greatly appreciated!

Thanks!

Trimeter answered 25/10, 2011 at 21:19 Comment(4)
How do you think fputs knows how many bytes to write?Micropyle
fwrite, or seek/putc('0') will be your easiest bet.Honeydew
Don't forget to handle errors (e.g. check argc)Injection
@MooingDuck: I think the teacher will take a red marker, and correct putc('0') into putc(0) or putc('\0'). At which time, the student should take the red marker, and strongly cross out the ++ signs appearing in the name of this course :)Injection
I
24

Potentially sparse file

This creates output.img of size 300 MB:

#include <fstream>

int main()
{
    std::ofstream ofs("ouput.img", std::ios::binary | std::ios::out);
    ofs.seekp((300<<20) - 1);
    ofs.write("", 1);
}

Note that technically, this will be a good way to trigger your filesystem's support for sparse files.

Dense file - filled with 0's

Functionally identical to the above, but filling the file with 0's:

#include <iostream>
#include <fstream>
#include <vector>

int main()
{
    std::vector<char> empty(1024, 0);
    std::ofstream ofs("ouput.img", std::ios::binary | std::ios::out);

    for(int i = 0; i < 1024*300; i++)
    {
        if (!ofs.write(&empty[0], empty.size()))
        {
            std::cerr << "problem writing to file" << std::endl;
            return 255;
        }
    }
}
Injection answered 25/10, 2011 at 21:25 Comment(4)
Added a three line solution that will save space by making a sparse file.Injection
This works, but I don't understand the 20 in the ofs.seekp((300<<20)-1); I understand that it gets you to the size-1 position to write your empty character, but what does the 300<<20 operator do?Trimeter
<< is the bitwise shift-left operation. Shifting binary numbers left by one bit is equivalent to multiplying by 2. So shifting left by 10 bits is equivalent to multiplying by 1024 (2**10). It is a convenient shorthand in absense of C++11 userdefined literals like 300MbInjection
Thanks! Totally forgot about bit shifting :STrimeter
P
2

Your code doesn't work because you are using fputs which writes a null-terminated string into the output buffer. But you are trying to write all nulls, so it stops right when it looks at the first byte of your string and ends up writing nothing.

Now, to create a file of a specific size, all you need to do is to call truncate function (or _chsiz for Windows) exactly once and set what size you want the file to be.

Good luck!

Pleinair answered 25/10, 2011 at 21:24 Comment(0)
F
0

To make a 2MB file you have to seek to 2*1024*1024 and write 0 bytes. fput()ting empty string will do no good no matter how many time. And the string is empty, because strings a 0-terminated.

Flatworm answered 25/10, 2011 at 21:22 Comment(2)
writing 0 bytes (e.g. ofstream::write("", 0)) doesn't work.Ierna
I do not think ofstream guarantees writing 0 bytes, honestly I have no idea how should one go about it with ofstream other than taking fd from it and performing the magic on it. Honestly, I don't think setting the size of the file is very "streaming" activity.Flatworm

© 2022 - 2024 — McMap. All rights reserved.