Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Как определить размер файла, если он больше 2 Гб? / 15 сообщений из 15, страница 1 из 1
19.10.2006, 15:52
    #34067193
Joss
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как определить размер файла, если он больше 2 Гб?
Для работы мне необходимо определить размер файла, размер диска и размер свободного места на диске. Использовать 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
19.10.2006, 16:03
    #34067242
Бенедикт
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как определить размер файла, если он больше 2 Гб?
GetDiskFreeSpaceEx
...
Рейтинг: 0 / 0
19.10.2006, 16:04
    #34067247
Бенедикт
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как определить размер файла, если он больше 2 Гб?
Тьфу. Прочитал по диагонали, пардон.
...
Рейтинг: 0 / 0
19.10.2006, 16:32
    #34067374
Бенедикт
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как определить размер файла, если он больше 2 Гб?
Joss,
на NTFS почти всё с этим кодом в порядке. "Почти" потому, что для файлов с размером 2^31..2^32-2 выдастся сообщение с отрицательным размером файла - из-за того, что размер печатается как signed long, а не как unsigned long.
...
Рейтинг: 0 / 0
19.10.2006, 16:40
    #34067404
Aklin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как определить размер файла, если он больше 2 Гб?
БенедиктJoss,
на NTFS почти всё с этим кодом в порядке. "Почти" потому, что для файлов с размером 2^31..2^32-2 выдастся сообщение с отрицательным размером файла - из-за того, что размер печатается как signed long, а не как unsigned long.

тогда если файл больше 4гб, тебе покажыт значительно более низкую цифру. если вообще покажут
...
Рейтинг: 0 / 0
19.10.2006, 17:03
    #34067459
Joss
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как определить размер файла, если он больше 2 Гб?
У меня файл имеет размер 3 563 978 752 байта. А программа выдает
Код: plaintext
File size:-730988544 bytes
И что делать?
...
Рейтинг: 0 / 0
19.10.2006, 17:29
    #34067547
Бенедикт
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как определить размер файла, если он больше 2 Гб?
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
19.10.2006, 17:31
    #34067560
Бенедикт
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как определить размер файла, если он больше 2 Гб?
Aklin,
проблема только с показом - проблем с двоичным представлением нет.
...
Рейтинг: 0 / 0
19.10.2006, 17:42
    #34067620
k-nike
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как определить размер файла, если он больше 2 Гб?
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
19.10.2006, 17:48
    #34067648
Joss
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как определить размер файла, если он больше 2 Гб?
to Бенедикт
А что означает число 2147483648#
...
Рейтинг: 0 / 0
19.10.2006, 17:56
    #34067689
Joss
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как определить размер файла, если он больше 2 Гб?
to Бенедикт
Извини, затуркался 2Гб = 2147483648#

to k-nike

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

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


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