在 C++ 中不打开文件的情况下检查文件大小?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8991192/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Check the file-size without opening file in C++?
提问by user1167566
I'm trying to get the filesize of a large file (12gb+) and I don't want to open the file to do so as I assume this would eat a lot of resources. Is there any good API to do so with? I'm in a Windows environment.
我正在尝试获取大文件 (12gb+) 的文件大小,但我不想打开文件这样做,因为我认为这会占用大量资源。有什么好的API可以这样做吗?我在 Windows 环境中。
回答by David Heffernan
You should call GetFileSizeEx
which is easier to use than the older GetFileSize
. You will need to open the file by calling CreateFile
but that's a cheap operation. Your assumption that opening a file is expensive, even a 12GB file, is false.
你应该调用GetFileSizeEx
哪个比旧的更容易使用GetFileSize
。您需要通过调用打开文件,CreateFile
但这是一个廉价的操作。您认为打开文件很昂贵,即使是 12GB 的文件也是错误的。
You could use the following function to get the job done:
您可以使用以下函数来完成工作:
__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;
}
There are other API calls that will return you the file size without forcing you to create a file handle, notably GetFileAttributesEx
. However, it's perfectly plausible that this function will just open the file behind the scenes.
还有其他 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;
}
If you are compiling with Visual Studio and want to avoid calling Win32 APIs then you can use _wstat64
.
如果您使用 Visual Studio 进行编译并希望避免调用 Win32 API,那么您可以使用_wstat64
.
Here is a _wstat64
based version of the function:
这是_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;
}
If performance ever became an issue for you then you should time the various options on all the platforms that you target in order to reach a decision. Don't assume that the APIs that don't require you to call CreateFile
will be faster. They might be but you won't know until you have timed it.
如果性能曾经成为您的问题,那么您应该在您所针对的所有平台上对各种选项进行计时,以便做出决定。不要假设不需要您调用的 APICreateFile
会更快。他们可能是,但你不会知道,直到你计时。
回答by CodeAngry
I've also lived with the fear of the price paid for opening a file and closing it just to get its size.And decided to ask the performance counter^and see how expensive the operations really are.
我也一直担心打开和关闭文件只是为了得到它的大小而付出的代价。并决定询问性能计数器^并查看操作的实际成本。
This is the number of cycles it took to execute 1 file size query on the same file with the three methods.Tested on 2 files: 150 MB and 1.5 GB. Got +/- 10% fluctuations so they don't seem to be affected by actual file size. (obviously this depend on CPU but it gives you a good vantage point)
这是使用三种方法对同一文件执行 1 个文件大小查询所需的周期数。测试了 2 个文件:150 MB 和 1.5 GB。有 +/- 10% 的波动,因此它们似乎不受实际文件大小的影响。(显然这取决于 CPU,但它为您提供了一个很好的有利位置)
- 190 cycles-
CreateFile
,GetFileSizeEx
,CloseHandle
- 40 cycles-
GetFileAttributesEx
- 150 cycles-
FindFirstFile
,FindClose
- 190 个周期-
CreateFile
,GetFileSizeEx
,CloseHandle
- 40 个周期-
GetFileAttributesEx
- 150 次循环-
FindFirstFile
,FindClose
The GIST with the code used^is available here.
使用^代码的 GIST可在此处获得。
As we can see from this highly scientific :) test, slowest is actually the file opener. 2nd slowest is the file finder while the winner is the attributes reader. Now, in terms of reliability, CreateFile
should be preferred over the other 2.But I still don't like the concept of opening a file just to read its size... Unless I'm doing size critical stuff, I'll go for the Attributes.
正如我们从这个高度科学的 :) 测试中看到的,最慢的实际上是文件打开器。第二慢的是文件查找器,而获胜者是属性读取器。现在,就可靠性而言,CreateFile
应该优先于其他 2 个。但我仍然不喜欢打开文件只是为了读取其大小的概念......除非我在做大小关键的事情,否则我会去的属性。
PS: When I'll have time I'll try to read sizes of files that are opened and am writing to. But not right now...
PS:当我有时间时,我会尝试读取已打开和正在写入的文件的大小。但不是现在...
回答by RRUZ
Another option using the FindFirstFilefunction
使用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 %u\n"), FileSize);
FindClose(hFind);
}
return 0;
}
回答by Davis Herring
回答by Armen Tsirunyan
What about GetFileSizefunction?
什么GetFileSize功能?