Skip to content

Commit 6010a7c

Browse files
jercaianudlang-bot
authored andcommitted
Fix Issue 16487 - Add function to obtain the available disk space (#5776)
Fix Issue 16487 - Add function to obtain the available disk space merged-on-behalf-of: unknown
1 parent 275f394 commit 6010a7c

File tree

2 files changed

+89
-0
lines changed

2 files changed

+89
-0
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
Added the `std.file.getAvailableDiskSpace` functionality.
2+
3+
$(REF getAvailableDiskSpace, std,file) receives as a parameter the path of a file or
4+
directory in the file system, and returns the available disk space on the mounted filesystem.
5+
If the given path is nonexistent, an exception is thrown.
6+
7+
---
8+
import std.file;
9+
ulong size = getAvailableDiskSpace(".");
10+
assert(size > 0);
11+
---
12+
13+
---
14+
import std.file;
15+
assertThrown(getAvailableDiskSpace("NonExistentFile"));
16+
---
17+

std/file.d

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ $(TR $(TD Other) $(TD
6262
$(LREF FileException)
6363
$(LREF PreserveAttributes)
6464
$(LREF SpanMode)
65+
$(LREF getAvailableDiskSpace)
6566
))
6667
)
6768
@@ -5232,3 +5233,74 @@ string tempDir() @trusted
52325233
myFile.write("hello");
52335234
assert(myFile.readText == "hello");
52345235
}
5236+
5237+
/**
5238+
Returns the available disk space based on a given path.
5239+
On Windows, `path` must be a directory; on Posix systems, it can be a file or directory.
5240+
5241+
Params:
5242+
path = on Windows, it must be a directory; on Posix it can be a file or directory
5243+
Returns:
5244+
Available space in bytes
5245+
5246+
Throws:
5247+
$(LREF FileException) in case of failure
5248+
*/
5249+
ulong getAvailableDiskSpace(scope const(char)[] path) @safe
5250+
{
5251+
version (Windows)
5252+
{
5253+
import core.sys.windows.winbase : GetDiskFreeSpaceExW;
5254+
import core.sys.windows.winnt : ULARGE_INTEGER;
5255+
import std.internal.cstring : tempCStringW;
5256+
5257+
ULARGE_INTEGER freeBytesAvailable;
5258+
auto err = () @trusted {
5259+
return GetDiskFreeSpaceExW(path.tempCStringW(), &freeBytesAvailable, null, null);
5260+
} ();
5261+
cenforce(err != 0, "Cannot get available disk space");
5262+
5263+
return freeBytesAvailable.QuadPart;
5264+
}
5265+
else version (Posix)
5266+
{
5267+
import std.internal.cstring : tempCString;
5268+
5269+
version (FreeBSD)
5270+
{
5271+
import core.sys.freebsd.sys.mount : statfs, statfs_t;
5272+
5273+
statfs_t stats;
5274+
auto err = () @trusted {
5275+
return statfs(path.tempCString(), &stats);
5276+
} ();
5277+
cenforce(err == 0, "Cannot get available disk space");
5278+
5279+
return stats.f_bavail * stats.f_bsize;
5280+
}
5281+
else
5282+
{
5283+
import core.sys.posix.sys.statvfs : statvfs, statvfs_t;
5284+
5285+
statvfs_t stats;
5286+
auto err = () @trusted {
5287+
return statvfs(path.tempCString(), &stats);
5288+
} ();
5289+
cenforce(err == 0, "Cannot get available disk space");
5290+
5291+
return stats.f_bavail * stats.f_frsize;
5292+
}
5293+
}
5294+
else static assert(0, "Unsupported platform");
5295+
}
5296+
5297+
///
5298+
@safe unittest
5299+
{
5300+
import std.exception : assertThrown;
5301+
5302+
auto space = getAvailableDiskSpace(".");
5303+
assert(space > 0);
5304+
5305+
assertThrown!FileException(getAvailableDiskSpace("ThisFileDoesNotExist123123"));
5306+
}

0 commit comments

Comments
 (0)