0
私は、ハードディスクの内容をスキャンするWindowsプログラムを持っています。意味のあるプログレスバーを表示したいと思います。ディスク上のファイルの総数を取得する簡単な方法はありますか?その数は正確である必要はありません - 10%程度の近似が必要です。ディスク上のファイル数をすばやく取得する方法はありますか?
私は、ハードディスクの内容をスキャンするWindowsプログラムを持っています。意味のあるプログレスバーを表示したいと思います。ディスク上のファイルの総数を取得する簡単な方法はありますか?その数は正確である必要はありません - 10%程度の近似が必要です。ディスク上のファイル数をすばやく取得する方法はありますか?
これはNTFSボリュームで可能です。片道ハリー・ジョンストンwrite。何らかの別の方法でも可能で、ファイルレコードを反復するだけで十分に高速です。
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;
}
管理者特権はありますか? [MFTの内容を読む](http://stackoverflow.com/a/7459109/886887)は、ディスクの内容をより高速にスキャンする方法を提供します。そうした場合は、あなたが処理した[MFTの何パーセント](http://stackoverflow.com/a/11337898/886887)のトラック。 –
それには運がない - このプログラムは、できるだけ広い範囲で実行できる必要があります。 – Mark