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

  • Автор темы Автор темы ankass
  • Дата начала Дата начала
Статус
Закрыто для дальнейших ответов.
A

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
    46,7 КБ · Просмотры: 737
  • Debugger.JPG
    Debugger.JPG
    83,3 КБ · Просмотры: 621
Стоит глянуть код в файле lsxsd.lss (в папке Лотуса). Там есть функции notesStreamToBase64, base64ToNotesStream, notesStreamToBase64Ext, base64ToNotesStreamExt, может они чем помогут. Особенно мне понравилась реализация двух последних :rolleyes:.
 

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.
 
Стоит глянуть код в файле lsxsd.lss (в папке Лотуса). Там есть функции notesStreamToBase64, base64ToNotesStream, notesStreamToBase64Ext, base64ToNotesStreamExt, может они чем помогут. Особенно мне понравилась реализация двух последних :rolleyes:.

В программе обращение идет как раз к этим функциям через
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
 
Стоит глянуть код в файле lsxsd.lss (в папке Лотуса). Там есть функции notesStreamToBase64, base64ToNotesStream, notesStreamToBase64Ext, base64ToNotesStreamExt, может они чем помогут. Особенно мне понравилась реализация двух последних :rolleyes:.
Подключил файл от 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
 
люди готовы на любые костыли, лиж бы не изучать/перенимать опыт...
 
в функции base64ToNotesStream есть странная строка:
Call ns.WriteDecoded(b64String,ENC_BASE64) 'internal use only
ее внутренности обнаружить не удалось ((
Я думаю тут и зарыта проблема.
Точнее в base64ToNotesStreamExt. А в notesStreamToBase64Ext есть аналогичная "странная" строка:
notesStreamToBase64Ext = ns.ReadEncoded(ENC_BASE64, 76) 'internal use only
Вот эти строки мне и "понравились". ИБМ использует недокументированные методы класса NotesStream. Разумеется, их внутренности посмотреть не удастся. А судя по проблеме, реализованы они криво, нужно сообщить ИБМ об ошибке.
Т.о. стоит задуматься на предложением turumbay
 
Сейчас не знаю, но в 7-ке вот так всё работало, безо всяких файлов:
import sun.misc.BASE64Decoder;

byte[] bytes = new BASE64Decoder().decodeBuffer(pStr);
String decodeDXL64 = new String(bytes, "UTF-8");
 
Статус
Закрыто для дальнейших ответов.
Мы в соцсетях:

Взломай свой первый сервер и прокачай скилл — Начни игру на HackerLab