powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Как определить размер файла, если он больше 2 Гб?
15 сообщений из 15, страница 1 из 1
Как определить размер файла, если он больше 2 Гб?
    #34067193
Фотография Joss
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Для работы мне необходимо определить размер файла, размер диска и размер свободного места на диске. Использовать FSO (FileSystemObject) нельзя, так как он работает при объемах до 2 Гб. А если больше?
Для определения свободного места на диске я воспользовался функцией API - GetDiskFreeSpaceEx. Всё отработало нормально.
А вот с определением размера файла - проблема. Я использую функцию API - GetFileSize. Для файлов до 2 Гб она работает нормально, а вот потом сбоит. И я непойму, в чем тут дело.
Пример кода
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
' This code is licensed according to the terms and conditions listed here.

' Declarations and such needed for the example:
' (Copy them to the (declarations) section of a module.)
Public Type ULARGE_INTEGER
    LowPart As Long
    HighPart As Long
End Type

Public Type SECURITY_ATTRIBUTES
    nLength As Long
    lpSecurityDescriptor As Long
    bInheritHandle As Long
End Type


Const GENERIC_READ = &H80000000
Const GENERIC_WRITE = &H40000000
Const FILE_SHARE_READ = &H1
Const FILE_SHARE_WRITE = &H2
Const CREATE_ALWAYS =  2 
Const CREATE_NEW =  1 
Const OPEN_ALWAYS =  4 
Const OPEN_EXISTING =  3 
Const TRUNCATE_EXISTING =  5 
Const FILE_ATTRIBUTE_ARCHIVE = &H20
Const FILE_ATTRIBUTE_HIDDEN = &H2
Const FILE_ATTRIBUTE_NORMAL = &H80
Const FILE_ATTRIBUTE_READONLY = &H1
Const FILE_ATTRIBUTE_SYSTEM = &H4
Const FILE_FLAG_DELETE_ON_CLOSE = &H4000000
Const FILE_FLAG_NO_BUFFERING = &H20000000
Const FILE_FLAG_OVERLAPPED = &H40000000
Const FILE_FLAG_POSIX_SEMANTICS = &H1000000
Const FILE_FLAG_RANDOM_ACCESS = &H10000000
Const FILE_FLAG_SEQUENTIAL_SCAN = &H8000000
Const FILE_FLAG_WRITE_THROUGH = &H80000000

Public Declare Function GetFileSize Lib "kernel32.dll" (ByVal hFile As Long, lpFileSizeHigh As Long) As Long
Public Declare Function CreateFile Lib "kernel32.dll" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, _
   ByVal dwShareMode As Long, lpSecurityAttributes As Any, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, _
   ByVal hTemplateFile As Long) As Long
Public Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Public Declare Function GetLastError Lib "kernel32.dll" () As Long

' *** Place the following code inside the form window. ***

Public Function sbFileSize()

   On Error GoTo sbFileSize_Error

' Display the file size of "C:\BaseBdPortal_new_log.ldf".  Note how
' the alternate declare of the CreateFile function (needed to get the file's handle)
' must be used -- see that function's page for details.
Dim hFile As Long  ' receives a handle to the file
Dim loworder As Long, highorder As Long  ' receive the low- and high-order halves of the file size
Dim retval As Long  ' return value
Dim errorcode As Long  ' error code

' Get a handle to the file using CreateFile's alternate declare (necessary for non-Win NT).
hFile = CreateFile("C:\BaseBdPortal_new_log.ldf", GENERIC_READ, FILE_SHARE_READ, ByVal CLng( 0 ), OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE,  0 )

If hFile = - 1  Then  ' error opening the file
  Debug.Print "Could not open file C:\DimS\BaseBdPortal_new_log.ldf"
  End  ' abort the program
End If

' Read and display that file's size in bytes.
highorder =  0   ' initialize the value for high-order half
loworder = GetFileSize(hFile, highorder)  ' read the file's size
If highorder =  0  Then  ' if there is no high-order part
  Debug.Print "File size:"; loworder; "bytes"  ' display the file size
Else  ' if there is a high-order part (file size >= 4.29 GB!)
  ' Visual Basic has no 64-bit variables, so we can't display the actual value:
  Debug.Print "File size:"; highorder; "* 2^32 +"; loworder; "bytes (in base-10)"
  ' But we can combine the two hex values to give the result in hexadecimal:
  Debug.Print "File size: "; Hex(highorder); Hex(loworder); " bytes (in hexadecimal)"
End If

' Close the file
retval = CloseHandle(hFile)  ' close the handle

   On Error GoTo  0 
Exit_sbFileSize:
   Exit Function

sbFileSize_Error:

    MsgBox "Ошибка " & Err.Number & " (" & Err.Description & ") в процедуре sbFileSize"
    Resume Exit_sbFileSize

End Function

А API для определения размера диска я пока не нашел.
...
Рейтинг: 0 / 0
Как определить размер файла, если он больше 2 Гб?
    #34067242
Фотография Бенедикт
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GetDiskFreeSpaceEx
...
Рейтинг: 0 / 0
Как определить размер файла, если он больше 2 Гб?
    #34067247
Фотография Бенедикт
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тьфу. Прочитал по диагонали, пардон.
...
Рейтинг: 0 / 0
Как определить размер файла, если он больше 2 Гб?
    #34067374
Фотография Бенедикт
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Joss,
на NTFS почти всё с этим кодом в порядке. "Почти" потому, что для файлов с размером 2^31..2^32-2 выдастся сообщение с отрицательным размером файла - из-за того, что размер печатается как signed long, а не как unsigned long.
...
Рейтинг: 0 / 0
Как определить размер файла, если он больше 2 Гб?
    #34067404
Фотография Aklin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
БенедиктJoss,
на NTFS почти всё с этим кодом в порядке. "Почти" потому, что для файлов с размером 2^31..2^32-2 выдастся сообщение с отрицательным размером файла - из-за того, что размер печатается как signed long, а не как unsigned long.

тогда если файл больше 4гб, тебе покажыт значительно более низкую цифру. если вообще покажут
...
Рейтинг: 0 / 0
Как определить размер файла, если он больше 2 Гб?
    #34067459
Фотография Joss
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У меня файл имеет размер 3 563 978 752 байта. А программа выдает
Код: plaintext
File size:-730988544 bytes
И что делать?
...
Рейтинг: 0 / 0
Как определить размер файла, если он больше 2 Гб?
    #34067547
Фотография Бенедикт
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Joss,
ну, правильно.
-730988544l = 0xD46E0000 = 3563978752ul. Что делать - показывать его, как unsigned.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
Function ULong2Double(ByVal ULong As Long) As Double
 If ULong >=  0  Then
    ULong2Double = ULong
 Else
    ULong2Double = CDbl(ULong And &H7FFFFFFF) +  2147483648 #
 End If
End Function
...
Рейтинг: 0 / 0
Как определить размер файла, если он больше 2 Гб?
    #34067560
Фотография Бенедикт
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Aklin,
проблема только с показом - проблем с двоичным представлением нет.
...
Рейтинг: 0 / 0
Как определить размер файла, если он больше 2 Гб?
    #34067620
Фотография k-nike
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JossИспользовать FSO (FileSystemObject) нельзя, так как он работает при объемах до 2 Гб.
Почему?
Вот расширенный пример на все параметры файла на VBA из книжки. Все прекрасно работает.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
Sub FileInfo()
    Dim fs As New FileSystemObject
    Dim ft As File
    Dim fn As String
    fn = "E:\video.rar"
    If fs.fileexists(fn) Then
        Dim s As String
        Dim f As File
        Set f = fs.getfile(fn)
        s = "File " & UCase(fn) & vbCr
        s = s & "Date Created: " & f.dateCreated & vbCr
        s = s & "Date Last Accessed: " & f.datelastaccessed & vbCr
        s = s & "Date Last Modified: " & f.datelastModified & vbCr
        s = s & "Paren Folder: " & f.Parentfolder.Name & vbCr
        s = s & "Path: " & f.Path & vbCr
        s = s & "Type: " & f.Type & vbCr
        s = s & "Size: " & f.Size & " bytes" & vbCr
        If f.Attributes And  0  Then s = s & "Normal attribute" & vbCr
        If f.Attributes And  1  Then s = s & "Read only attribute" & vbCr
        If f.Attributes And  2  Then s = s & "Hidden attribute" & vbCr
        If f.Attributes And  4  Then s = s & "System attribute" & vbCr
        If f.Attributes And  16  Then s = s & "Directory attribute" & vbCr
        If f.Attributes And  32  Then s = s & "Archive attribute" & vbCr
        If f.Attributes And  128  Then s = s & "Compressed attribute" & vbCr
        MsgBox s
    End If
End Sub
...
Рейтинг: 0 / 0
Как определить размер файла, если он больше 2 Гб?
    #34067648
Фотография Joss
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
to Бенедикт
А что означает число 2147483648#
...
Рейтинг: 0 / 0
Как определить размер файла, если он больше 2 Гб?
    #34067689
Фотография Joss
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
to Бенедикт
Извини, затуркался 2Гб = 2147483648#

to k-nike

Проверил - работает, но и справочнике В.И. Короля и на MSDN (только сегодня лазил) утверждают, что правильный размер только для файлов менее 2 Гб. А из какой книги ты брал пример?

-------------------------------
А, ты, вложил уже свой кровный рубль в 50-ти миллиардное состояние Билла Гейтса?
...
Рейтинг: 0 / 0
Как определить размер файла, если он больше 2 Гб?
    #34067714
Фотография k-nike
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JossА из какой книги ты брал пример?
"Самоучитель VBA" 2-ое издание, Андрей Гарнаев, "БХВ-Петербург"
...
Рейтинг: 0 / 0
Как определить размер файла, если он больше 2 Гб?
    #34067735
Фотография Бенедикт
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Joss,
FileSystemObject.Size возвращает Variant. До 2^31-1 этот Variant имеет подтип Long, а для 2^31..(предположительно)2^53-1 - Double. Для практических целей достаточно. Но, возможно, так было не во всех версиях Scripting Runtime.
...
Рейтинг: 0 / 0
Как определить размер файла, если он больше 2 Гб?
    #34068013
Фотография orunbek
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У меня через FSO прекрасно выводит информацию о размерах, файлов, у которых он более чем 2 гига, а именно 4 гига и т.д.
...
Рейтинг: 0 / 0
Как определить размер файла, если он больше 2 Гб?
    #34068064
Фотография Бенедикт
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Joss,
я тоже слегка "затуркался".
4294967296# + ULong
будет побыстрее, чем
CDbl(ULong And &H7FFFFFFF) + 2147483648#
...
Рейтинг: 0 / 0
15 сообщений из 15, страница 1 из 1
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Как определить размер файла, если он больше 2 Гб?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]