Как ускорить извлечение файла из ресурсов программы?

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
Watts[]n!
Постоялец
Постоялец
 
Сообщения: 573
Зарегистрирован: 11.02.2007 (Вс) 0:19

Как ускорить извлечение файла из ресурсов программы?

Сообщение Watts[]n! » 03.09.2007 (Пн) 22:58

Всем доброго времени суток!
Использую функцию для сохранения файла из ресурсов на жесткий диск:

Код: Выделить всё
Public Function GetBinary(File_Path As String, ByVal ID As Long, Resource As String) As Boolean
Dim File() As Byte
File = LoadResData(ID, Resource)

    If Len(File(1)) > 0 Then
   Open File_Path For Binary Access Write As #1
   Put #1, 1, File
   Close #1

   GetBinary = True
   Exit Function
    End If

GetBinary = False
End Function


Вопрос - можно ли как-нибудь оптимизировать ее скорость, потому что нужно извлечь файл размером 110 Мб?
А делается это при загрузке формы, и приходится очень долго ждать даже на новой "машине", что уж говорить про более медленные =)

VVitafresh
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1641
Зарегистрирован: 12.05.2005 (Чт) 14:44
Откуда: Херсон, UA

Сообщение VVitafresh » 03.09.2007 (Пн) 23:03

Зачем хранить такой большой файл в ресурасах?
Никакую проблему невозможно решить на том же уровне, на каком она возникла. Нужно стать выше этой проблемы, поднявшись на следующий уровень.

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 03.09.2007 (Пн) 23:05

Если у тебя 110 Мб в ресурсах, мало что поможет. Ты их в реестре храни лучше.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Lumen
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 841
Зарегистрирован: 03.12.2005 (Сб) 16:09
Откуда: Брянск

Сообщение Lumen » 03.09.2007 (Пн) 23:05

А может проще поставлять этот файл отдельно, пусть себе валяется рядом с программой.
Подпись проходит рефакторинг

Watts[]n!
Постоялец
Постоялец
 
Сообщения: 573
Зарегистрирован: 11.02.2007 (Вс) 0:19

Сообщение Watts[]n! » 03.09.2007 (Пн) 23:25

GSerg писал(а):Ты их в реестре храни лучше.

LOL :D

Lumen писал(а):А может проще поставлять этот файл отдельно, пусть себе валяется рядом с программой.

Желательно, чтобы все одним файлом шло.

Ладно, пошел прикручивать ProgressBar :cry:

iGrok
Артефакт VBStreets
Артефакт VBStreets
 
Сообщения: 4272
Зарегистрирован: 10.05.2007 (Чт) 16:11
Откуда: Сетевое сознание

Сообщение iGrok » 03.09.2007 (Пн) 23:30

Вы таки извращенец.. =)))
Создать экзешник на 110 мб.. Ты понимаешь, что всё это щастье в память грузится при запуске?
label:
cli
jmp label

Watts[]n!
Постоялец
Постоялец
 
Сообщения: 573
Зарегистрирован: 11.02.2007 (Вс) 0:19

Сообщение Watts[]n! » 03.09.2007 (Пн) 23:35

Подозреваю :oops:
Тогда возникает такой вопрос:
Помню, был у меня 1 GB экзешник (RAR-овский SFX-архив с GTA San Andreas), так он тоже что ли весь в память грузился?

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 03.09.2007 (Пн) 23:40

Раровский экзешник не есть экзешник с ресурсами. Там данные дописаны в конец образа и игнорируются загрузчиком.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Re: Как ускорить извлечение файла из ресурсов программы?

Сообщение jangle » 04.09.2007 (Вт) 9:11

Watts[]n! писал(а):Вопрос - можно ли как-нибудь оптимизировать ее скорость, потому что нужно извлечь файл размером 110 Мб?
А делается это при загрузке формы, и приходится очень долго ждать даже на новой "машине", что уж говорить про более медленные =)



Вместо LoadResData надо использовать Resource API функции LoadResource и т.д. :

Код: Выделить всё
Private Declare Function LoadResource Lib "kernel32" Alias "LoadResource" (ByVal hInstance As Long, ByVal hResInfo As Long) As Long


Файл сохраняй функцией WriteFile, скорость возрастет значительно:

Код: Выделить всё
Private Declare Function WriteFile Lib "kernel32" Alias "WriteFile" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToWrite As Long, lpNumberOfBytesWritten As Long, lpOverlapped As OVERLAPPED) As Long



iGrok
Вы таки извращенец.. =)))
Создать экзешник на 110 мб.. Ты понимаешь, что всё это щастье в память грузится при запуске?


Секция ресурсов, не отображается (не грузится) в память при запуске приложения. Выражаясь на старый манер - это оверлей, данные из которого программист подгружает сам по мере необходимости, используя Resource API.

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Re: Как ускорить извлечение файла из ресурсов программы?

Сообщение tyomitch » 04.09.2007 (Вт) 10:15

jangle писал(а):Вместо LoadResData надо использовать Resource API функции LoadResource и т.д. :

Файл сохраняй функцией WriteFile, скорость возрастет значительно:

Это умозрительное заключение, или ты проверил и сравнил?
Готов поспорить, что первое.


jangle писал(а):Секция ресурсов, не отображается (не грузится) в память при запуске приложения. Выражаясь на старый манер - это оверлей, данные из которого программист подгружает сам по мере необходимости, используя Resource API.

Отображается при запуске, грузится по первому обращению. Как и код / данные только для чтения, абсолютно так же.
Resource API процессом загрузки не управляют абсолютно никак.
Соответствия староманерным оверлеям нет абсолютно никакого.
Изображение

Watts[]n!
Постоялец
Постоялец
 
Сообщения: 573
Зарегистрирован: 11.02.2007 (Вс) 0:19

Сообщение Watts[]n! » 04.09.2007 (Вт) 15:05

Мало того, что 4 минуты тормозит (засекал =)), так только что заметил, что создается файл нулевого размера!
Хотя маленькие файлы создаются этой функцией на ура...

Для сравнения - Restorator 2007 извлекает этот файл чуть меньше, чем за 20 секунд.

Отсюда появилась бредовая идея - найти какой нибудь редактор ресурсов (желательно бесплатный и небольшой по размеру), поддерживающий ключи командной строки, и при запуске программы "скормить" ему путь для извлечения, тип ресурса и ID.

jangle!
Функция WriteFile не работает, чего-то вроде не хватает. Ругается на неопределенный пользовательский тип.

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 04.09.2007 (Вт) 15:15

Watts, лучше не майся дурью и не запихивай в ресурсы то, чему там не место. Лучше в отдельный NTFS-стрим запихни, тоже будет один файл.
Изображение

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 04.09.2007 (Вт) 15:19

Тогда файл будет сложно переносить на флешках, выкладывать в инете, отправлять почтой и т.п. Что-то большое лучше прицепить в конце файла, как это RAR делает.
Lasciate ogni speranza, voi ch'entrate.

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Re: Как ускорить извлечение файла из ресурсов программы?

Сообщение jangle » 04.09.2007 (Вт) 15:40

tyomitch
Отображается при запуске, грузится по первому обращению. Как и код / данные только для чтения, абсолютно так же.
Resource API процессом загрузки не управляют абсолютно никак.
Соответствия староманерным оверлеям нет абсолютно никакого.


Первая же строка в описании LoadResource из "Microsoft Win32 Progreamers Reference":

The LoadResource function loads the specified resource into global memory.


Для примера создай один пустой EXE без ресурсов, а ко второму EXE прилинкуй скомпилированный в RES файл архив, мегабайт на 700 (фильм какой-нибудь). По очереди запусти оба EXE, и помедитируй, в мыслях почему оба файла запускаются одновременно и без всяких тормозов во втором случае. :)


jangle!
Функция WriteFile не работает, чего-то вроде не хватает. Ругается на неопределенный пользовательский тип.


Работает! Я проверял :wink: Значит, что-то не так делаешь.

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Re: Как ускорить извлечение файла из ресурсов программы?

Сообщение tyomitch » 04.09.2007 (Вт) 15:57

jangle писал(а):
tyomitch
Отображается при запуске, грузится по первому обращению. Как и код / данные только для чтения, абсолютно так же.
Resource API процессом загрузки не управляют абсолютно никак.
Соответствия староманерным оверлеям нет абсолютно никакого.


Первая же строка в описании LoadResource из "Microsoft Win32 Progreamers Reference":

The LoadResource function loads the specified resource into global memory.

Теперь растолкуй, как ты эту строчку понимаешь. Что загруженные этой функцией ресурсы доступны всем процессам?

jangle писал(а):Для примера создай один пустой EXE без ресурсов, а ко второму EXE прилинкуй скомпилированный в RES файл архив, мегабайт на 700 (фильм какой-нибудь). По очереди запусти оба EXE, и помедитируй, в мыслях почему оба файла запускаются одновременно и без всяких тормозов во втором случае.

А ты спроецируй этот же файл вызовом MapViewOfFile, и помедитируй, в мыслях почему он проецируется мгновенно и без всяких тормозов.
Изображение

Watts[]n!
Постоялец
Постоялец
 
Сообщения: 573
Зарегистрирован: 11.02.2007 (Вс) 0:19

Сообщение Watts[]n! » 04.09.2007 (Вт) 19:32

jangle писал(а):Работает! Я проверял Значит, что-то не так делаешь.

Я вообще в API не очень силен :oops:

Просто при попытке запуска выдает упомянутую мной ошибку. Может быть, у тебя в коде еще какие-нибудь константы или типы объявлены, о которых ты не упомянул?

alibek писал(а):не запихивай в ресурсы то, чему там не место

Ну почему же не место? :)
Тогда подскажите пожалуйста, как дописывать в конец Exe-шника данные и потом их читать?

alibek писал(а):Тогда файл будет сложно переносить на флешках, выкладывать в инете, отправлять почтой и т.п.

Вот именно! К тому же у меня Fat32 :)

Crio
Обычный пользователь
Обычный пользователь
Аватара пользователя
 
Сообщения: 84
Зарегистрирован: 21.05.2007 (Пн) 12:01
Откуда: Питер

Сообщение Crio » 04.09.2007 (Вт) 21:54

Тогда подскажите пожалуйста, как дописывать в конец Exe-шника данные и потом их читать?


Можно работать с exe как с обычным файлом.
(вопрос самому себе: а exe файл необычный?)

Например, чтобы добавить в конец exe файла строку:

Код: Выделить всё
Open strFileName For Append As intFreeFile
Print intFreeFile, strText
Close intFreeFile


Но это нельзя проделать при запущенном exe.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 04.09.2007 (Вт) 22:07

Я вообще в API не очень силен :oops:

Бред. rtcMsgBox - то же API. В ней ты тоже не силён?

Просто при попытке запуска выдает упомянутую мной ошибку. Может быть, у тебя в коде еще какие-нибудь константы или типы объявлены, о которых ты не упомянул?

Если пишет "Пользовательский тип не определён" - то это не значит "в коде что-то не так" или "может быть какую-то константу забыли объявить". Это однозначно значит (тавтология, блин), что пользовательский тип не определён - и ничто иное.

Тогда подскажите пожалуйста, как дописывать в конец Exe-шника данные и потом их читать?


Да, пожалуй, также как если бы их надо было записать не в конец, или не в EXE-шник.

Можно работать с exe как с обычным файлом.
(вопрос самому себе: а exe файл необычный?)

Обычный.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Watts[]n!
Постоялец
Постоялец
 
Сообщения: 573
Зарегистрирован: 11.02.2007 (Вс) 0:19

Сообщение Watts[]n! » 04.09.2007 (Вт) 22:44

Не силен в API - это значит, что пока что мало с ним работал и ошибка "Пользовательский тип не определён" мне мало что говорит. Но это уже, естественно, моя "заслуга" :)

Crio писал(а):Можно работать с exe как с обычным файлом.

Понятно, значит будем работать как с обычным, бинарным.

А вообще, уже начинаю понимать бессмысленность этой своей затеи. Лучше уж, как сказал в начале Lumen, положить его рядом с экзешником и не париться.

Crio
Обычный пользователь
Обычный пользователь
Аватара пользователя
 
Сообщения: 84
Зарегистрирован: 21.05.2007 (Пн) 12:01
Откуда: Питер

Сообщение Crio » 04.09.2007 (Вт) 23:10

А вообще, уже начинаю понимать бессмысленность этой своей затеи. Лучше уж, как сказал в начале Lumen, положить его рядом с экзешником и не париться.


Лучше отдельно. Вдруг редактировать его придётся; заменять, обновлять, патчить...

С другой стороны по случайности не удалят, не испортят, не забудут, кто угодно копаться не будет.

А какая у тебя задача? (если не секрет)

Lumen
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 841
Зарегистрирован: 03.12.2005 (Сб) 16:09
Откуда: Брянск

Сообщение Lumen » 05.09.2007 (Ср) 1:33

Ошибка "пользовательский тип не определен", как это ни странно, означает, что пользовательский тип не определен. :)
Покажи код, где возникает ошибка...
Подпись проходит рефакторинг

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Сообщение jangle » 05.09.2007 (Ср) 9:19

Watts[]n! писал(а):Я вообще в API не очень силен :oops:

Просто при попытке запуска выдает упомянутую мной ошибку. Может быть, у тебя в коде еще какие-нибудь константы или типы объявлены, о которых ты не упомянул?


Ну хоть бы описание в MSDN почитал, вот пример сохранения файла около 100 мбайт. На моей P4-2.6 Ггц, RAM-512 мб занимает 4 секунды.


Код: Выделить всё
Option Explicit

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

Public Type OVERLAPPED
        Internal As Long
        InternalHigh As Long
        offset As Long
        OffsetHigh As Long
        hEvent As Long
End Type

Public Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, lpSecurityAttributes As SECURITY_ATTRIBUTES, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long
Public Declare Function WriteFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToWrite As Long, lpNumberOfBytesWritten As Long, LPOVERLAPPED As OVERLAPPED) As Long
Public Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Public Const GENERIC_WRITE = &H40000000
Public Const FILE_SHARE_READ = &H1
Public Const CREATE_ALWAYS = 2
Public Const FILE_ATTRIBUTE_NORMAL = &H80

Sub Main()
  Dim FileNum As Long
  Dim Dest As String
  Dim dwWritten As Long
  Dim SecAttrib As SECURITY_ATTRIBUTES
  Dim LPOVERLAPPED As OVERLAPPED
  Dim hTemplateFile As Long
    Dest = Space(50485760)
          FileNum = CreateFile("c:\hello.txt", GENERIC_WRITE, FILE_SHARE_READ, SecAttrib, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, hTemplateFile)
          Call WriteFile(FileNum, ByVal StrPtr(Dest), LenB(Dest), dwWritten, LPOVERLAPPED)
          CloseHandle FileNum
          MsgBox "Файл сохранен"
End Sub

Watts[]n!
Постоялец
Постоялец
 
Сообщения: 573
Зарегистрирован: 11.02.2007 (Вс) 0:19

Сообщение Watts[]n! » 05.09.2007 (Ср) 13:06

jangle, спасибо, буду разбираться! :)


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: Majestic-12 [Bot], Yandex-бот и гости: 81

    TopList