简体   繁体   中英

C++ get the size of a file while it's being written to

I have a recording application that is reading data from a network stream and writing it to file. It works very well, but I would like to display the file size as the data is being written. Every second the gui thread updates the status bar to update the displayed time of recording. At this point I would also like to display the current file size.

I originally consulted this question and have tried both the stat method:

struct stat stat_buf;
int rc = stat(recFilename.c_str(), &stat_buf);
std::cout << recFilename << " " << stat_buf.st_size << "\n";

(no error checking for simplicity) and the fseek method:

FILE *p_file = NULL;
p_file = fopen(recFilename.c_str(),"rb");
fseek(p_file,0,SEEK_END);
int size = ftell(p_file);
fclose(p_file);

but either way, I get 0 for the file size. When I go back and look at the file I write to, the data is there and the size is correct. The recording is happening on a separate thread.

I know that bytes are being written because I can print the size of the data as it is written in conjunction with the output of the methods shown above. 在此处输入图像描述

The filename plus the 0 is what I print out from the GUI thread. 'Bytes written x' is out of the recording thread.

You can read all about C++ file manipulations here http://www.cplusplus.com/doc/tutorial/files/

This is an example of how I would do it.

#include <fstream>

std::ifstream::pos_type filesize(const char* file)
{
    std::ifstream in(file, std::ifstream::ate | std::ifstream::binary);
    return in.tellg(); 
}

Hope this helps.

As a desperate alternative, you can use a ftell in "the write data thread" or maybe a variable to track the amount of data that is written, but going to the real problem, you must be making a mistake, maybe fopen never opens the file, or something like that.

I'll copy a test code to show that this works at least in a singlethread app

int _tmain(int argc, _TCHAR* argv[]) 
{
    FILE * mFile;
    FILE * mFile2;

    mFile = fopen("hi.txt", "a+");

    // fseek(mFile, 0, SEEK_END);

    // @@ this is to make sure that fputs and fwrite works equal
    // fputs("fopen example", mFile);
    fwrite("fopen ex", 1, 9, mFile);

    fseek(mFile, 0, SEEK_END);
    std::cout << ftell(mFile) << ":";

    mFile2 = fopen("hi.txt", "rb");
        fseek(mFile2, 0, SEEK_END);
        std::cout << ftell(mFile2) << std::endl;
   fclose(mFile2);

   fclose(mFile);

   getchar();

   return 0;
}

Just use freopen function before calling stat. It seems freopen refreshes the file length.

I realize this post is rather old at this point, but in response to @TylerD007, while that works, that is incredibly expensive to do if all you're trying to do is get the amount of bytes written.

In C++17 and later, you can simply use the <filesystem> header and call
auto fileSize {std::filesystem::file_size(filePath)}; and now variable fileSize holds the actual size of the file.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM