【问题标题】:Generic File Size Calculator通用文件大小计算器
【发布时间】:2013-09-17 18:27:39
【问题描述】:

我正在尝试编写一个通用函数来在文件大小、字节到 kb、gb 到 mb 等之间进行转换...

当“ToSize”值低于“FromSize”时问题开始,我没有得到正确的值。

有人可以帮我解决问题,也许可以简化所有代码?

#Region " Convert Between Sizes "

Enum FromSize As Long
    bytes = 1L
    kilobyte = 1024L
    megabyte = 1048576L
    gigabyte = 1073741824L
    terabyte = 1099511627776L
    petabyte = 1125899906842624L
End Enum

Enum ToSize As Long
    bytes = 1L
    kilobyte = 1024L
    megabyte = 1048576L
    gigabyte = 1073741824L
    terabyte = 1099511627776L
    petabyte = 1125899906842624L
End Enum

Private Function Size_To_Size(ByVal Size As Long, _
                              ByVal FromSize As FromSize, _
                              ByVal ToSize As ToSize, _
                              Optional ByVal decimals As Integer = 2 _
                              ) As Double

    Dim bytes As Double = Convert.ToDouble(Size * FromSize)
    Dim Kbs As Double = bytes * FromSize.kilobyte
    Dim mbs As Double = bytes * FromSize.megabyte
    Dim gbs As Double = bytes * FromSize.gigabyte
    Dim tbs As Double = bytes * FromSize.terabyte
    Dim pbs As Double = bytes * FromSize.petabyte

    If ToSize < FromSize Then

        Select Case ToSize
            Case ToSize.bytes : Return bytes
            Case ToSize.kilobyte : Return Kbs.ToString("n" & decimals)
            Case ToSize.megabyte : Return mbs.ToString("n" & decimals)
            Case ToSize.gigabyte : Return gbs.ToString("n" & decimals)
            Case ToSize.terabyte : Return tbs.ToString("n" & decimals)
            Case ToSize.petabyte : Return pbs.ToString("n" & decimals)
            Case Else : Return -1
        End Select

    ElseIf ToSize > FromSize Then

        Select Case ToSize
            Case ToSize.bytes : Return bytes
            Case ToSize.kilobyte : Return (Kbs / ToSize.kilobyte / 1024L).ToString("n" & decimals)
            Case ToSize.megabyte : Return (mbs / ToSize.megabyte / 1024L / 1024L).ToString("n" & decimals)
            Case ToSize.gigabyte : Return (gbs / ToSize.gigabyte / 1024L / 1024L / 1024L).ToString("n" & decimals)
            Case ToSize.terabyte : Return (tbs / ToSize.terabyte / 1024L / 1024L / 1024L / 1024L).ToString("n" & decimals)
            Case ToSize.petabyte : Return (pbs / ToSize.petabyte / 1024L / 1024L / 1024L / 1024L / 1024L).ToString("n" & decimals)
            Case Else : Return -1
        End Select

    Else ' ToSize = FromSize
        Return Size.ToString("n" & decimals)

    End If

End Function

#End Region

更新:

这给出了正确的结果:

    MsgBox(Size_To_Size(50, FromSize.gigabyte, ToSize.bytes).ToString("n2"))
    ' Result: 53,687,091,200

这不会给出正确的结果:

    msgbox(Size_To_Size(50, FromSize.gigabyte, ToSize.kilobyte).ToString("n2"))
    ' Result: 54.975.581.388.800,00
    ' Expected result: 52,428,800
    ' As shown here: http://www.t1shopper.com/tools/calculate/file-size/result/?size=50&unit=gigabytes

【问题讨论】:

  • 您能举一个输入示例以及预期和实际输出吗?
  • @Steven Doggart 当然,请看我的更新,谢谢!

标签: .net vb.net math filesize bitrate


【解决方案1】:

作为扩展

Imports System.Runtime.CompilerServices

Module UnitExtension

    Public Enum Units
        B = 0
        KB = 1 'kilo
        MB = 2 'mega
        GB = 3 'giga
        TB = 4 'tera
        PB = 5 'peta
        EB = 6 'exa
        ZB = 7 'zetta
        YB = 8 'yotta
        'add new values as needed
        Auto = -1
    End Enum
    'compute max value of enum
    Private ReadOnly maxU As Integer = [Enum].GetValues(GetType(Units)).Cast(Of Integer)().Max

    'kFactor should be set according to your use
    'see
    'http://physics.nist.gov/cuu/Units/prefixes.html
    'and
    'http://physics.nist.gov/cuu/Units/binary.html
    Private ReadOnly Kfactor As Integer = 1024 'or 1000

    <Extension()>
    Public Function ToUnit(ByVal theNumberToConvert As Object, _
                           Optional ByVal precision As Integer = 0, _
                           Optional ByVal whichUnit As Units = Units.Auto) As String

        Dim _aNumber As Double = CType(theNumberToConvert, Double) 'the number being converted
        Dim _fmt As String = "n" & precision.ToString 'format string

        Dim _unit As Integer
        If whichUnit = Units.Auto Then 'auto unit
            _unit = CInt(Math.Floor(Math.Log(_aNumber, Kfactor))) 'yes
            If _unit > maxU Then '> max unit
                _unit = maxU 'use max unit
            End If
        Else
            _unit = whichUnit 'no, force unit
        End If

        Dim _numberOfUnits As Double = _aNumber / (Kfactor ^ _unit) 'calculate number of units

        Return String.Format("{0} {1}", _numberOfUnits.ToString(_fmt), CType(_unit, Units))
    End Function

End Module

编辑:

单位到单位转换的重载

<Extension()>
Public Function ToUnit(ByVal theNumberToConvert As Object, _
                       fromUnit As Units, _
                       Optional ByVal precision As Integer = 0, _
                       Optional ByVal whichUnit As Units = Units.Auto) As String

    Dim _aNumber As Double = CType(theNumberToConvert, Double) * (Kfactor ^ fromUnit) 'the number being converted
    Dim _fmt As String = "n" & precision.ToString 'format string

    Dim _unit As Integer
    If whichUnit = Units.Auto Then 'auto unit
        _unit = CInt(Math.Floor(Math.Log(_aNumber, Kfactor))) 'yes
        If _unit > maxU Then '> max unit
            _unit = maxU 'use max unit
        End If
    Else
        _unit = whichUnit 'no, force unit
    End If

    Dim _numberOfUnits As Double = _aNumber / (Kfactor ^ _unit) 'calculate number of units

    Return String.Format("{0} {1}", _numberOfUnits.ToString(_fmt), CType(_unit, Units))
End Function

【讨论】:

  • 太棒了,谢谢,但这是将字节转换为其他单位,对吗?
  • 没错。添加从任何单元到任何单元的重载应该不难。
【解决方案2】:

你只是混淆了你的数学逻辑。要修复它,请更改以下内容:

Dim Kbs As Double = bytes * FromSize.kilobyte
Dim mbs As Double = bytes * FromSize.megabyte
Dim gbs As Double = bytes * FromSize.gigabyte
Dim tbs As Double = bytes * FromSize.terabyte
Dim pbs As Double = bytes * FromSize.petabyte

到这里:

Dim Kbs As Double = bytes / FromSize.kilobyte
Dim mbs As Double = bytes / FromSize.megabyte
Dim gbs As Double = bytes / FromSize.gigabyte
Dim tbs As Double = bytes / FromSize.terabyte
Dim pbs As Double = bytes / FromSize.petabyte

【讨论】:

  • 解决方案根本没有解决问题,但给了我一个思路,除数和乘数我都用过,谢谢!
【解决方案3】:

解决办法如下:

Enum Units As Long
    bytes = 1L
    kilobyte = 1024L
    megabyte = 1048576L
    gigabyte = 1073741824L
    terabyte = 1099511627776L
    petabyte = 1125899906842624L
End Enum

Private Function Size_To_Size(ByVal Size As Long, _
                              ByVal FromSize As Units, _
                              ByVal ToSize As Units, _
                              Optional ByVal decimals As Integer = 2 _
                              ) As Double

    Dim bytes As Double = Convert.ToDouble(Size * FromSize)
    Dim result As Double = 0

    If ToSize < FromSize Then

        Select Case ToSize
            Case Units.bytes : result = bytes
            Case Units.kilobyte : result = bytes / Units.kilobyte
            Case Units.megabyte : result = bytes / Units.megabyte
            Case Units.gigabyte : result = bytes / Units.gigabyte
            Case Units.terabyte : result = bytes / Units.terabyte
            Case Units.petabyte : result = bytes / Units.petabyte
            Case Else : Return -1
        End Select

    ElseIf ToSize > FromSize Then

        Select Case ToSize
            Case Units.bytes : result = bytes
            Case Units.kilobyte : result = bytes * Units.kilobyte / Units.kilobyte ^ 2
            Case Units.megabyte : result = bytes * Units.megabyte / Units.megabyte ^ 2
            Case Units.gigabyte : result = bytes * Units.gigabyte / Units.gigabyte ^ 2
            Case Units.terabyte : result = bytes * Units.terabyte / Units.terabyte ^ 2
            Case Units.petabyte : result = bytes * Units.petabyte / Units.petabyte ^ 2
            Case Else : Return -1
        End Select

    ElseIf ToSize = FromSize Then

        Return Size.ToString("n" & decimals)

    End If

    Return result.ToString("n" & decimals)

End Function

【讨论】:

    【解决方案4】:

    下面是我在 Microsoft Access 中使用的一个 VBA 函数,可以很容易地适应 VB。

    Public Function FormatFileSize(ByVal lngFileSize As Long) As String
    
      Dim x      As Integer:      x = 0
      Dim Suffix As String:  Suffix = ""
      Dim Result As Single:  Result = lngFileSize
    
      Do Until Int(Result) < 1000
         x = x + 1
         Result = Result / 1024
      Loop
    
      Result = Round(Result, 2)
    
      Select Case x
             Case 0
                  Suffix = "Bytes"
             Case 1 'KiloBytes
                  Suffix = "KB"
             Case 2 'MegaBytes
                  Suffix = "MB"
             Case 3 'GigaBytes
                  Suffix = "GB"
             Case 4 'TeraBytes
                  Suffix = "TB"
             Case 5 'PetaBytes
                  Suffix = "PB"
             Case 6 'ExaBytes
                  Suffix = "EB"
             Case 7 'ZettaBytes
                  Suffix = "ZB"
             Case 8 'YottaBytes
                  Suffix = "YB"
             Case Else
                  Suffix = "Too big to compute :)"
      End Select
    
      FormatFileSize = Format(Result, "#,##0.00") & " " & Suffix
    
    End Function 'FormatFileSize
    

    【讨论】:

      猜你喜欢
      • 2011-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-02
      • 1970-01-01
      • 2010-10-10
      • 2010-12-22
      • 2012-02-06
      相关资源
      最近更新 更多