简体   繁体   English

C++ 在写入文件时获取文件的大小

[英]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. gui线程每秒更新状态栏以更新显示的录制时间。 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:我最初咨询了这个问题并尝试了两种stat方法:

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: (为简单起见没有错误检查)和fseek方法:

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.但无论哪种方式,我的文件大小都为 0。 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.文件名加上 0 是我从 GUI 线程打印出来的。 'Bytes written x' is out of the recording thread. 'Byteswritten x' 不在记录线程中。

You can read all about C++ file manipulations here http://www.cplusplus.com/doc/tutorial/files/您可以在此处阅读有关 C++ 文件操作的所有信息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.作为一种绝望的选择,您可以在“写入数据线程”中使用 ftell 或者使用变量来跟踪写入的数据量,但要解决真正的问题,您一定是犯了一个错误,也许 fopen 永远不会打开文件,或类似的东西。

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.只需在调用 stat 之前使用 freopen 函数。 It seems freopen refreshes the file length.似乎 freopen 刷新了文件长度。

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.我意识到这篇文章在这一点上已经相当老了,但是作为对@TylerD007 的回应,虽然这很有效,但如果你想要做的只是获取写入的字节数,那么这样做的成本非常高。

In C++17 and later, you can simply use the <filesystem> header and call在 C++17 及更高版本中,您可以简单地使用<filesystem>标头并调用
auto fileSize {std::filesystem::file_size(filePath)}; and now variable fileSize holds the actual size of the file.现在变量fileSize保存文件的实际大小。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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