Windows 有没有快速获取磁盘上文件数量的方法?
我有一个可以扫描硬盘内容的Windows程序。我想在它这样做时显示一个有意义的进度条。有没有一种快速获取磁盘上文件总数的方法?这个数字不一定要精确——大约在10%以内就可以了。这对于NTFS卷是可能的。单程扮演哈利·约翰斯顿。也可以通过另一种方式,通过迭代文件记录,速度也足够快:Windows 有没有快速获取磁盘上文件数量的方法?,windows,filesystems,Windows,Filesystems,我有一个可以扫描硬盘内容的Windows程序。我想在它这样做时显示一个有意义的进度条。有没有一种快速获取磁盘上文件总数的方法?这个数字不一定要精确——大约在10%以内就可以了。这对于NTFS卷是可能的。单程扮演哈利·约翰斯顿。也可以通过另一种方式,通过迭代文件记录,速度也足够快: struct NTFS_RECORD_HEADER { enum { FILE = 'ELIF', INDX = 'XDNI', BAAD = 'DAAB',
struct NTFS_RECORD_HEADER
{
enum {
FILE = 'ELIF',
INDX = 'XDNI',
BAAD = 'DAAB',
HOLE = 'ELOH',
CHKD = 'DKHC'
} Type;
USHORT UsaOffset;
USHORT UsaCount;
USN Usn;
};
struct NTFS_FILE_RECORD_HEADER : public NTFS_RECORD_HEADER
{
USHORT SequenceNumber;
USHORT LinkCount;
USHORT AttributesOffset;
USHORT Flags;
ULONG BytesInUse;
ULONG BytesAllocated;
ULONGLONG BaseFileRecord;
USHORT NextAttributeNumber;
enum{
flgInUse = 1, flgDirectory = 2
};
};
ULONG GetFileCount(HANDLE hVolume, PULONG FileCount)
{
NTFS_VOLUME_DATA_BUFFER nvdb;
ULONG cb, BytesReturned;
if (!DeviceIoControl(hVolume, FSCTL_GET_NTFS_VOLUME_DATA, NULL, 0, &nvdb, sizeof(nvdb), &BytesReturned, NULL))
{
return GetLastError();
}
NTFS_FILE_RECORD_INPUT_BUFFER nfrib;
cb = FIELD_OFFSET(NTFS_FILE_RECORD_OUTPUT_BUFFER, FileRecordBuffer[nvdb.BytesPerFileRecordSegment]);
PNTFS_FILE_RECORD_OUTPUT_BUFFER pnfrob = (PNTFS_FILE_RECORD_OUTPUT_BUFFER)alloca(cb);
union {
PVOID FileRecordBuffer;
NTFS_RECORD_HEADER* pnrh;
NTFS_FILE_RECORD_HEADER* pnfrh;
};
FileRecordBuffer = pnfrob->FileRecordBuffer;
// get maximum valid FileReferenceNumber
ULONG a = 0, b = MAXLONG, N;
do
{
nfrib.FileReferenceNumber.QuadPart = N = (a + b) >> 1;
DeviceIoControl(hVolume, FSCTL_GET_NTFS_FILE_RECORD,
&nfrib, sizeof nfrib, pnfrob, cb, &BytesReturned, 0) ? a = N + 1 : b = N;
} while(a < b);
if (!b)
{
return ERROR_GEN_FAILURE;
}
N = 0;
nfrib.FileReferenceNumber.QuadPart = b - 1;
// itterate [0, nfrib.FileReferenceNumber.QuadPart)
do
{
if (DeviceIoControl(hVolume, FSCTL_GET_NTFS_FILE_RECORD,
&nfrib, sizeof nfrib, pnfrob, cb, &BytesReturned, 0))
{
// are really file
if (
pnrh->Type == NTFS_RECORD_HEADER::FILE &&
pnfrh->Flags & NTFS_FILE_RECORD_HEADER::flgInUse &&
!pnfrh->BaseFileRecord
)
{
N++;
}
}
else
{
pnfrob->FileReferenceNumber.QuadPart = nfrib.FileReferenceNumber.QuadPart;
}
} while (0 <= (nfrib.FileReferenceNumber.QuadPart = pnfrob->FileReferenceNumber.QuadPart - 1));
*FileCount = N;
return NOERROR;
}
struct NTFS\u记录\u头
{
枚举{
文件='ELIF',
INDX='XDNI',
BAAD='DAAB',
孔='ELOH',
CHKD='DKHC'
}类型;
USHORT-UsaOffset;
USHORT UsaCount;
美国海军;
};
结构NTFS文件记录头:公共NTFS记录头
{
USHORT序列号;
USHORT链接计数;
USHORT属性偏移;
美国国旗;
乌隆比特西努斯;
ULONG Bytes;
ULONGLONG BaseFileRecord;
USHORT NextAttributeNumber;
枚举{
flgInUse=1,flgDirectory=2
};
};
ULONG GetFileCount(HANDLE hVolume,PULONG FileCount)
{
NTFS_卷_数据_缓冲区nvdb;
ULONG cb,BytesReturned;
if(!DeviceIoControl(hVolume、FSCTL\u GET\u NTFS\u VOLUME\u DATA、NULL、0、&nvdb、sizeof(nvdb)、&bytesrurned、NULL))
{
返回GetLastError();
}
NTFS文件记录输入缓冲区nfrib;
cb=字段偏移量(NTFS文件记录输出缓冲区,FileRecordBuffer[nvdb.BytesPerFileRecordSegment]);
PNTFS文件记录输出缓冲区pnfrob=(PNTFS文件记录输出缓冲区)alloca(cb);
联合{
pvoidfilerecordbuffer;
NTFS_记录_头*pnrh;
NTFS文件记录头*pnfrh;
};
FileRecordBuffer=pnfrob->FileRecordBuffer;
//获取最大有效FileReferenceNumber
ULONG a=0,b=MAXLONG,N;
做
{
nfrib.FileReferenceNumber.QuadPart=N=(a+b)>>1;
设备控制(hVolume、FSCTL\u GET\u NTFS\u FILE\u RECORD、,
&nfrib,nfrib的大小,pnfrob,cb和字节返回,0)?a=N+1:b=N;
}而(aType==NTFS\u记录头::文件&&
pnfrh->标志和NTFS文件记录头::flgInUse&&
!pnfrh->BaseFileRecord
)
{
N++;
}
}
其他的
{
pnfrob->FileReferenceNumber.QuadPart=nfrib.FileReferenceNumber.QuadPart;
}
}而(0 FileReferenceNumber.QuadPart-1));
*FileCount=N;
返回无错误;
}
您是否具有管理员权限?提供了一种更快的扫描磁盘内容的方法,如果您这样做了,您可以通过跟踪您已处理的内容来实现进度条。在这方面运气不好--此程序需要能够在尽可能广泛的环境下运行。