Четверг, 03.07.2025, 23:51
Приветствую Вас Гость | RSSГлавная | Регистрация | Вход
Меню сайта
Категории раздела
Субклассирование элементов управления [3]
Приёмы субклассирования различных элементов управления для расширения их функциональных возможностей.
Вспомогательные функции [4]
Полезные советы, которые могут пригодиться во всех областях программирования
Мультимедиа [2]
Советы по работе над различными мультимедийными приложениями.
Необычные приложения [1]
Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0
Главная » Статьи » Программирование на Visual Basic » Вспомогательные функции

Определение размеров очень больших файлов

Для определения размера файла в VB6 существует встроенная функция FileLen. Она возвращает длину файла в байтах (тип Long). Таким образом, максимальный размер файла, который может определить эта функция - 2 Гб, так как для переменной типа Long это максимально допустимое значение. При попытке передать в функцию путь к файлу большего, чем 2 Гб, размера, возвращается ошибка (-1). Как же получает размеры таких файлов ОС Windows? Она пользуется при этом функциями GetFileSize и GetFileSizeEx. Рассмотрим более удобную для нас функцию GetFileSizeEx. На языке C она объявляется так:

BOOL GetFileSizeEx(HANDLE hFile, PLARGE_INTEGER lpFileSize);

Здесь lpFileSize - это указатель на объединение (Union) ULARGE_INTEGER, которое может представлять собой либо одно 64-битовое целое число, либо пользовательский тип, состоящий из двух 32-битовых переменных. Так как компилятор VB6 не поддерживает объединения, а также 64-битовые целые числа, выберем последний вариант.

Type ULARGE_INTEGER
 LowPart As Long
 HighPart As Long
End Type 'ULARGE_INTEGER

Declare Function GetFileSizeEx Lib "kernel32" ( _
ByVal hFile As Long, lpFileSize As ULARGE_INTEGER) As Long

Открыть файл для чтения и получить его дескриптор можно с помощью великолепной функции CreateFile:

Declare Function CreateFile Lib "kernel32" _
 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

Const OPEN_EXISTING = 3&
Const INVALID_HANDLE_VALUE = -1

Функция GetFileSizeEx в случае, если ей передан верный дескриптор, заполнит структуру ULARGE_INTEGER, но нам от этого не легче. Нас интересует численное значение размера файла. Как же нам прочитать его из невразумительной двухчастной структуры? К счастью, в VB6 есть тип данных Currency. Размер такой переменной как раз 8 байт, и этот тип поддерживает арифметические операции. Копируя 8 байт из ULARGE_INTEGER в переменную типа Currency с помощью функции CopyMemory, мы сможем прочитать размер файла в байтах (функция CopyMemory описана в статье LOWORD и HIWORD). Следует учесть, что Currency - это число с фиксированной запятой с точностью 4 знака, поэтому результат нужно будет умножить на 10000.

Напишем функцию для определения размера большого файла (разумеется, она будет работать и с маленькими):

Public Function GetBigFileSize(ByVal FilePath As String) As Currency
 Dim uli As ULARGE_INTEGER, hFile As Long
 Dim retVal As Currency, lret As Long
 
 'Открываем файл, и получаем его дескриптор
 hFile = CreateFile(FilePath, 0&, 0&, ByVal 0&, _
 OPEN_EXISTING, 0&, 0&)
 
 'Если файл не существует,
 'возвратим -1 (ошибка), и выходим
 If hFile = INVALID_HANDLE_VALUE Then
 retVal = -1@
 GoTo retLine
 End If
 
 'Получим размер файла
 lret = GetFileSizeEx(hFile, uli)
 
 'Если дескриптор верный,
 'закроем его, он больше не нужен
 If hFile <> INVALID_HANDLE_VALUE Then CloseHandle hFile
 
 'Если функция почему-то не сработала
 'возвратим -1 (ошибка), и выходим
 If lret = 0 Then
 retVal = -1@
 GoTo retLine
 End If
 
 'Копируем структуру в "человеческую" переменную
 CopyMemory ByVal VarPtr(retVal), ByVal VarPtr(uli), 8
 
 'Для корректного результата умножим на 10000
 retVal = retVal * 10000
 
retLine:
 GetBigFileSize = retVal
End Function 'GetBigFileSize

P. S. У некоторых снобов от программирования считается недостаточно изящным применение оператора GoTo. Цзяофани - люди простые, от земли, и они не гнушаются использовать этот удобный оператор. Представьте, насколько более непонятным сделался бы код вышеприведённой функции без него!

Автор - Цзяофань

Категория: Вспомогательные функции | Добавил: Xiaofang (11.06.2009)
Просмотров: 4065 | Рейтинг: 4.7/3 |
Всего комментариев: 2
2 Xiaofang  
Вот ещё одного отловил... biggrin

1 Сноб, с 20 летним стажем программинга VB6  
Да, в натуре, только реальные калеки используют Goto вместо циклов. Если руки крюки, это совершенно не значит, что оператор Goto приобрёл какие-то особенности и преимущества, не присущие ему в принципе.

Читай мануалы и доки, выясни какое время использует GOTO и какое использует Do:Loop например, учись писать не только удобно для себя, но ещё и оптимально для системы, а в прочем, вряд ли ты когда-нить будешь программистом.

З.Ы. Видимо такие умнички как ты, писали Виндовоз. :))))


Форма входа
Поиск
Друзья сайта
Антология советской песни
Сайт управляется системой uCoz