Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > VB6 > Реально ли?


Автор: WildSpy 10.7.2007, 17:21
Такой вопрос, реально ли на VB получить низкоуровневый доступ к устройству, например винту?
И вообще, как это реализуется на любых языках?
Объясните плз...

Автор: cardinal 10.7.2007, 22:04
Цитата(WildSpy @  10.7.2007,  15:21 Найти цитируемый пост)
И вообще, как это реализуется на любых языках?

Через драйверы.

Автор: Akina 10.7.2007, 22:24
Что разумеется под словами "низкоуровневый доступ"?
Хочешь напрямую с портами ввода-вывода работать? пожалуйста, есть драйвер DirectIO... вот только ОС, пожалуй, обидится... можно напрямую с драйвером устройства поработать - через IOCTL или DirectIOControl, например... 

А вот самостоятельный драйвер устройства на VB, пожалуй, нереализуем. То есть формально это возможно, но получится сплошь инлайновый ассемблер...


Автор: WildSpy 11.7.2007, 08:46
Просто мне нужно считать файл не стандартной функцией, а максимально быстро. И я так думаю, что для этого нужно получить низкоуровневый доступ к винту, как это делает например антивирус.
А потом ещё разобраться как считать файл.

Подскажите что-нибудь.

Автор: Akina 11.7.2007, 08:51
Цитата(WildSpy @  11.7.2007,  09:46 Найти цитируемый пост)
мне нужно считать файл не стандартной функцией, а максимально быстро.

C этого места поподробнее. Задачу полностью, от самого начала. Почему максимально быстро? Один файл или то, какой файл потребуется, выбирается программно? его прогнозируемый размер? расположение (локальный, сетевой)? 
А то есть подозрение, что ты собрался микроскопом орехи колоть...

Автор: W4FhLF 11.7.2007, 08:56
Цитата(Akina @  10.7.2007,  22:24 Найти цитируемый пост)
То есть формально это возможно, но получится сплошь инлайновый ассемблер...


Это невозможно ни в каком виде при использовании компилятора VB. 

Цитата(WildSpy @  11.7.2007,  08:46 Найти цитируемый пост)
Просто мне нужно считать файл не стандартной функцией, а максимально быстро. И я так думаю, что для этого нужно получить низкоуровневый доступ к винту, как это делает например антивирус.


Самое быстрое, что тут можно придумать, помимо разбирая файловой системы, т.е. работы в RAW режиме, это самостоятельная посылка пакета в disk.sys, но в ВБ это нереализуемо. 

Автор: WildSpy 11.7.2007, 09:44
Да нет, файл определяется пользователем. Тут не суть важно, размер неизвестен. Но в среднем не больше 10 мег.

Файл бинарный, нужно как можно быстрее загрузить его в память.

и еще один вопрос, есть код:

Код

Dim sX As Double
Dim llen As Double
Dim sBytes As String
Dim sTemp As String

llen = Len(sBytes)
    
    For sX = 1 To llen
          sTemp = Hex(Asc(Mid(sBytes, sX, 1)))
            If sTemp = "0" Then
                sTemp = "00"
            ElseIf Len(sTemp) = 1 Then
                sTemp = "0" & sTemp
            End If
        packbytes = packbytes & sTemp
    Next sX


это код переводит файл в hex, типа как это делают WinHEX и т.д.

Вопрос, как этот код ускорить, а то он работает ужасно медленно.

Автор: W4FhLF 11.7.2007, 10:39
Цитата(WildSpy @  11.7.2007,  09:44 Найти цитируемый пост)
это код переводит файл в hex, типа как это делают WinHEX и т.д.


Покажи, что у тебя на входе и что должно быть на выходе

Автор: WildSpy 11.7.2007, 11:17
Цитата(W4FhLF @ 11.7.2007,  10:39)
Цитата(WildSpy @  11.7.2007,  09:44 Найти цитируемый пост)
это код переводит файл в hex, типа как это делают WinHEX и т.д.


Покажи, что у тебя на входе и что должно быть на выходе

Код

Dim sX As Double
    Dim llen As Double
    Dim sBytes As String
    Dim sTemp As String
    packbytes = ""
    
    Open (file) For Binary Access Read As #1
        a = FileLen(file)
        sBytes = Space(a)
        
        Get #1, , sBytes
        
    Close #1
    
    llen = Len(sBytes)
    
    For sX = 1 To llen
          sTemp = Hex(Asc(Mid(sBytes, sX, 1)))
            If sTemp = "0" Then
                sTemp = "00"
            ElseIf Len(sTemp) = 1 Then
                sTemp = "0" & sTemp
            End If
        packbytes = packbytes & sTemp
    Next sX

    
    packbytes = Trim(packbytes)



так понятнее?

Автор: mihanik 11.7.2007, 12:02
Цитата(WildSpy @  11.7.2007,  09:44 Найти цитируемый пост)
Вопрос, как этот код ускорить, а то он работает ужасно медленно. 


Естественно!

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

Сформулируй поточнее саму задачу, а не то, как ты её решал!!!


Автор: WildSpy 11.7.2007, 12:11
Цитата(mihanik @ 11.7.2007,  12:02)
Цитата(WildSpy @  11.7.2007,  09:44 Найти цитируемый пост)
Вопрос, как этот код ускорить, а то он работает ужасно медленно. 


Естественно!

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

Сформулируй поточнее саму задачу, а не то, как ты её решал!!!

Открыть файл и перевести его в hex, типа как это реализовано в hex-Редакторах типа WinHEX

Автор: W4FhLF 11.7.2007, 13:36
Код

Dim Bytes() As Byte
Dim sSump As String
Dim szDump As String
Dim i As Long

Private Sub Form_Load()
    Bytes = LoadFile("E:\Temp\untitled1")
    sDump = Space(szDump * 4 + 1)
    For i = 1 To szDump - 1
        Mid(sDump, 3 * i, 2) = Left$("00", 2 - IIf(Bytes(i) > &HF, 2, 1)) & Hex(Bytes(i))
    Next i
    Text1.Text = Trim$(sDump)
End Sub

Function LoadFile(ByVal sName As String) As Byte()
    Dim arrFile() As Byte
    Dim nFile As Integer

    nFile = FreeFile
    Open sName For Binary As #nFile
        ReDim arrFile(1 To (LOF(nFile) - 1))
        szDump = UBound(arrFile) + 1
        Get #nFile, , arrFile
    Close #nFile
    LoadFile = arrFile
End Function


В Text1 поставь шрифт Courier New

Автор: Akina 11.7.2007, 13:55
Читать лучше через FileSystemObject.ReadAll - 10 мег всасывается мгновенно. Это не лимитирует.
Лимитирует именно конвертация - медленные строковые функции... и совершенно правильное решение ускорить процесс за счет работы с фиксированным буфером.


Автор: WildSpy 11.7.2007, 14:16
Огромное спасибо, работает. =)

Автор: WildSpy 11.7.2007, 14:32
Ещё один маленький вопрос, код написан достаточно сложно, т.е. как можно более компактно и не совсем понятен для меня.

Так вот, такой ламерский вопрос, как избавится от пробелов на выходе? т.е. чтобы между цифрами и буквами не было пробелов?

убирать их replace'ом долго, а откуда они берутся не могу найти.

Автор: Akina 11.7.2007, 14:40
Цитата(WildSpy @  11.7.2007,  15:32 Найти цитируемый пост)
откуда они берутся не могу найти.

Так изначально же буфер заполняется пробелами...

Автор: WildSpy 11.7.2007, 14:57
Цитата(Akina @ 11.7.2007,  14:40)
Цитата(WildSpy @  11.7.2007,  15:32 Найти цитируемый пост)
откуда они берутся не могу найти.

Так изначально же буфер заполняется пробелами...

а, понятно и как от них избавится, чтобы на выходе получился сплошной текст, и чтобы скорость приличная была....?

Автор: Akina 11.7.2007, 17:00
Цитата(WildSpy @  11.7.2007,  15:57 Найти цитируемый пост)
как от них избавится, чтобы на выходе получился сплошной текст, и чтобы скорость приличная была....? 

Откорректировать расчет размера буфера и смещений, чтобы данные ложились "впритирку"...

Автор: WildSpy 11.7.2007, 17:17
Блин, непонимаю как это...
можно пример?

Автор: Akina 11.7.2007, 17:30
Код

Option Explicit

Dim Bytes() As Byte
Dim sDump As String
Dim szDump As String
Dim i As Long

Private Sub Form_Load()
    Bytes = LoadFile("E:\Filename.Ext")
    sDump = Space(szDump * 2)
    For i = 1 To szDump
        Mid(sDump, 2 * i - 1, 2) = Right("0" & Hex(Bytes(i)), 2)
    Next i
    Text1.Text = sDump
End Sub

Function LoadFile(ByVal sName As String) As Byte()
    Dim arrFile() As Byte
    Dim nFile As Integer

    nFile = FreeFile
    Open sName For Binary As #nFile
    ReDim arrFile(1 To (LOF(nFile)))
    szDump = UBound(arrFile)
    Get #nFile, , arrFile
    Close #nFile
    LoadFile = arrFile
End Function

Автор: WildSpy 11.7.2007, 18:07
Спасибо, но почему то то код с "пробелами" работал быстрее, чем этот, "без пробелов"...почему так?
причем разница в скорости серьезно ощутима

т.е. новый код, по скорости примерно так же, как старый с применением Replace'а...

Автор: W4FhLF 11.7.2007, 19:39
Цитата(WildSpy @  11.7.2007,  18:07 Найти цитируемый пост)
т.е. новый код, по скорости примерно так же, как старый с применением Replace'а...


У меня новый быстрее в среднем на 11%, оно и следовало предполагать. Чему там быть медленнее?

Автор: WildSpy 11.7.2007, 20:17
Незнаю, у меня старый код, где без убранных пробелов намного быстрее остального.

Автор: bom 12.7.2007, 00:04
Первый код "загружает" в Textbox кусок файла размером 21 КВ, второй - 32 КВ, отсюда и разница в скорости, так как Texbox довольно тормозной контрол. 

Автор: WildSpy 12.7.2007, 07:37
Ага, я уже разобрался, всем спасибо.

Если можно, то последний вопрос, как загрузить файл с определенного байта (offset'а) ?

Автор: Akina 12.7.2007, 12:53
seek

Автор: __Sergey__ 12.7.2007, 15:55
надо использовать ф-ции, работающие с файловым отображением.

Добавлено через 2 минуты и 5 секунд
CreateFileMapping, MapViewOfFile ...

Автор: WildSpy 12.7.2007, 16:05
Цитата(__Sergey__ @ 12.7.2007,  15:55)
надо использовать ф-ции, работающие с файловым отображением.

Добавлено @ 15:57
CreateFileMapping, MapViewOfFile ...

Спасибо, а не подскажешь, где про это почитать?

Автор: Akina 12.7.2007, 17:06
Цитата(MSDN @  как ни странно)

Seek Statement

Sets the position for the next read/write operation within a file opened using the Open statement.

Syntax

Seek [#]filenumber, position

The Seek statement syntax has these parts:


filenumber Required. Any valid file number. 
position Required. Number in the range 1 – 2,147,483,647, inclusive, that indicates where the next read/write operation should occur. 

Remarks

Record numbers specified in Get and Put statements override file positioning performed by Seek.

Performing a file-write operation after a Seek operation beyond the end of a file extends the file. If you attempt a Seek operation to a negative or zero position, an error occurs.



Автор: W4FhLF 12.7.2007, 18:24
Код

Get #nFile, POS_IN_FILE, arrFile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)