Как установить двоичный режим передачи файлов в FileZilla, Total Commander и CuteFTP
Из этого туториала вы узнаете, как установить двоичный режим передачи файлов в FileZilla , Total Commander и CuteFTP.
С помощью FTP можно загружать файлы на сервер в двух режимах: ASCII и двоичном (binary). В режиме ASCII файлы передаются в формате ‘текст’. В Двоичном (Binary) файлы передаются в исходном формате данных.
Если у вас возникли проблемы с поврежденными при передаче файлами, для решения этого вопроса можно использовать двоичный режим. Для большинства популярных FTP -клиентов способ выбора двоичного режима передачи отличается:
Total Commander : в панели инструментов вверху найдите вкладку «Режим передачи» (‘Transfer mode’). Затем в выпадающем списке выберите «двоичный» (‘Binary’) (архивы, документы т. д.)’:
FileZilla : в верхнем меню выберите Передача (Transfer)> Тип передачи (Transfer type)> Двоичный (Binary):
CuteFTP: перейдите в раздел Файл (File)> Тип передачи (Transfer Type)> Двоичный (Binary):
Вы также можете воспользоваться детальным видео — туториалом:
Передача двоичного файла (данных) в Java
Я имел обыкновение быть программистом переменного тока. В C, если я хочу передать двоичные данные (не только текстовые файлы) из станд гипергликемии, я просто не могу это сделать, не вызывая getchar() и putchar() снова и снова, пока не достигнет EOF . Мой вопрос заключается в том , что это возможно сделать так же , как в Java? Могу ли я просто позвонить readline() и writeline() снова и снова? Если нет, то что я могу сделать?
Спасибо!
Нет, вы должны абсолютно не ничего с использовать readLine() и writeLine() звонки. Это для текстовых данных. Если вы переносите двоичные данные, вы должны использовать InputStream и OutputStream — ничего с Reader или Writer от имени. Если преобразовать двоичные данные в текст, вы почти гарантированно потерять данные.
Но тогда вы можете просто скопировать блоки данных в то время:
Jsp -> servlet -> jsp, как передать данные?
Здравствуйте, возник вопрос как передать данные из jsp в servlet для обработки и вернуть в ту же jsp. У меня servlet возвращает пустую страницу, подскажите, пожалуйста, где я ошибся.
Суть проекта, в том, что через форму calc.jsp мы вводим цифры и выбираем операцию, обработка запроса происходит на сервлете и он возвращает строи операций (ArrayList) обратно в сервлет где он отображается.
- Вопрос задан более трёх лет назад
- 9995 просмотров
Метод doGet должен просто форвордить на jsp, на которой ваша форма, которая отправляет POST запрос, который обрабатывает метод doPost. Результат обработки, вы добавляете в реквест с помощью методов setAttribute.
setAttribute — метод HttpServletRequest-а специально предназначен для передачи данных между сервлетами/jsp
передача файла в 1С через http сервис 1с
Собственно проблема в следующем.
есть в конфигурации http-сервис. который генерит следующий текст html:
Этот код позволяет выбрать, загрузить и передать в 1с файл в теле запроса.
В полученной html форме народ выбирает файл и нажимает кнопку отправить.
Но проблема в следующем. Передача файлов и др. бинарной информации возможна только с применением кодирования «multipart/form-data» а это кодирование предполагает хранение заголовков запроса и файла единым текстом с использованием разделителя. Http сервисы типа Php разбирают такой текст без проблем — стандартными языковыми структурами. Мой вопрос — как это сделать в 1С?
АйТиБложик
Маленький IT блог с характером 1С.
Страницы
Поиск по блогу
четверг, 29 октября 2015 г.
Передача двоичных данных с помощью веб-сервиса
Объект метаданных «Веб-сервис» предназначен для обмена данными посредством веб-технологий, а если быть точнее — по протоколу HTTP. Как же осуществляется передача двоичных данных в мире веб-разработки? Для этого используется кодирование двоичных данных под названием base64 (64 — это число символов в алфавите кодирования, из которого формируется конечный буквенно-цифровой текст на основе латинского алфавита).
Закодированные двоичные данные выглядят примерно так:
TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0
Платформа 1С в своем арсенале имеет имеет парочку функций, которые умеют кодировать двоичные данные в base64:
- Base64Строка — имеет один входящий параметр типа ДвоичныеДанные, возвращает строку, закодированную по алгоритму base64.
- XMLСтрока — так же имеет один входящий параметр, который может принимать значение типа ДвоичныеДанные и возвращать строку в формате base64, следует использовать для создания XML.
Допустим, имеется веб-сервис, который содержит метод GetFacsimile. Этот метод принимает номер заказа и возвращает счет факсимиле в виде PDF-файла.
Рисунок 1. Метод веб-сервиса GetFacsimile |
Если метод возвращает значение (в нашем случае это файл), то нужно указать тип возвращаемого значения, выберем тип String пространства имен http://www.w3.org/2001/XMLSchema, ведь base64 это строка.
Рисунок 2. Тип возвращаемого значения метода |
Напишем программный код для метода:
Функция GetFacsimile(Number)
ФайлКакBase64 = «»;
НомерЗаказаКлиента = СокрЛП(Number);
ЗаказКлиента = Документы.ЗаказКлиента.НайтиПоНомеру(НомерЗаказаКлиента);
Если Не ЗаказКлиента.Пустая() Тогда
МассивОбъектов = Новый Массив;
МассивОбъектов.Добавить(ЗаказКлиента);
СтруктураТипов = ОбщегоНазначенияУТ.СоответствиеМассивовПоТипамОбъектов(МассивОбъектов);
ПараметрыПечати = Новый Структура;
ПараметрыПечати.Вставить(«ДополнитьКомплектВнешнимиПечатнымиФормами», Ложь);
ПараметрыПечати.Вставить(«ОтображатьФаксимиле», Истина);
ИмяВременногоФайла = ПолучитьИмяВременногоФайла(«pdf»);
ТабличныйДокумент = Обработки.ПечатьСчетовНаОплату.СформироватьПечатнуюФормуСчетНаОплату(
СтруктураТипов,
Новый СписокЗначений,
ПараметрыПечати);
ТабличныйДокумент.Записать(ИмяВременногоФайла, ТипФайлаТабличногоДокумента.PDF);
ДвоичныеДанныефайла = Новый ДвоичныеДанные(ИмяВременногоФайла);
Попытка
УдалитьФайлы(ИмяВременногоФайла);
Исключение
КонецПопытки;
ФайлКакBase64 = Base64Строка(ДвоичныеДанныефайла);
Иначе
ЗаписьЖурналаРегистрации(
«Документы.ЗаказКлиента.НайтиПоНомеру»,
УровеньЖурналаРегистрации.Предупреждение,
Метаданные.Документы.ЗаказКлиента,
,
«Не найден счет факсимиле по номеру заказа клиента: » + НомерЗаказаКлиента + «.»);
КонецЕсли;
Возврат ФайлКакBase64;
КонецФункции
Но можно и по другому, для этого находим информацию в синтакс-помощнике о типе ДвоичныеДанные и смотрим, может ли данный тип сериализоваться в объект XDTO, если да, то какому типу соответствует.
Рисунок 3. Дополнительно описание типа ДвоичныеДанные |
Из рисунка 3 видно, что тип ДвоичныеДанные сопоставим с типами base64Binary и hexBinary, которые относятся к пространству имен http://www.w3.org/2001/XMLSchema. Далее указываем для метода тип возвращаемого значения (см. рисунок 2) из списка сопоставимых. Теперь в методе можно возвращать двоичные данные без явного кодирования в base64, система это сделает за вас.
Функция GetFacsimile(Number)
// Создание файла . . .
ДвоичныеДанныефайла = Новый ДвоичныеДанные(ИмяВременногоФайла);
Возврат ДвоичныеДанныефайла ;
КонецФункции
Принимающей стороне остается декодировать строку формата base64 в двоичные данные.
Получение файла с сервера с обработкой возможных ошибок
Для одной из наших интранет-систем мы делали простой поиск по содержимым файлов, присоединённых к официальным документам. Результатом поиска был список имён файлов и ссылок на сервлет, эти файлы выгружающий. Сервлет читает файл по его идентификатору из хранилища и выдаёт его с «Content-Type: application/octet-stream» или MIME-типу, соответствующему файлу. Но как поступить, если на сервере произошла ошибка, как сказать об этом оператору? Можно было бы устроить переадресацию на страницу с сообщением, но это неудобно — надо возвращаться назад, где введённые в формы данные потеряны.
С другой стороны, можно вызвать сервлет через AJAX XmlHttpRequest и вывести сообщение об ошибке, но как же тогда вернуть файл? Функции обратных вызовов объекта XHR не работают с пришедшими с сервера двоичными данными и не смогут показать стандартный браузерный диалог «Сохранить/загрузить файл».
Вышли из положения таким образом. Клиент вызывает сервлет два раза. На шаге 1 он просит его загрузить файл из серверного хранилища (по технологии AJAX передавая все необходимые для этого параметры), сервлет вычитывает файл и кладёт его содержимое, имя, MIME-тип и прочие атрибуты в сессию, а клиенту отвечает (формат ответа JSON) либо неким session_id (документ успешно получен и ждёт клиента), либо строкой ошибки, которую Javascript на клиенте легко покажет через window.alert() . Получив на шаге 1 session_id, клиент делает второй ход: с помощью обычной переадресации вида example.com/servletname?session_ > тут же делает следующий запрос к тому же сервлету с этим параметром и получает в ответ Content-Type: application/octet-stream сотоварищи, что в конечном итоге приводит к появлению стандартного диалога в браузере. После этого документ удаляется из сессии, освобождая место.
Несколько коротких замечаний:
- Для всей AJAX-кухни мы используем MochiKit старой версии 1.3.1.
- При выдаче документа с не-ASCII символами в имени файла это имя не отображается правильно во всех браузерах.
- Для формирования JSON-ответов можно было бы воспользоваться готовыми библиотеками, например распространённой json-lib, но для такой малой задачи не хотелось добавлять к проекту новых зависимостей.
Дополнительное описание работы можно получить в представленном коде.
Абстрактный Java-класс, выполняющий основную работу. Конкретный класс-наследний должен реализовать в нём два метода, уникальных для каждого случая.
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Serializable;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* Сервлет для получения документа с сервера.
*
*
Потомки этого класса должны реализовать следующие методы:
*
* populateIdentity(HttpServletRequest)
* Чтение из запроса данных, которые будут участвовать в поиске
* документа.
* getDocument(HttpServletRequest, Object)
* Получение непосредственно документа на клиента.
*
*
*
* Параметры: либо набор параметров для получения документа с EJB (поиск
* на сервере по этим параметрам), либо параметр с именем
* AbstractGetFileAJAXWay#DSID (идентификатор, полученный после первого запроса
* сервера) для непосредственной выдачи документа клиенту.
*
Варианты JSON-ответа первого шага:
*
*
Успешное получение документа с EJB:
*
*
*
Ошибка получения документа с EJB:
*
*
*
*/
public abstract class AbstractGetFileAJAXWay extends HttpServlet <
public static final String DS ;
public class GetFileAJAXWayException extends Exception <
public GetFileAJAXWayException() < super(); >
public GetFileAJAXWayException(String msg) < super(msg); >
public GetFileAJAXWayException(Throwable thw) < super(thw); >
public GetFileAJAXWayException(String msg, Throwable thw) < super(msg, thw); >
>
public interface IFileContainer extends Serializable <
public String getFileName();
public String getContentType();
public long getFileLength();
public byte[] getFileContent();
>
/**
* Точка входа в сервлет.
*
* @param req HTTP-запрос.
* @param resp HTTP-ответ.
* @throws ServletException
* @throws IOException
*/
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException <
// Выдача документа клиенту.
String ds >
// Выдача документа клиенту.
if (ds > 0) <
try <
deliverDocument(dsid, req, resp);
> catch (GetFileAJAXWayException e) <
e.printStackTrace();
throw new ServletException(e);
>
>
// Запрос документа с сервера.
else if (req.getParameterMap().size() > 0) <
try <
Object > retrieveDocument(identity, req, resp);
> catch (GetFileAJAXWayException e) <
e.printStackTrace();
throw new ServletException(e);
>
>
// Чёрти что.
else <
final String err = «Неизвестный режим работы!»;
log(err);
sendFailureReply(err, resp);
return;
>
>
/**
* Получение документа с сервера и сохранение его в сессии для последующего забора.
* @param identity Объект с данными, которые участвуют в поиске документа. * @param req HTTP-запрос.
* @param resp HTTP-ответ.
* @throws ServletException
* @throws IOException
*/
private void retrieveDocument
(Object identity, HttpServletRequest req, HttpServletResponse resp)
throws IOException <
// Сессия.
HttpSession session = req.getSession(false);
// Получение документа с помощью метода, реализованного в наследнике.
IFileContainer cont;
try <
cont = getDocument(req, identity);
> catch (Exception e) <
final String err = «Ошибка получения документа с сервера: »
+ e.getMessage() + «!»;
log(err);
sendFailureReply(err, resp);
return;
>
// Уникальный идентификатор объекта.
final String ds > new long[] < cont.hashCode(),
cont.getFileLength(),
session.hashCode() >);
// Сохранение документа в пользовательской сессии.
session.setAttribute(dsid, cont);
// Выдача клиенту сообщения о результате работы.
sendSuccessReply(dsid, resp);
>
/**
* Выдача ранее полученного документа клиенту.
* @param dsid Идентификатор документа в сессии.
* @param req HTTP-запрос.
* @param resp HTTP-ответ.
* @throws ServletException
* @throws IOException
*/
private void deliverDocument
(String dsid, HttpServletRequest req, HttpServletResponse resp)
throws GetFileAJAXWayException, IOException <
// Сессия.
HttpSession session = req.getSession(false);
// Есть ли такой документ?
Object sessobj = session.getAttribute(dsid);
if (sessobj == null) <
throw new GetFileAJAXWayException(«Нет объекта \»» + DSID + «\» в сессии!»);
> else if (!(sessobj instanceof IFileContainer)) <
throw new GetFileAJAXWayException(«Неверный объект \»» + DSID + «\» в сессии!»);
>
// Удаление документа из сессии.
session.removeAttribute(dsid);
// Документ.
IFileContainer document = (IFileContainer) sessobj;
// Выдача файла.
resp.setStatus(HttpServletResponse.SC_OK);
resp.setContentLength((int) document.getFileLength());
resp.setContentType(document.getContentType());
resp.setHeader(«Content-Transfer-Encoding», «binary»);
/* // По стандарту — в IE не работает
String filename = «=?windows-1251?Q?» + new org.apache.commons.codec.net.QuotedPrintableCodec().encode(document.getFileName(), «Cp1251») + «?=»;
resp.setHeader(«Content-Disposition», «attachment; filename=\»» + filename + «\»»);
*/
/* // Обещали работу в IE — фиг
String filename = java.net.URLEncoder.encode(document.getFileName(), «Cp1251»).replaceAll(«\\+», » «);
resp.setHeader(«Content-Disposition», «attachment; filename=\»» + filename + «\»»);
*/
/**/ // По-тупому
String filename = document.getFileName();
int dotpos = filename.lastIndexOf(‘.’);
if (dotpos > -1)
filename = «file.» + filename.substring(dotpos + 1);
else
filename = «file.dat»;
resp.setHeader(«Content-Disposition», «attachment; filename=\»» + filename + «\»»);
/**/
OutputStream out = resp.getOutputStream();
out.write(document.getFileContent());
out.flush();
out.close();
>
/**
* Уникальный номер документа, положенного в сессию для последующего забора.
*
* @param trashheap Набор произвольных чисел для генерации случайного результата.
* Может быть null, в этом случае в генерации не участвует.
* @return Уникальный идентификатор документа в сессии.
*/
private String dsid(long[] trashheap) <
long ds > if (trashheap != null && trashheap.length > 0)
for (int i = 0; i return Long.toString(Math.abs(new Random(dsid).nextLong()), 10);
>
/**
* Экранирование символов в строках для присоединения их к строке формата JSON.
* @param subject Исходная строка.
* @return Результат.
*/
private String escapeJSON(String subject) <
if (subject == null || subject.length() == 0)
return «»;
return subject.replaceAll(«\»», «\\\»»)
.replaceAll(«\\\\», «\\\\»)
.replaceAll(«[\n\r]», «\\\\n»);
>
/**
* Формирование и отправка JSON-сообщения об успешном завершении работы.
* @param dsid Идентификатор документа в сессии, который (документ) впоследствие можно забрать.
* @param resp HTTP-ответ.
* @throws ServletException
* @throws IOException
*/
private void sendSuccessReply(String dsid, HttpServletResponse resp)
throws IOException <
String ds
+ escapeJSON(dsid) + «\»>»;
/**
* Формирование и отправка JSON-сообщения об ошибке работы.
* @param reason Строка ошибки.
* @param resp HTTP-ответ.
* @throws ServletException
* @throws IOException
*/
private void sendFailureReply(String reason, HttpServletResponse resp)
throws IOException <
String reasonJSON = » <\"result\":\"failure\",\"reason\":\""
+ escapeJSON(reason) + «\»>»;
/**
* Отправка сообщения клиенту.
* @param json Отправляемая строка.
* @param resp HTTP-ответ.
* @throws IOException
*/
private void sendAnyReply(String json, HttpServletResponse resp)
throws IOException <
final byte[] result_bytes = json.getBytes(«UTF-8»);
final int CHUNK = 1024;
final BufferedOutputStream output = new BufferedOutputStream(
resp.getOutputStream(), CHUNK);
resp.setStatus(HttpServletResponse.SC_OK);
resp.setHeader(«Content-Encoding», «UTF-8»);
resp.setContentType(«text/plain; charset=UTF-8»);
resp.setContentLength(result_bytes.length);
int bytes_pos = 0, bytes_chunk = 0;
do <
bytes_chunk = bytes_pos + CHUNK
Класс-наследник, реализующий требуемую для конкретного случая логику.
public class ConcreteDocumentRetrievalServlet extends AbstractGetFileAJAXWay <
public ConcreteDocumentRetrievalServlet() <
super();
>
public Object populateIdentity(HttpServletRequest req)
throws GetFileAJAXWayException <
// Код чтения данных из запроса.
return null;
>
public IFileContainer getDocument(HttpServletRequest req, Object identity)
throws GetFileAJAXWayException <
// Код получения файла из серверного хранилища.
return null;
>
>
Примерный JSP-файл, осуществляющий взаимодействие с сервлетом.
Передача бинарного файла клиенту из jsp
Потому что это нелогично. Ты не можешь взять тебе то, чего тебе не дают.
wF = File.createTextFile(«C://файл.xxx»);
Вот из-за этого весь баг. Из соображений безопаснопасности — ты не можешь получить доступ к файловой системе юзера.
И это не целесообразно зачем его туда сохранять?
25.06.2008, 15:28 | #5 |
25.06.2008, 21:18 | #6 |