在不使用C++打开文件的情况下检查文件大小
Check the file-size without opening file in C++?
我正在尝试获取一个大文件(12gb+)的文件大小,但我不想打开该文件,因为我认为这会占用大量资源。有什么好的API可以这样做吗?我在Windows环境中。
您应该调用比旧GetFileSize
更易于使用的GetFileSizeEx
。您需要通过调用CreateFile
来打开文件,但这是一个廉价的操作。你认为打开一个文件很昂贵,即使是12GB的文件,也是错误的。
您可以使用以下功能来完成任务:
__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;
}
还有其他API调用将返回文件大小,而无需创建文件句柄,特别是GetFileAttributesEx
。然而,这个函数只是在幕后打开文件,这是完全合理的。
__int64 FileSize(const wchar_t* name)
{
WIN32_FILE_ATTRIBUTE_DATA fad;
if (!GetFileAttributesEx(name, GetFileExInfoStandard, &fad))
return -1; // error condition, could call GetLastError to find out more
LARGE_INTEGER size;
size.HighPart = fad.nFileSizeHigh;
size.LowPart = fad.nFileSizeLow;
return size.QuadPart;
}
如果使用Visual Studio进行编译,并且希望避免调用Win32 API,则可以使用_wstat64
。
以下是基于_wstat64
的函数版本:
__int64 FileSize(const wchar_t* name)
{
__stat64 buf;
if (_wstat64(name, &buf) != 0)
return -1; // error, could use errno to find out more
return buf.st_size;
}
如果性能曾经成为您的一个问题,那么您应该对所有目标平台上的各种选项进行计时,以便做出决定。不要以为不需要调用CreateFile
的API会更快。它们可能是,但在计时之前你不会知道。
我也生活在打开文件并关闭文件以获取其大小所付出的代价的恐惧中并决定询问性能计数器^,看看这些操作的成本到底有多高。
这是使用三种方法对同一文件执行1个文件大小查询所花费的周期数在2个文件上进行了测试:150 MB和1.5 GB。有+/-10%的波动,所以它们似乎不受实际文件大小的影响(显然这取决于CPU,但它为您提供了一个很好的优势)
-
190次循环-
CreateFile
、GetFileSizeEx
、CloseHandle
-
40次循环-
GetFileAttributesEx
-
150次循环-
FindFirstFile
、FindClose
此处提供带有所用代码的GIST^。
正如我们从这个高度科学化的测试中看到的:)测试,最慢的实际上是文件打开程序。排名第二的是文件查找器,而排名第一的是属性读取器现在,就可靠性而言,CreateFile
应该比其他2更受欢迎。但我仍然不喜欢打开文件只是为了读取其大小的概念。。。除非我在做尺寸关键的事情,否则我会选择属性。
PS:当我有时间的时候,我会尝试读取打开并正在写入的文件的大小。但现在不行
使用FindFirstFile函数的另一个选项
#include "stdafx.h"
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
int _tmain(int argc, _TCHAR* argv[])
{
WIN32_FIND_DATA FindFileData;
HANDLE hFind;
LPCTSTR lpFileName = L"C:\Foo\Bar.ext";
hFind = FindFirstFile(lpFileName , &FindFileData);
if (hFind == INVALID_HANDLE_VALUE)
{
printf ("File not found (%d)n", GetLastError());
return -1;
}
else
{
ULONGLONG FileSize = FindFileData.nFileSizeHigh;
FileSize <<= sizeof( FindFileData.nFileSizeHigh ) * 8;
FileSize |= FindFileData.nFileSizeLow;
_tprintf (TEXT("file size is %un"), FileSize);
FindClose(hFind);
}
return 0;
}
与C++17一样,file_size是标准库的一部分。(然后实现者可以决定如何高效地完成它!)
GetFileSize函数怎么样?
- 为什么在某些情况下不写入此文件?
- 在 Windows 上,是否可以让 dll 在不使用 PATH 环境变量的情况下在另一个文件夹中查找依赖项?
- 有没有办法在不使用 getline() 的情况下从.csv文件中读取?
- 是否可以在没有真实文件的情况下创建 ifstream
- 在 c++ 中连接字符串和整数,以便在 C++ 11 不支持计算机的情况下读取多个文件
- 如何在多写入器情况下对文件支持的共享内存中的大页面出错
- 如何在添加文件的情况下在VSCode中调试C++程序
- 每个文件(理想情况下是每个部分)的 clang 格式样式覆盖
- 如何在不重新创建现有文件的情况下写入.txt文件
- 如何在不知道大小的情况下读取文本文件并存储到数组中
- 如何使用Winforms C#或C++.Net在不更改文件中其他内容的情况下修改jpg文件中的Orientation e
- 如何在不循环的情况下使用getline读取文件
- 在不打开应用程序的情况下在MinGW c++中播放声音(.wav)文件
- C++-在没有自定义.lib文件的情况下从Lua C模块调用Lua函数
- 如何在不使用文件扩展名的情况下使用命令行参数打开C++中的文本文件?
- 如何在不受其他文件影响的情况下"by itself" Visual Studio 项目中运行C++文件?
- 如何在不包含完整的文件系统头的情况下使用文件系统的类路径C++17?
- 如何在不设置 ulimit -n 的情况下解决套接字程序打开太多文件的错误
- Nlohmann 在不知道密钥的情况下解析 JSON 文件
- C++:如何在不将命令传递给 shell 的情况下执行文件?