Skip to content

Commit 0bffa0b

Browse files
committed
Fix Issue 16487 - Add function to obtain the available disk space
1 parent 861e65a commit 0bffa0b

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
@@ -60,6 +60,7 @@ $(TR $(TD Other) $(TD
6060
$(LREF FileException)
6161
$(LREF PreserveAttributes)
6262
$(LREF SpanMode)
63+
$(LREF getAvailableDiskSpace)
6364
))
6465
)
6566
@@ -5119,3 +5120,74 @@ string tempDir() @trusted
51195120
myFile.write("hello");
51205121
assert(myFile.readText == "hello");
51215122
}
5123+
5124+
/**
5125+
Returns the available disk space based on a given path.
5126+
On Windows, `path` must be a directory; on Posix systems, it can be a file or directory.
5127+
5128+
Params:
5129+
path = on Windows, it must be a directory; on Posix it can be a file or directory
5130+
Returns:
5131+
Available space in bytes
5132+
5133+
Throws:
5134+
$(LREF FileException) in case of failure
5135+
*/
5136+
ulong getAvailableDiskSpace(string path) @safe
5137+
{
5138+
version (Windows)
5139+
{
5140+
import core.sys.windows.winbase : GetDiskFreeSpaceExW;
5141+
import core.sys.windows.winnt : ULARGE_INTEGER;
5142+
import std.internal.cstring : tempCStringW;
5143+
5144+
ULARGE_INTEGER freeBytesAvailable;
5145+
auto err = () @trusted {
5146+
return GetDiskFreeSpaceExW(path.tempCStringW(), &freeBytesAvailable, null, null);
5147+
} ();
5148+
cenforce(err != 0, "Cannot get available disk space");
5149+
5150+
return freeBytesAvailable.QuadPart;
5151+
}
5152+
else version (Posix)
5153+
{
5154+
import std.string : toStringz;
5155+
5156+
version (FreeBSD)
5157+
{
5158+
import core.sys.posix.sys.statvfs : statfs, statfs_t;
5159+
5160+
statfs_t stats;
5161+
auto err = () @trusted {
5162+
return statfs(path.toStringz(), &stats);
5163+
} ();
5164+
cenforce(err == 0, "Cannot get available disk space");
5165+
5166+
return stats.f_bavail * stats.f_bsize;
5167+
}
5168+
else
5169+
{
5170+
import core.sys.posix.sys.statvfs : statvfs, statvfs_t;
5171+
5172+
statvfs_t stats;
5173+
auto err = () @trusted {
5174+
return statvfs(path.toStringz(), &stats);
5175+
} ();
5176+
cenforce(err == 0, "Cannot get available disk space");
5177+
5178+
return stats.f_bavail * stats.f_frsize;
5179+
}
5180+
}
5181+
else static assert(0, "Unsupported platform");
5182+
}
5183+
5184+
///
5185+
@safe unittest
5186+
{
5187+
import std.exception : assertThrown;
5188+
5189+
auto space = getAvailableDiskSpace(".");
5190+
assert(space > 0);
5191+
5192+
assertThrown!FileException(getAvailableDiskSpace("ThisFileDoesNotExist123123"));
5193+
}

0 commit comments

Comments
 (0)