加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Windows > 正文

windows – 将文件大小转换为文本表示

发布时间:2020-12-14 04:26:27 所属栏目:Windows 来源:网络整理
导读:我正在建立在线文件管理器.它显示的一个列是文件大小,但这总是很大的字节数.我想像 Windows资源管理器一样显示文件大小,使用较小的数字和适当的单位,例如5 MB而不是5000000. 这对我来说并不难,但我想知道Windows而不是内置函数来做到这一点.有没有东西,或者
我正在建立在线文件管理器.它显示的一个列是文件大小,但这总是很大的字节数.我想像 Windows资源管理器一样显示文件大小,使用较小的数字和适当的单位,例如5 MB而不是5000000.

这对我来说并不难,但我想知道Windows而不是内置函数来做到这一点.有没有东西,或者我必须自己动手?

解决方法

以下是C#中的两个变体(它们需要Windows Vista):

...
Console.WriteLine(FormatByteSize(1031023120)); // 983 MB
Console.WriteLine(FormatByteSize2(1031023120,true)); // 1?006?859 KB
...

请注意,使用Windows的好处(或不方便,具体取决于您的使用方式)是使用Shell / OS文化获得本地化版本(如果有).

public static string FormatByteSize2(long size,bool alwaysKb = false)
{
    // Here,we use Windows Shell's size column definition and formatting
    // note although System.Size is defined as a UInt64,formatting doesn't support more than long.MaxValue...
    PSGetPropertyKeyFromName("System.Size",out var pk);
    var pv = new PROPVARIANT(size);
    var sb = new StringBuilder(128);
    const int PDFF_ALWAYSKB = 4;
    PSFormatForDisplay(ref pk,pv,alwaysKb ? PDFF_ALWAYSKB : 0,sb,sb.Capacity);
    return sb.ToString();
}

public static string FormatByteSize(long size)
{
    // Here,we use use a Windows Shell API (probably the sames algorithm underneath)
    // It's much simpler,we only need to declare one StrFormatByteSizeW API
    var sb = new StringBuilder(128);
    StrFormatByteSizeW(size,sb.Capacity);
    return sb.ToString();
}

[DllImport("shlwapi",CharSet = CharSet.Unicode)]
private static extern IntPtr StrFormatByteSizeW(long qdw,[MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszBuf,int cchBuf);

[DllImport("propsys",CharSet = CharSet.Unicode)]
private static extern int PSFormatForDisplay(
    ref PROPERTYKEY propkey,PROPVARIANT pv,int pdfFlags,CharSet = CharSet.Unicode)]
private static extern int PSGetPropertyKeyFromName([MarshalAs(UnmanagedType.LPWStr)] string pszName,out PROPERTYKEY ppropkey);

[StructLayout(LayoutKind.Sequential)]
private struct PROPERTYKEY
{
    public Guid fmtid;
    public int pid;
}

[StructLayout(LayoutKind.Sequential)]
private class PROPVARIANT
{
    // note this version of PROPVARIANT is far from being suited for all purposes...
    public short vt;
    short wReserved1;
    short wReserved2;
    short wReserved3;
    public long val;

    const short VT_UI8 = 21;

    public PROPVARIANT(long ul)
    {
        wReserved3 = wReserved2 = wReserved1 = 0;
        val = ul;
        vt = VT_UI8;
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读