フォルダないにあるファイルの合計容量を表示したいのですが
FindFirst を使って Size を合計するとファイルのサイズは取得
できたのですが、 ディスク上のサイズがわかりません。
HDD・OS・機種?によって値が変わるのですが
どうやって求めればよいのでしょうか?
昔は 1024で割って、切り上げて 1024 倍すると
サイズがでてきたと思いますが・・・・
ディスク上のサイズはHDDの1クラスタの容量によって変わるのではないかと思うのですが、
GetDiskFreeSpaceで1クラスタの容量を取得し、取得バイト数で割って切り上げて(以下略
// RootPathName に 'C:'や'C:\'のようにドライブを指定。
function GetBytePerCluster(RootPathName: String): Cardinal;
var
SectorsPerCluster,
BytesPerSector,
FreeClusterCount,
ClusterCount: Cardinal;
begin
GetDiskFreeSpace(PAnsiChar(RootPathName),
SectorsPerCluster,
BytesPerSector,
FreeClusterCount,
ClusterCount);
// 1クラスタの容量 = 1セクタのバイト数 * 1クラスタのセクタ数
Result := BytesPerSector * SectorsPerCluster;
end;
見習いなのでこれが限度です(ーー;
ちなみにWin2000+NTFSではきちんと動作しました。
どうもです。
がんばります。
9x系でファイルシステムがFAT32の場合、
GetDiskFreeSpaceは間違った値を返すので処理をわける必要があります。
9x系 FAT32クラスタサイズ取得方法は下記のようにします。
const
CARRY_FLAG = $00000001;
VWIN32_DIOC_DOS_DRIVEINFO = 6;
type
// DIOCレジスタ構造体
TDIOC_REGISTERS = record
reg_EBX : DWORD;
reg_EDX : DWORD;
reg_ECX : DWORD;
reg_EAX : DWORD;
reg_EDI : DWORD;
reg_ESI : DWORD;
reg_Flags: DWORD;
end;
// -----------------------------------------------------------------
// 9x系 FAT32クラスタサイズ取得関数 ※取得失敗時は -1 を返す
// Drive ドライブ番号 1 が A ドライブ,2 が B ドライブと続きます。
// -----------------------------------------------------------------
function GetClusterSizeFAT32(Drive: Byte): Integer;
type
// FAT32 拡張DPB(Device Parameter Block)構造体
TExtDPB = packed record
dpb_drive : Byte;
dpb_unit : Byte;
dpb_sector_size : Word; // セクタサイズ
dpb_cluster_mask : Byte; // クラスタ当りのセクタ数 - 1
dpb_cluster_shift : Byte;
dpb_first_fat : Word;
dpb_fat_count : Byte;
dpb_root_entries : Word;
dpb_first_sector : Word;
dpb_max_cluster : Word;
dpb_fat_size : Word;
dpb_dir_sector : Word;
dpb_reserved2 : DWORD;
dpb_media : Byte;
dpb_first_access : Byte;
dpb_reserved3 : DWORD;
dpb_next_free : Word;
dpb_free_cnt : Word;
extdpb_free_cnt_hi : Word;
extdpb_flags : Word;
extdpb_FSInfoSec : Word;
extdpb_BkUpBootSec : Word;
extdpb_first_sector: DWORD;
extdpb_max_cluster : DWORD;
extdpb_fat_size : DWORD;
extdpb_root_clus : DWORD;
extdpb_next_free : DWORD;
end;
// Int 21h Function 7302hの戻り値を格納する構造体
TDPBResult = packed record
wSize: Word;
DPB : TExtDPB;
end;
var
Reg : TDIOC_REGISTERS;
DPBResult : TDPBResult;
hDevice : THandle;
bResult : Boolean;
BytesReturned: DWORD;
begin
Result:= -1;
FillChar(DPBResult, SizeOf(TDPBResult), 0);
FillChar(Reg, SizeOf(TDIOC_REGISTERS), 0);
Reg.reg_EDX := Drive; // 対象のドライブ番号をDLレジスタに読込
Reg.reg_EAX := $7302; // Int 21h Function 7302h: Get_ExtDPB(FAT32)
Reg.reg_EDI := DWORD(@DPBResult); // 戻り値を受け取る構造体のアドレス。 DeviceIoControlによって、ES:DIに分割される
Reg.reg_ECX := SizeOf(TDPBResult); // 戻り値を受け取る構造体のサイズ
Reg.reg_Flags:= CARRY_FLAG; // エラーを仮定したキャリーフラグ
// 仮想ドライバ Vwin32を開く
hDevice:= CreateFile('\\.\vwin32', 0, 0, nil, 0, FILE_FLAG_DELETE_ON_CLOSE, 0);
if (hDevice <> INVALID_HANDLE_VALUE) then
begin
// Int 21h Function 7302hの呼出
try
bResult:=
DeviceIoControl(
hDevice, VWIN32_DIOC_DOS_DRIVEINFO, @Reg, SizeOf(TDIOCRegisters),
@Reg, SizeOf(TDIOCRegisters), BytesReturned, nil
);
finally
CloseHandle(hDevice);
end;
// reg_FlagsのLSBはcarry flagであり、エラーならセットされる
if bResult and (Reg.reg_Flags and CARRY_FLAG = 0) then
with DPBResult.DPB do Result:= (dpb_cluster_mask + 1) * dpb_sector_size;
end;
end;
この他にも setupapi.dll の API関数を使った方法もあります。
使用関数は
SetupCreateDiskSpaceList
SetupDestroyDiskSpaceList
SetupAddToDiskSpaceList
SetupQuerySpaceRequiredOnDrive
です。
こちらはクラスタギャップを考慮したディスクサイズを返してくれます。
よかったら調べてみて下さい。
ツイート | ![]() |