在 C++ 中检查空文件

Checking for an empty file in C++

提问人:Crystal 提问时间:3/6/2010 最后编辑:Crystal 更新时间:9/13/2022 访问量:150724

问:

有没有一种简单的方法来检查文件是否为空。就像你把一个文件传递给一个函数,你意识到它是空的,然后你马上关闭它?谢谢。

编辑,我尝试使用 fseek 方法,但收到错误说“无法将 ifstream 转换为 FILE *”。

我的函数的参数是

myFunction(ifstream &inFile)
C++ EOF

评论

0赞 C. K. Young 3/6/2010
太糟糕了,你不能轻松地从 .您可以在 Unix 上使用 轻松检查空文件。9-3fstreamfstat

答:

5赞 Mehrdad Afshari 3/6/2010 #1

寻找文件的末尾并检查位置:

 fseek(fileDescriptor, 0, SEEK_END);
 if (ftell(fileDescriptor) == 0) {
     // file is empty...
 } else {
     // file is not empty, go back to the beginning:
     fseek(fileDescriptor, 0, SEEK_SET);
 }

如果您还没有打开文件,只需使用该功能并直接检查文件大小即可。fstat

-1赞 sizzzzlerz 3/6/2010 #2
pFile = fopen("file", "r");
fseek (pFile, 0, SEEK_END);
size=ftell (pFile);
if (size) {
  fseek(pFile, 0, SEEK_SET);
  do something...
}

fclose(pFile)

评论

1赞 t0mm13b 3/6/2010
使用类似于“100110”的工具栏按钮设置代码格式
0赞 Antonio 1/26/2023
这是 C 代码,不适用于流(如果文件名可用,则有 C++ 方法)
9赞 pajton 3/6/2010 #3

好的,所以这段代码应该对你有用。我更改了名称以匹配您的参数。

inFile.seekg(0, ios::end);  
if (inFile.tellg() == 0) {    
  // ...do something with empty file...  
}

评论

0赞 2/16/2021
那么这到底是在做什么呢?它有效,但我想知道为什么。它是否检查流的末尾并查看它是否等于 0?
0赞 Antonio 1/26/2023
@user12455086 seekg(0, ios::end) 将读取指针移动到文件的末尾,然后告诉我们它仍然在位置 0,然后我们知道文件的末尾与文件的开头相对应,因此文件是空的。if inFile.tellg()
0赞 Antonio 1/26/2023
这个解决方案的问题在于它搞砸了流,下面的 Aylian Craspa 展示了如何规避这个问题 stackoverflow.com/a/69755880/2436175
91赞 GManNickG 3/6/2010 #4

也许类似于:

bool is_empty(std::ifstream& pFile)
{
    return pFile.peek() == std::ifstream::traits_type::eof();
}

短小精悍。


考虑到您的错误,其他答案使用 C 样式的文件访问,您可以在其中获得具有特定功能的文件。FILE*

相反,您和我正在使用 C++ 流,因此无法使用这些函数。上面的代码以简单的方式工作:将查看流并返回下一个字符,而不删除。如果它到达文件末尾,则返回 .因此,我们只是在流上,看看它是否是,因为空文件没有什么可偷看的。peek()eof()peek()eof()

请注意,如果文件从一开始就没有打开过,这也将返回 true,这应该适用于您的情况。如果您不想要:

std::ifstream file("filename");

if (!file)
{
    // file is not open
}

if (is_empty(file))
{
    // file is empty
}

// file is open and not empty

评论

0赞 Potatoswatter 3/6/2010
添加起来不会太难return pFile.tellg() > 0 || …
0赞 Viktor Stefanov 8/9/2021
不会那么好用吗?pFile.peek() == '\n'
2赞 Marc 8/25/2021
@ViktorStefanov 否,如果文件以空行开头怎么办?
0赞 Antonio 1/26/2023
公平地说,对于文件,这仅在刚刚创建流(文件刚刚打开)时才有效。如果某些字符已被读取,并且“光标”已移动到文件末尾,则可能会说 是空的,但实际上并非如此。您可能需要额外的检查,因为我认为@Potatoswatter试图建议。filepFile.tellg() != 0 &&
0赞 user4471014 1/20/2015 #5
char ch;
FILE *f = fopen("file.txt", "r");

if(fscanf(f,"%c",&ch)==EOF)
{
    printf("File is Empty");
}
fclose(f);

评论

3赞 Lightness Races in Orbit 1/20/2015
为什么要在C++中使用这些C习语?
0赞 CroCo 1/20/2015 #6

怎么样(虽然不是优雅的方式)

int main( int argc, char* argv[] )
{
    std::ifstream file;
    file.open("example.txt");

    bool isEmpty(true);
    std::string line;

    while( file >> line ) 
        isEmpty = false;

        std::cout << isEmpty << std::endl;
}

评论

1赞 Lightness Races in Orbit 1/20/2015
很公平。它比user4471014的稍微好一点(由于是实际的C++,而不是C),尽管仍然完全浪费和次优。
0赞 CroCo 1/20/2015
@LightnessRacesinOrbit,你是对的,但是不需要遍历文件的所有行。一旦检测到第一行并将其设置为 ,while 循环就可以停止。如果这可以增强代码。isEmptyfalse
0赞 CroCo 1/20/2015
我可以理解这段代码是次优的,但为什么它是浪费的?OP 没有要求或寻找足够或如此优化的代码。
0赞 Lightness Races in Orbit 1/20/2015
(a) 这是浪费,因为您正在提取永远不会使用的数据。阅读这些字符毫无意义。(b) 仅仅因为 OP 没有特意要求提供“优化”代码并不意味着我们应该特意提供相反的代码。:)
-1赞 amna 11/4/2016 #7
if (nfile.eof()) // Prompt data from the Priming read:
    nfile >> CODE >> QTY >> PRICE;
else
{
    /*used to check that the file is not empty*/
    ofile << "empty file!!" << endl;
    return 1;
}

评论

1赞 Eli Sadoff 11/5/2016
虽然这可能为 OP 的问题提供解决方案,但没有对代码的解释。
0赞 Vytaute 1/22/2018 #8

使用这个: data.peek() != '\0'

我一直在寻找一个小时,直到最终这有帮助!

2赞 Mansoor 1/29/2021 #9

C++17 解决方案:

#include <filesystem>

const auto filepath = <path to file> (as a std::string or std::filesystem::path)

auto isEmpty = (std::filesystem::file_size(filepath) == 0);

假设您存储了文件路径位置,我认为您无法从对象中提取文件路径。std::ifstream

1赞 Aylian Craspa 10/28/2021 #10

当文件为空时,如果它为空,tellg 会给你值 0,所以专注于这一点,这是查找空文件的最简单方法,如果你只是创建文件,它会给你 -1。

outfile.seekg(0,ios::end);
if(file.tellg()<1){
  //empty
}else{
  file.clear(); // clear all flags(eof)
  file.seekg(0,ios::beg);//reset to front
  //not empty
}

评论

0赞 Antonio 1/26/2023
尽管有更好的答案,但至少这显示了如何将流重置为可用状态。
1赞 Antonio 9/13/2022 #11

如果您的用例提供了在打开文件之前检查空的可能性,
C++17 为您提供了is_empty

#include <filesystem>

if (!std::filesystem::is_empty("path.txt")) {
     ///Open and use the file
}

评论

0赞 metablaster 1/25/2023
出于某种原因,它说文件不是空的,而它是空的。
0赞 Antonio 1/25/2023
@metablaster 你能提供一些背景信息吗?您是否检查过文件不包含任何空格?
0赞 metablaster 1/25/2023
是的,我仔细检查了一下,只有一行,而且没有任何空格,甚至某些 Windows API 函数在文件为空时也会返回文件大小为 4 字节。我点击了几次以确保绝对没有任何东西。backspace
0赞 Antonio 1/25/2023
@metablaster 很抱歉多余,你能用HxD做最后的检查吗?mh-nexus.de/en/hxd
1赞 Antonio 1/26/2023
@metablaster 这里的重要结论是,这确实有效。为了规避其他应用程序的错误,您可以对 进行第二次检查,如果大小小于 X 个字符,您可以打开文件并检查内容是否全部为 null。filesystem::is_emptyfilesystem::file_size