Копирование медленного байтового массива VBScript - PullRequest
1 голос
/ 20 декабря 2010

Я использую следующий код для чтения в двоичном файле в VBScript и сохранения его в байтовом массиве, к которому я затем обращаюсь из Javascript и копирую в массив JS, в основном просто хитрым способом (единственный способ!)Я обнаружил чтение двоичных данных в моем JS.

Function readBinaryFile(fileName)
    dim inStream,buff

    set inStream=CreateObject("ADODB.Stream")
    inStream.Open
    inStream.type=1

    inStream.LoadFromFile fileName

    buff=inStream.Read()
    inStream.Close

    Dim byteArray()

    Dim i
    Dim len
    len = LenB(buff)

    ReDim byteArray(len)

    For i = 1 To len
        byteArray(i-1) = AscB(MidB(buff, i, 1))
    Next

    readBinaryFile=byteArray
End Function

Кажется, он работает точно так, как ожидалось, единственная проблема в том, что он кажется очень медленным.Например, чтение в файле размером 300 КБ может занять более 2 минут.Я ожидаю прочитать файлы примерно до 2 мг.

Может кто-нибудь объяснить, почему это такая медленная операция и если я могу что-нибудь сделать, чтобы ускорить ее?

Спасибо.

Ответы [ 3 ]

3 голосов
/ 20 декабря 2010

Проблема в петле.Попробуйте использовать отключенный набор записей, чтобы выполнить преобразование:

Function RSBinaryToString(xBinary)
    'Antonin Foller, http://www.motobit.com
    'RSBinaryToString converts binary data (VT_UI1 | VT_ARRAY Or MultiByte string)
    'to a string (BSTR) using ADO recordset

    Dim Binary
    'MultiByte data must be converted To VT_UI1 | VT_ARRAY first.
    If vartype(xBinary)=8 Then Binary = MultiByteToBinary(xBinary) Else Binary = xBinary

    Dim RS, LBinary
    Const adLongVarChar = 201
    Set RS = CreateObject("ADODB.Recordset")
    LBinary = LenB(Binary)

    If LBinary>0 Then
        RS.Fields.Append "mBinary", adLongVarChar, LBinary
        RS.Open
        RS.AddNew
        RS("mBinary").AppendChunk Binary 
        RS.Update
        RSBinaryToString = RS("mBinary")
    Else  
        RSBinaryToString = ""
    End If
End Function

Function MultiByteToBinary(MultiByte)
    '© 2000 Antonin Foller, http://www.motobit.com
    ' MultiByteToBinary converts multibyte string To real binary data (VT_UI1 | VT_ARRAY)
    ' Using recordset
    Dim RS, LMultiByte, Binary
    Const adLongVarBinary = 205
    Set RS = CreateObject("ADODB.Recordset")
    LMultiByte = LenB(MultiByte)
    If LMultiByte>0 Then
        RS.Fields.Append "mBinary", adLongVarBinary, LMultiByte
        RS.Open
        RS.AddNew
        RS("mBinary").AppendChunk MultiByte & ChrB(0)
        RS.Update
        Binary = RS("mBinary").GetChunk(LMultiByte)
    End If
    MultiByteToBinary = Binary
End Function

В вашем случае readBinaryFile возвращает «содержимое ASCII» файла и использует его вместо массива: readBinaryFile = RSBinaryToString(buf)

2 голосов
/ 20 декабря 2010

Я думаю, это потому, что вы используете высокоуровневый язык сценариев для эмуляции того, что должно быть сделано низкоуровневыми скомпилированными языками.Я предполагаю, что есть причина, по которой скрипты не поддерживают двоичные данные.Они не предназначены для обработки данных по одному байту за раз.Зацикливание 300 000 байтов данных займет много времени во многих языках, но не скомпилированный (скриптовый) язык делает его еще хуже.Единственное, что я могу предложить, - это использовать вместо этого скомпилированный язык или какой-либо объект ActiveX, созданный на скомпилированном языке, который поддерживает операции, которые вы хотите выполнить, без необходимости выполнять их побайтно в скрипте.У вас есть возможность использовать скомпилированные компоненты или другие языки?

0 голосов
/ 02 февраля 2011

До сих пор не найдено решение этой проблемы, но сейчас это побочный вопрос, и он работает как есть (хотя и очень медленно в некоторых обстоятельствах), поэтому, к сожалению, у нас нет времени на дальнейшее рассмотрение.

...