Bug 16487 – Add function to obtain the available disk space

Status
RESOLVED
Resolution
FIXED
Severity
enhancement
Priority
P1
Component
phobos
Product
D
Version
D2
Platform
All
OS
All
Creation time
2016-09-11T21:20:54Z
Last change time
2019-06-28T06:36:04Z
Keywords
pull
Assigned to
alex.jercaianu
Creator
Johan Engelen

Comments

Comment #0 by jbc.engelen — 2016-09-11T21:20:54Z
Would be nice to have a function that returns the available disk space on a given path (file, directory, server share). Something like this: ``` // Returns ulong.max when the available disk space could not be determined. ulong getAvailableDiskSpace(string path) { import std.string: toStringz; version (WINDOWS) { import core.sys.windows.winbase; ULARGE_INTEGER freeBytesAvailable; auto pathCstr = (driveName(path) ~ dirSeparator).toStringz(); bool success = GetDiskFreeSpaceExW(path, &freeBytesAvailable, null, null); return success ? free_bytes.QuadPart : ulong.max; } else { import core.sys.posix.sys.statvfs; statvfs_t stats; int err = statvfs(path.toStringz(), &stats); return !err ? stats.f_bavail * stats.f_frsize : ulong.max; } } ```
Comment #1 by dfj1esp02 — 2016-09-12T10:10:01Z
NTFS supports symbolic links too, so GetDiskFreeSpaceExW should receive the folder path because it can reside on a different partition than the disk it's accessed through.
Comment #2 by jbc.engelen — 2016-09-12T11:25:34Z
Indeed, I misread GetDiskFreeSpaceEx's documentation. Thanks.
Comment #3 by jbc.engelen — 2016-09-13T08:11:49Z
Version that actually compiles on Windows too: ``` // Returns ulong.max when the available disk space could not be determined. ulong getAvailableDiskSpace(string path) { import std.string: toStringz; version (Windows) { import std.path; import core.sys.windows.winbase; import core.sys.windows.winnt; import std.internal.cstring; ULARGE_INTEGER freeBytesAvailable; path ~= dirSeparator; auto success = GetDiskFreeSpaceExW(path.tempCStringW(), &freeBytesAvailable, null, null); return success ? freeBytesAvailable.QuadPart : ulong.max; } else { import core.sys.posix.sys.statvfs; statvfs_t stats; int err = statvfs(path.toStringz(), &stats); return !err ? stats.f_bavail * stats.f_frsize : ulong.max; } } ```
Comment #4 by b2.temp — 2016-09-13T08:56:14Z
(In reply to Johan Engelen from comment #3) > Version that actually compiles on Windows too: > ``` > // Returns ulong.max when the available disk space could not be determined. > ulong getAvailableDiskSpace(string path) > { > import std.string: toStringz; > version (Windows) > { > import std.path; > import core.sys.windows.winbase; > import core.sys.windows.winnt; > import std.internal.cstring; > > ULARGE_INTEGER freeBytesAvailable; > path ~= dirSeparator; > auto success = GetDiskFreeSpaceExW(path.tempCStringW(), > &freeBytesAvailable, null, null); > return success ? freeBytesAvailable.QuadPart : ulong.max; > } > else > { > import core.sys.posix.sys.statvfs; > > statvfs_t stats; > int err = statvfs(path.toStringz(), &stats); > return !err ? stats.f_bavail * stats.f_frsize : ulong.max; > } > } > ``` what I would say if it'd be a PR: 1. change declaration to ulong getAvailableDiskSpace(const(char)[] path) because const(char)[] acts as a wildcard and takes all char[] variants. 2. returns -1 on failure. ulong.max: No way !!! 3. linux version: don't need to init the target so statvfs_t stats = void; Otherwise let's get the merge ;)
Comment #5 by jbc.engelen — 2016-09-13T09:20:48Z
(In reply to b2.temp from comment #4) > 2. returns -1 on failure. ulong.max: No way !!! The return type is _unsigned_. Throwing an exception is also a possibility.
Comment #6 by b2.temp — 2016-09-13T10:35:58Z
(In reply to Johan Engelen from comment #5) > (In reply to b2.temp from comment #4) > > 2. returns -1 on failure. ulong.max: No way !!! > > The return type is _unsigned_. Oops, sorry , i must be blind ^^ Anyway...Wouldn't 0 be a possible return type in case of error ? It would allow: if (auto space = getAvailableDiskSpace(root)) { } else { throw new Exception("either the disk is full or inaccessible"); } > Throwing an exception is also a possibility. No, seriously, delegate this option to the user.
Comment #7 by jack — 2016-09-13T13:19:07Z
(In reply to b2.temp from comment #6) > Anyway...Wouldn't 0 be a possible return type in case of error No. What if there's no more space in the drive? Would you return something other than zero?
Comment #8 by b2.temp — 2016-09-13T14:18:15Z
In both cases I 'd return 0. statvfs_t stats; int err = statvfs(path.toStringz(), &stats); return err ? 0 : stats.f_bavail * stats.f_frsize; > "either the disk is full or inaccessible" Because in both cases you can do nothing. By the way HDD are never full. Only removable media can be full (bootable USB key, DVD/CD rom, etc).
Comment #9 by greeenify — 2016-12-27T12:54:49Z
@Johan: As you have already prepared a nice function & no one disagrees that it wouldn't be useful - I assigned this to you. Looking forward to your PR ;-)
Comment #10 by jbc.engelen — 2016-12-27T22:19:58Z
Unassigning myself. I'm not going to work on this any time soon.
Comment #11 by alex.jercaianu — 2017-10-09T16:01:25Z
Hi, I'd like to take this task. In which part of the std do you think it would be best to put this function? Thanks, Alex
Comment #12 by b2.temp — 2017-10-09T16:14:57Z
std.file makes more sense. User wants available disk space to know if it can create a file or how many byte in disk a cache can use (or whatever else). Much less useful in std.path. ideally there would be: std.filesystem.file std.filesystem.path std.filesystem.package <-- i would put it here but since it's not the case std.file is the best ooption.
Comment #13 by johanengelen — 2018-02-15T20:43:18Z
Comment #14 by dlang-bot — 2019-06-18T23:27:28Z
@jercaianu updated dlang/phobos pull request #5776 "Fix Issue 16487 - Add function to obtain the available disk space" fixing this issue: - Fix Issue 16487 - Add function to obtain the available disk space - Fix Issue 16487 - Add function to obtain the available disk space https://github.com/dlang/phobos/pull/5776
Comment #15 by dlang-bot — 2019-06-28T06:36:04Z
dlang/phobos pull request #5776 "Fix Issue 16487 - Add function to obtain the available disk space" was merged into master: - d38cbf90cbd66685efa51b5c9a553ff253c7c1a5 by Alexandru Jercaianu: Fix Issue 16487 - Add function to obtain the available disk space https://github.com/dlang/phobos/pull/5776