我正在尝试编写一个通用函数来将文件大小,字节转换为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
答案 0 :(得分:1)
你刚刚混淆了数学逻辑。要修复它,请更改:
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
答案 1 :(得分: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 :(得分:0)
以下是解决方案:
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
答案 3 :(得分:0)
下面是我在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