【问题标题】:How to return KB, MB and GB from Bytes using a public function如何使用公共函数从 Bytes 返回 KB、MB 和 GB
【发布时间】:2014-12-08 21:22:35
【问题描述】:

我正在编写一个返回文件大小(以 B、KB、MB、GB 为单位)的“函数”。

VB.Net 代码总是首先获取以字节为单位的大小,因此当文件的大小(以字节为单位)小于 100 时,它返回 B,如果 > 1000,则我将其除以 1000,然后返回 KB。但是当它应该是 MB 时,我尝试除以 1000000,它返回的大小总是比它应该的大小大 2 MB!?

谁能告诉我我做错了什么!!

示例

我的文件大小是 (15,570,550 字节) ..这是.. (14.8 MB)

所以当我通过这个函数运行它时,它返回 16MB!

代码

Public Function GetFileSize(ByVal TheFile As String, _
                            Optional ByVal ShowSizeType As Boolean = False) As String
    If TheFile.Length = 0 Then Return ""
    If Not System.IO.File.Exists(TheFile) Then Return ""
    '---
    Dim TheSize As Integer = My.Computer.FileSystem.GetFileInfo(TheFile).Length
    Dim SizeType As String = ""
    '---
    If TheSize < 1000 Then
        SizeType = "B"
    Else
        If TheSize < 1000000000 Then
            If TheSize < 1000000 Then
                SizeType = "KB"
                TheSize = TheSize / 1000
            Else
                SizeType = "MB"
                TheSize = TheSize / 1000000
            End If
        Else
            SizeType = "GB"

        End If
    End If
    '---
    If ShowSizeType = True Then
        Return TheSize & SizeType
    Else
        Return TheSize
    End If
End Function

【问题讨论】:

  • 计算机使用二进制。 Binary = Base 2...Decimal = Base 10。你应该使用2^x...
  • 阅读其他人发布的内容,但要回答您的具体问题:它会将 15570550/1000000 舍入,即 15.57 到 16 以将其存储在您的整数变量中。
  • 照 roryap 说的做。将它除以 1024。此外,为了使代码更简单,例如使用 (1024 ^ 2) 而不是像 1 048 576 那样计算它。并且如果您希望输出具有小数点,则可以将 TheSize 声明为小数点并使用 TheSize = Math.Round(TheSize / (1024 ^ 2), 1)

标签: vb.net visual-studio-2010 .net-4.0


【解决方案1】:

我会使用选择案例而不是 if。
并且总是从最大的尺寸开始。”我停在 TB 但 Corse 如果你需要,你可以添加更多......”

我将 Dim TheSize As Integer 更改为“Dim TheSize As ULong”,否则大数字不起作用。

另外制作一个暗淡的“Dim DoubleBytes As Double”,您将在选择案例中使用它。

首先你将你拥有的字节与一个案例进行比较,比如说 mb "Case 1048576 To 1073741823"
因此,如果是这种情况,请将 TheSize 转换为双倍 "DoubleBytes = CDbl(TheSize / 1048576) 'MB "

然后在返回中使用 FormatNumber 设置要在 . “nuber 2 将其设置为 2 后面。就像 28.11 一样,将其更改为 0 它将返回 28”也是因为您知道它 mb 您将在返回值中添加 & mb。
"返回 FormatNumber(DoubleBytes, 2) & "MB" "

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    MsgBox(GetFileSize("E:\Software\TeamSpeak3-Client-win64-3.0.14.exe"))
End Sub

Dim DoubleBytes As Double

Public Function GetFileSize(ByVal TheFile As String) As String
    If TheFile.Length = 0 Then Return ""
    If Not System.IO.File.Exists(TheFile) Then Return ""
    '---
    Dim TheSize As ULong = My.Computer.FileSystem.GetFileInfo(TheFile).Length
    Dim SizeType As String = ""
    '---

    Try
        Select Case TheSize
            Case Is >= 1099511627776
                DoubleBytes = CDbl(TheSize / 1099511627776) 'TB
                Return FormatNumber(DoubleBytes, 2) & " TB"
            Case 1073741824 To 1099511627775
                DoubleBytes = CDbl(TheSize / 1073741824) 'GB
                Return FormatNumber(DoubleBytes, 2) & " GB"
            Case 1048576 To 1073741823
                DoubleBytes = CDbl(TheSize / 1048576) 'MB
                Return FormatNumber(DoubleBytes, 2) & " MB"
            Case 1024 To 1048575
                DoubleBytes = CDbl(TheSize / 1024) 'KB
                Return FormatNumber(DoubleBytes, 2) & " KB"
            Case 0 To 1023
                DoubleBytes = TheSize ' bytes
                Return FormatNumber(DoubleBytes, 2) & " bytes"
            Case Else
                Return ""
        End Select
    Catch
        Return ""
    End Try
End Function

我为它制作了一个 dll。
然后我可以将它导入到我的项目中,我可以在需要将字节数更改为其他“如 mb 等”时调用它
FormatBytes(GetHDSizeF) "GetHDSizeF 为字节数"

Dim DoubleBytes As Double
Default Public Property FormatBytes(ByVal BytesCaller As ULong) As String
    Get
        Try
            Select Case BytesCaller
                Case Is >= 1099511627776
                    DoubleBytes = CDbl(BytesCaller / 1099511627776) 'TB
                    Return FormatNumber(DoubleBytes, 2) & " TB"
                Case 1073741824 To 1099511627775
                    DoubleBytes = CDbl(BytesCaller / 1073741824) 'GB
                    Return FormatNumber(DoubleBytes, 2) & " GB"
                Case 1048576 To 1073741823
                    DoubleBytes = CDbl(BytesCaller / 1048576) 'MB
                    Return FormatNumber(DoubleBytes, 2) & " MB"
                Case 1024 To 1048575
                    DoubleBytes = CDbl(BytesCaller / 1024) 'KB
                    Return FormatNumber(DoubleBytes, 2) & " KB"
                Case 0 To 1023
                    DoubleBytes = BytesCaller ' bytes
                    Return FormatNumber(DoubleBytes, 2) & " bytes"
                Case Else
                    Return ""
            End Select
        Catch
            Return ""
        End Try
    End Get
    Set(value As String)

    End Set
End Property

如果您不想制作 dll,您可以像这样使用普通函数。

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    MsgBox(FormatBytes(2000))
End Sub

Dim DoubleBytes As Double
Public Function FormatBytes(ByVal BytesCaller As ULong) As String

    Try
        Select Case BytesCaller
            Case Is >= 1099511627776
                DoubleBytes = CDbl(BytesCaller / 1099511627776) 'TB
                Return FormatNumber(DoubleBytes, 2) & " TB"
            Case 1073741824 To 1099511627775
                DoubleBytes = CDbl(BytesCaller / 1073741824) 'GB
                Return FormatNumber(DoubleBytes, 2) & " GB"
            Case 1048576 To 1073741823
                DoubleBytes = CDbl(BytesCaller / 1048576) 'MB
                Return FormatNumber(DoubleBytes, 2) & " MB"
            Case 1024 To 1048575
                DoubleBytes = CDbl(BytesCaller / 1024) 'KB
                Return FormatNumber(DoubleBytes, 2) & " KB"
            Case 0 To 1023
                DoubleBytes = BytesCaller ' bytes
                Return FormatNumber(DoubleBytes, 2) & " bytes"
            Case Else
                Return ""
        End Select
    Catch
        Return ""
    End Try

End Function

【讨论】:

    【解决方案2】:

    您需要除以 1024 而不是 1000。1 KB 不是 1000 字节,而是 1024 字节。 1 MB 不是 1000 KB,而是 1024 KB,以此类推。

    这里有一个很好的网站来解释这一切:http://pc.net/helpcenter/answers/why_1024_bytes

    【讨论】:

      【解决方案3】:

      我是这样做的,下面是我在 Microsoft Access 中使用的 VBA 函数,可以轻松转换为 VB 或 VBScript 等。

      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
      

      【讨论】:

      • 这比选择案例要好得多。这与您在纸上的工作方式相同。
      【解决方案4】:

      当我试图解决这个问题时,这篇文章帮助了我学习 C#,我通常使用 VB。无论如何,我想我会发布我的更新,以防有人愿意使用它。 它在 VB 中,因为我有一个有用的函数和子库,我用来保存这些东西,我在 VB 中启动它,懒得更改所有代码。它对我很有效,所以我希望它可以帮助别人。

      Function ByteConv(Bytes As Double, Optional Style As Integer = 1) As String
      
          Dim count As Integer = 0
          Dim factor As Integer = 1024
          Dim Workingnum As Double = Bytes
          Dim Suffix() As String = {"Bytes", "Kb", "Mb", "Tb", "Pb", "Eb"} 'Dimention the string array upto Exobyte .. Cos why not?'
      
          If Style - 1 Then factor = 1000 Else factor = 1024  'This allows for Function to be used for Comms Calculations. I.e So it returns 100MB connection rather than 95.37'
      
          While Workingnum > factor And count < 5             'Basically keep dividing the Bytecount by the factor until the result reaches a whole number less that the factor itself'
              Workingnum = Workingnum / factor                ' '
              count = count + 1
          End While
          Return Workingnum.ToString("N") + Suffix(count)     ' Then return a string that includes the result and the applicable suffix.'
      End Function
      

      【讨论】:

      • 只是为了确认一下,If Style - 1 不应该是 If Style = -1 吗?使用Option Strict On 否则会出现错误。我将那个位重写为三元组(我喜欢三元组:P)factor = If(intStyle = -1, 1000, 1024)
      • 您忘记了 Suffix() 数组中的 Gb 吗?
      【解决方案5】:

      这是我在评论中的意思的一个例子:

      Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
      
          If OpenFileDialog1.ShowDialog() = Windows.Forms.DialogResult.OK Then
              Dim CalculatedSize As Decimal
              Dim TheSize As Long = Long.Parse(My.Computer.FileSystem.GetFileInfo(OpenFileDialog1.FileName).Length)
              Dim SizeType As String = "B"
      
              If TheSize < 1024 Then
                  CalculatedSize = TheSize
      
              ElseIf TheSize > 1024 AndAlso TheSize < (1024 ^ 2) Then 'KB
                  CalculatedSize = Math.Round((TheSize / 1024), 2)
                  SizeType = "KB"
      
              ElseIf TheSize > (1024 ^ 2) AndAlso TheSize < (1024 ^ 3) Then 'MB
                  CalculatedSize = Math.Round((TheSize / (1024 ^ 2)), 2)
                  SizeType = "MB"
      
              ElseIf TheSize > (1024 ^ 3) AndAlso TheSize < (1024 ^ 4) Then 'GB
                  CalculatedSize = Math.Round((TheSize / (1024 ^ 3)), 2)
                  SizeType = "GB"
      
              ElseIf TheSize > (1024 ^ 4) Then 'TB
                  CalculatedSize = Math.Round((TheSize / (1024 ^ 4)), 2)
                  SizeType = "TB"
      
              End If
      
              MessageBox.Show("File size is: " & CalculatedSize.ToString & " " & SizeType, "File size", MessageBoxButtons.OK, MessageBoxIcon.Information)
          End If
      End Sub
      

      结果:

      【讨论】:

        【解决方案6】:
          Public Function GetDirSize(RootFolder As String) As Long
                Dim FolderInfo = New IO.DirectoryInfo(RootFolder)
                For Each File In FolderInfo.GetFiles : TotalSize += File.Length
                Next
                For Each SubFolderInfo In FolderInfo.GetDirectories : GetDirSize(SubFolderInfo.FullName)
                Next
                Return TotalSize
            End Function
        
            Public Sub GetfilesizeFromDirectory()
                Dim path As String
                path = "D:"
                TotalSize = 0 'Reset the counter
                Dim TheSize As Long = GetDirSize(path)
                ' TextBox1.Text = (FormatNumber(TheSize / 1024 / 1024 / 1) & vbCr & "MB")
            End Sub
        

        【讨论】:

          猜你喜欢
          • 2010-09-28
          • 1970-01-01
          • 2012-11-12
          • 1970-01-01
          • 2017-11-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多