.Net Core ค้นหาพื้นที่ว่างในดิสก์บนระบบปฏิบัติการที่แตกต่างกัน

มีวิธีค้นหาพื้นที่ว่างบนระบบปฏิบัติการต่าง ๆ (ส่วนใหญ่เป็น Linux และ Windows) โดยใช้ C# ASP.NET Core หรือไม่

ฉันพบวิธี (โดยใช้ DriveInfo) ในการเพิ่มพื้นที่ว่างโดยส่งชื่อไดรฟ์เป็นพารามิเตอร์ สิ่งนี้ทำงานได้ดีบน Windows แต่ฉันก็ต้องการเช่นเดียวกันสำหรับ Linux เช่นกัน

public static int CheckDiskSpace(string driveLetter)
{
    DriveInfo drive = new DriveInfo(driveLetter);

    var totalBytes = drive.TotalSize;
    var freeBytes = drive.AvailableFreeSpace;

    var freePercent = (int)((100 * freeBytes) / totalBytes);

    return freePercent;
}

ผ่านการ Drive (C:/) ดังนี้

var freespace = DriveDetails.CheckDiskSpace("C:/");

อัปเดต: ใช้ได้กับ Linux ด้วย


person Dot Net Dev    schedule 17.07.2018    source แหล่งที่มา
comment
คุณทราบดีว่าโค้ดของคุณซึ่งทำงานเป็นส่วนหนึ่งของแอปพลิเคชัน ASP.NET Core ทำงานบนเซิร์ฟเวอร์ ไม่ใช่บนไคลเอนต์ใช่ไหม ดังนั้นคุณจะได้รับข้อมูลเดียวกันเสมอ ซึ่งก็คือพื้นที่ดิสก์ของเซิร์ฟเวอร์   -  person Camilo Terevinto    schedule 18.07.2018
comment
ชื่อคำถามของฉันได้รับการแก้ไข ฉันต้องหาพื้นที่ว่างในดิสก์ของแอปพลิเคชันบนระบบปฏิบัติการอื่น   -  person Dot Net Dev    schedule 18.07.2018
comment
@ johnny5 ที่ซ้ำกันนั้นไม่ได้ใกล้เคียงกับสิ่งที่ถูกถามที่นี่ด้วยซ้ำ OP ต้องการเส้นทางของแอปพลิเคชันที่กำลังทำงานอยู่ ไม่ใช่ของซอร์สโค้ด การแก้ไขไม่เหมาะสมอย่างยิ่ง   -  person Camilo Terevinto    schedule 18.07.2018
comment
ความผิดพลาดของฉัน แต่ชื่อปัจจุบันทำให้เข้าใจผิดคำถามนี้เกี่ยวข้องกับการค้นหาเส้นทางไม่ใช่พื้นที่ดิสก์   -  person johnny 5    schedule 18.07.2018
comment
@ johnny5 การค้นหาเส้นทางเป็นส่วนหนึ่งของคำถาม คำถามหลักคือการหาพื้นที่ดิสก์   -  person Dot Net Dev    schedule 18.07.2018
comment
Dot Net Dev คุณบอกว่าคุณได้พบวิธีใช้ข้อมูลไดรฟ์แล้ว คำถามนี้เกี่ยวข้องกับการได้รับเส้นทางมากกว่านั้นไม่ใช่หรือ?   -  person johnny 5    schedule 18.07.2018
comment
@ johnny5 ฉันพบวิธีใน Windows ฉันต้องการสิ่งที่ใช้ได้กับ Windows, Linux   -  person Dot Net Dev    schedule 18.07.2018


คำตอบ (2)


สำหรับ Net.Core ภายใต้ Linux คุณสามารถโทรได้

var freeBytes = new DriveInfo(path).AvailableFreeSpace; 

โดยที่ path คือชื่อโฟลเดอร์แบบสัมพัทธ์หรือแบบสัมบูรณ์ และจะให้ข้อมูลไดรฟ์เกี่ยวกับพาร์ติชันที่เก็บพาธนี้แก่คุณโดยอัตโนมัติ ทดสอบบน Net.Core 2.2

ในทางตรงกันข้าม ใน Windows คุณ:

A) จำเป็นต้องจัดเตรียมอักษรระบุไดรฟ์ (ซึ่งน่าเสียดายที่ไม่สามารถรับมาจากเส้นทางสัมพัทธ์ได้โดยตรง ดังนั้นคุณต้องทำงานเพิ่มเติม และไม่สามารถคำนวณสำหรับเส้นทาง UNC ได้เลย)

B) จำเป็นต้องใช้ Windows API (ใช้ได้กับเส้นทาง UNC ด้วย):

[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetDiskFreeSpaceEx(string lpDirectoryName,
    out ulong lpFreeBytesAvailable,
    out ulong lpTotalNumberOfBytes,
    out ulong lpTotalNumberOfFreeBytes);

GetDiskFreeSpaceEx(path, out var freeBytes, out var _, out var __);

นอกจากนี้ยังมีบางกรณีพิเศษอื่น ๆ ดังนั้นในที่สุดการใช้งานของฉันก็มีลักษณะดังนี้:

#if DEBUG        
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool GetDiskFreeSpaceEx(string lpDirectoryName,
    out long lpFreeBytesAvailable,
    out long lpTotalNumberOfBytes,
    out long lpTotalNumberOfFreeBytes);
#endif

public long? CheckDiskSpace()
{
    long? freeBytes = null;

    try     
    {
#if DEBUG //RuntimeInformation and OSPlatform seem to not exist while building for Linux platform
        if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
        {
            long freeBytesOut;
            //On some drives (for example, RAM drives, GetDiskFreeSpaceEx does not work
            if (GetDiskFreeSpaceEx(_path, out freeBytesOut, out var _, out var __))
                freeBytes = freeBytesOut;
        }
#endif

        if (freeBytes == null)
        {
            //DriveInfo works well on paths in Linux    //TODO: what about Mac?
            var drive = new DriveInfo(_path);
            freeBytes = drive.AvailableFreeSpace;
        }
    }
    catch (ArgumentException)
    {
        //ignore the exception
    }

    return freeBytes;
}
person Roland Pihlakas    schedule 18.07.2020

คุณสามารถใช้ System.AppContext.BaseDirectory หากคุณใช้ .Net Core

(OR)

Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)
person Rahul    schedule 17.07.2018