Раскодировать из Base64

Тема в разделе "Lotus - Программирование", создана пользователем ankass, 11 авг 2010.

Статус темы:
Закрыта.
  1. ankass

    ankass Гость

    Хотим передавать файл в формате Base64 (например для Web-сервисов)
    Для этого:

    1) Call inStream.Open("c:\In.doc", "binary")
    '------- кодируем поток в Base64
    Call Base64File.Setvaluefromnotesstream(inStream)

    2) '------- раскодируем Base64 обратно в поток
    Set promStream=Base64File.Getvalueasnotesstream()

    В результате:
    - при открытии файла видим окошко с кодировкой (Out.jpg)
    - отладчике видим несоответствие размеров исходного и полученного потока (Debugger.jpg)

    Подскажите пожалуйста что нужно сделать, чтобы заработало ))

    Sub Initialize()
    Dim ss As New NotesSession
    Dim inStream As NotesStream
    Dim outStream As NotesStream
    Dim promStream As NotesStream
    Dim buffer As Variant
    Dim Base64File As New Xsd_base64binary

    Set inStream=ss.Createstream()
    Set outStream=ss.Createstream()
    Set promStream=ss.Createstream()

    Call inStream.Open("c:\In.doc", "binary")
    '------- кодируем поток в Base64
    Call Base64File.Setvaluefromnotesstream(inStream)
    '------- раскодируем Base64 обратно в поток
    Set promStream=Base64File.Getvalueasnotesstream()
    promStream.Position=0

    Call outStream.Open("c:\Out.doc", "binary")
    do
    buffer=promStream.Read(32767)
    Call outStream.Write(buffer)
    Loop Until inStream.IsEOS

    Call inStream.Close()
    Call outStream.Close()
    Call promStream.Close()
    End Sub
     

    Вложения:

    • Out.JPG
      Out.JPG
      Размер файла:
      53,3 КБ
      Просмотров:
      164
    • Debugger.JPG
      Debugger.JPG
      Размер файла:
      103,7 КБ
      Просмотров:
      160
  2. nvyush

    nvyush Lotus team
    Lotus team

    Регистрация:
    22 апр 2009
    Сообщения:
    2.317
    Симпатии:
    0
    Стоит глянуть код в файле lsxsd.lss (в папке Лотуса). Там есть функции notesStreamToBase64, base64ToNotesStream, notesStreamToBase64Ext, base64ToNotesStreamExt, может они чем помогут. Особенно мне понравилась реализация двух последних :rolleyes:.
     
  3. turumbay

    Регистрация:
    13 мар 2009
    Сообщения:
    625
    Симпатии:
    2
    http://www.ibm.com/developerworks/lotus/li.../web-services3/
    If you perform base64 encoding or decoding operations in a Web service on files greater than 20 KB, you may want to use Java for the base64 operations instead of the native LotusScript encoding/decoding that is available in the XSD_BASE64BINARY class. LotusScript tends to be relatively slow at parsing large strings of data, while Java is especially fast at doing so.

    По нашему: не используйте медленный и глюкоемкий LS класс XSD_BASE64BINARY для кодирования/декодирования Base64. Юзайте java.( напрямую или через бридж LS2J )

    Для файла 150Kb разница по времени кодирования стократная(!!!): 1-2сек на java vs. 2 минуты на LS
    В статье есть ссылка на nsf базу. Скачайте и раскурите библиотеки base64java и base64 ls2j.
     
  4. ankass

    ankass Гость

    В программе обращение идет как раз к этим функциям через
    PUBLIC CLASS XSD_BASE64BINARY AS XSD_SIMPLETYPE

    SUB setValueFromNotesStream (nsValue As NotesStream)
    Dim xdtc As New XSD_DATATYPE_CONVERTER
    CALL Me.setValueFromString (xdtc.notesStreamToBase64Ext (nsValue))
    END SUB

    FUNCTION getValueAsNotesStream () As NotesStream
    Dim xdtc As New XSD_DATATYPE_CONVERTER
    set getValueAsNotesStream = xdtc.base64ToNotesStreamExt (Me.getValueAsString())
    END FUNCTION

    END CLASS

    в 7-ке было так
    PUBLIC CLASS XSD_BASE64BINARY AS XSD_SIMPLETYPE

    SUB setValueFromNotesStream (nsValue As NotesStream)
    Dim xdtc As New XSD_DATATYPE_CONVERTER
    CALL Me.setValueFromString (xdtc.notesStreamToBase64 (nsValue))
    END SUB

    FUNCTION getValueAsNotesStream () As NotesStream
    Dim xdtc As New XSD_DATATYPE_CONVERTER
    set getValueAsNotesStream = xdtc.base64ToNotesStream (Me.getValueAsString())
    END FUNCTION

    END CLASS
     
  5. ankass

    ankass Гость

    Подключил файл от 7-ки
    %Include "c:\Lotus\Notes7\lsxsd.lss"
    Стало работать нормально, но очень медленно.
    lsxsd.lss от 8-ки работает быстро, но неправильно ))
    в функции base64ToNotesStream есть странная строка:
    Call ns.WriteDecoded(b64String,ENC_BASE64) 'internal use only
    ее внутренности обнаружить не удалось ((
    Я думаю тут и зарыта проблема.

    P.S.: в опубликованном коде я в цикле ошибку допустил при переписывании, правильно так:
    do
    buffer=promStream.Read(32767)
    Call outStream.Write(buffer)
    Loop Until promStream.IsEOS
     
  6. lmike

    lmike нет, пердело совершенство
    Команда форума Lotus team

    Регистрация:
    27 авг 2008
    Сообщения:
    6.079
    Симпатии:
    300
    люди готовы на любые костыли, лиж бы не изучать/перенимать опыт...
     
  7. nvyush

    nvyush Lotus team
    Lotus team

    Регистрация:
    22 апр 2009
    Сообщения:
    2.317
    Симпатии:
    0
    Точнее в base64ToNotesStreamExt. А в notesStreamToBase64Ext есть аналогичная "странная" строка:
    notesStreamToBase64Ext = ns.ReadEncoded(ENC_BASE64, 76) 'internal use only
    Вот эти строки мне и "понравились". ИБМ использует недокументированные методы класса NotesStream. Разумеется, их внутренности посмотреть не удастся. А судя по проблеме, реализованы они криво, нужно сообщить ИБМ об ошибке.
    Т.о. стоит задуматься на предложением turumbay
     
  8. VladSh

    VladSh начинающий
    Lotus team

    Регистрация:
    11 дек 2009
    Сообщения:
    1.251
    Симпатии:
    2
    Сейчас не знаю, но в 7-ке вот так всё работало, безо всяких файлов:
     
Загрузка...
Статус темы:
Закрыта.

Поделиться этой страницей