), но только в UNICODE. Есть предложения как тип изменить?
Проблема именно в ADODB.Recordset, а не стриме, стрим уже получает юникодовую строку...
Собака зарылась в Fields.Append или rs.Fields(0).Type, но я вроде все перебрал- не получается.
Пробовал перебирать DataTypeEnum и FieldAttributeEnum — ничего пока.
в FieldAttributeEnum вообще интересно- есть только Long Binary (adFldLong), а просто бинари- нет.
как меняю- stream.Write ошибается, потому что переменная уже другого типа.
var rs = new ActiveXObject("ADODB.Recordset");
var stream = new ActiveXObject("ADODB.Stream");
var string = "test";
Ставлю проблему чётко:
Мне не нужно копировать бинарный поток, мне нужно создать его (внедрить exe/png в html).
В первой моей мессаге твой пример- он сохраняет строку как бинарные данные, но в UNICODE, а нужен 1-байтные тип.
Мне нужно генерить бинарные данные через мою простенькую функцию:
hex2str( 'D5A90000300000004000000FFF' );
которая возвращяет бинарную строку (String.fromCharCode);
Так-то понятно, что читаем стрим (не юникодовый), так он и сохраняется не юникодово, а вот сгенерить стрин скриптово (не из внешних источников) и сохранить в НЕюникоде- вот проблема.
Re[3]: ADODB.Stream запись бинарника, JScript only!
Здравствуйте, EugeNet.Spb, Вы писали:
ES>Мне нужно генерить бинарные данные через мою простенькую функцию:
ES>hex2str( 'D5A90000300000004000000FFF' ); ES>которая возвращяет бинарную строку (String.fromCharCode);
Всё понял. Вся проблема не в стриме, ещё раз тебе напомню, а в строках. В JScript все строки по умолчанию в Unicode.
Получаем задачу: Имея некоторую бинарную строку записанную в Unicode нужно преобразовать в однобайтную кодировку и сохранить как бинарный файл.
Последовательность действий такая:
1) Получить бинарную строку (это ты делаешь сам).
2) Преобразовать строку к однобайтной кодировке
3) Сохранить преобразование.
Получаем следующий вариант.
var binString = ""; // Некоторая бинарная строка, ты её сам получаешь.var outStreamW = new ActiveXObject("ADODB.Stream"); // Текстовый поток с кодировкой Unicode
outStreamW.Type = 2;
outStreamW.Open();
outStreamW.WriteText(binString);
outStreamW.Position = 0;
var outStreamA = new ActiveXObject("ADODB.Stream"); // Текстовый поток с однобайтной кодировкой
outStreamA.Type = 2;
outStreamA.Charset = "windows-1251"; // Почему не ASCII? а потому что в случае ASCII будут исковерканы байты со кодами больше 127.
outStreamA.Open();
outStreamW.CopyTo(outStreamA); // Преобразование с одной кодировки в другую.
outStreamA.SaveToFile("c:\\writetest.exe", 2); // Сохранение потока в файл.
outStreamW.Close();
outStreamA.Close();
Протестировал я это дело таким образом:
// Читаем бинарный файл, специально для тестаvar inStream = new ActiveXObject("ADODB.Stream");
inStream.Type = 1;
inStream.Open();
inStream.LoadFromFile("c:\\readtest.exe");
inStream.Position = 0;
var binData = inStream.Read();
inStream.Close();
///////////////////////////////////////////////////
// Преобразовываем бинарные данные в строкуvar bufferSize = 100000;
var rs = new ActiveXObject("ADODB.Recordset");
rs.Fields.Append("test", 201, bufferSize, 0x80);
rs.Open();
rs.AddNew();
rs.Fields("test").AppendChunk(binData);
rs.Update();
rs.MoveFirst();
var binString = rs("test").GetChunk(bufferSize);
rs.Close();
//////////////////////////////////////////////////
// Строка сейчас находится в Unicode, благодаря JavaScript
// Ну и далее уже записываем строку в файл с преобразованием в однобайтную кодировкуvar outStreamW = new ActiveXObject("ADODB.Stream");
outStreamW.Type = 2;
outStreamW.Open();
outStreamW.WriteText(binString);
outStreamW.Position = 0;
var outStreamA = new ActiveXObject("ADODB.Stream");
outStreamA.Type = 2;
outStreamA.Charset = "windows-1251";
outStreamA.Open();
outStreamW.CopyTo(outStreamA);
outStreamA.SaveToFile("c:\\writetest.exe", 2);
outStreamW.Close();
outStreamA.Close();
Применением diff получаем, что файлы writetest и readtest совпадают до байта.
Огромное спасибо Andir-у за хорошо работающие мозги =)
Наконец-то получилось записать бинарник (генерился самим скриптом) не в юникоде.
Пиндосы (американы) отдыхают — они все советуют эту функцию на VBS писать, типа на JS низзя...
В качестве примера генерю и сохраняю PNG и открываю проводник с файлом...
Обязательно используйте charset ISO-8859-1, Windows-125* и ascii тут не сработают.
Строки с комментарием // unnecessary — просто для демонстрации...
PS: Извините за английские комментарии, привычка у меня такая, все по пиндосски писать...
<SCRIPT LANGUAGE=jscript>
/*
======== RUSSIAN ===================================================
Скрипт для сохраннения бинарных данных из JScript и их генерации в нем же.
Задумка EugeNet, реализовать помог Andir (почти весь исходник).
======== ENGLISH ===================================================
This is done by EugeNet with great help of Andir (http://RSDN.ru).
For the foreign founders I'm gonna say-
It's the only JScript on a web, that allows to save binary data
(there's many for VBScript) generated by script itself.
( Viruses still uses VB, until this day =) ).
KEYWORDS: ADODB stream binary save file hex generate unicode
*/var outStreamW = new ActiveXObject("ADODB.Stream"); // Text stream in Unicode charsetvar outStreamA = new ActiveXObject("ADODB.Stream"); // Text stream in ISO-8859-1 charsetvar binStr = '';
var objShell = new ActiveXObject("Shell.Application"); // unnecessary
outStreamW.Type = 2;
outStreamW.Open();
// couples of HEX values
outStreamW.WriteText( hex2text( '89504E470D0A1A0A0000000D4948445200000027000000420803000000E3443FEE0000000C504C5445F0EEEEF95353F59393' ) );
outStreamW.WriteText( hex2text( 'FF04047F58B0FF000000097048597300002E2300002E230178A53F760000014249444154789CED955902C42008434DB8FF9D' ) );
outStreamW.WriteText( hex2text( 'A7AD4BD9AC1C60FCAA363E10115AF38361251D404D27520242A40414290171EB0A409112F0F6AEE2E1C33A033BEA0C1CA413' ) );
outStreamW.WriteText( hex2text( '900374022ECE37900BF30D5494EBB380FB061AA7F6401AC41EE8CEB803D20176C007C76B1C8000D0930A5D4A208D35658D61' ) );
outStreamW.WriteText( hex2text( '9069D28A3821E6CC60FB5E1013A2B679AB7CB7749B026F1A7ADB74157362EE49B9417D1C1349172D636DAF83F1DE7EEB3889' ) );
outStreamW.WriteText( hex2text( 'F729E7B943EE7434B762CFA1269C81EBF74B1BC035E3B80215671DB267E14AABF523E6C57B46F3E315B6960BA16DC4B49E89' ) );
outStreamW.WriteText( hex2text( 'A4F3282F0BD4897F1A2C7606D43BC35F57D7857A1375CF0DF9C297E87A6AF9040B3A2E9DAF48C11134575A32DD0439A0D7AD' ) );
outStreamW.WriteText( hex2text( 'A70857846C00D4DF50349D4C55A45D5B31B2F104231269D95D2DA12F317D96ABBA0BDE5692B9A3EA847AF1794654544EBAE9' ) );
outStreamW.WriteText( hex2text( '5AC7F103F62B06FEC580AB3F0000000049454E44AE426082' ) );
outStreamW.Position = 0; //don't forget it or .Read will return 0 bytes
outStreamA.Type = 2;
outStreamA.Charset = 'ISO-8859-1'; // to avoid character conversion upper 127 ascii code
outStreamA.Open();
outStreamW.CopyTo( outStreamA ); // Copy unicoded stream to ISO-8859-1 stream
outStreamA.SaveToFile( 'c:\\YOUR FACE IN FBI DATABASE.png', 2 ); // save file as...
outStreamW.Close();
outStreamA.Close();
objShell.Open( 'C:\\' ); // unnecessary, opens Windows Explorer in root c:
// converts couples of HEX values to a string of charsfunction hex2text( inHexStr ){
binStr = ''; //using global variable will be faster, I think.for ( i = 0; i < ( inHexStr.length / 2 ); i++ ){
binStr += String.fromCharCode( '0x' + inHexStr.substr( i * 2, 2 ) );
}
return binStr;
}
</SCRIPT>