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

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

ankass

Гость
#1
Хотим передавать файл в формате 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
 

Вложения

nvyush

Well-Known Member
Lotus team
22.04.2009
2 317
0
#2
Стоит глянуть код в файле lsxsd.lss (в папке Лотуса). Там есть функции notesStreamToBase64, base64ToNotesStream, notesStreamToBase64Ext, base64ToNotesStreamExt, может они чем помогут. Особенно мне понравилась реализация двух последних :rolleyes:.
 
13.03.2009
625
2
#3
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.
 
A

ankass

Гость
#4
Стоит глянуть код в файле 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
 
A

ankass

Гость
#5
Стоит глянуть код в файле 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
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 490
366
#6
люди готовы на любые костыли, лиж бы не изучать/перенимать опыт...
 

nvyush

Well-Known Member
Lotus team
22.04.2009
2 317
0
#7
в функции base64ToNotesStream есть странная строка:
Call ns.WriteDecoded(b64String,ENC_BASE64) 'internal use only
ее внутренности обнаружить не удалось ((
Я думаю тут и зарыта проблема.
Точнее в base64ToNotesStreamExt. А в notesStreamToBase64Ext есть аналогичная "странная" строка:
notesStreamToBase64Ext = ns.ReadEncoded(ENC_BASE64, 76) 'internal use only
Вот эти строки мне и "понравились". ИБМ использует недокументированные методы класса NotesStream. Разумеется, их внутренности посмотреть не удастся. А судя по проблеме, реализованы они криво, нужно сообщить ИБМ об ошибке.
Т.о. стоит задуматься на предложением turumbay
 

VladSh

начинающий
Lotus team
11.12.2009
1 248
2
#8
Сейчас не знаю, но в 7-ке вот так всё работало, безо всяких файлов:
import sun.misc.BASE64Decoder;

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