Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Скачанная страница содержит квадратики, почему? Местами(!) вместо нормального символа � 
:(
    Опции темы
i_SweP
Дата 26.10.2010, 20:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 126
Регистрация: 23.6.2007

Репутация: нет
Всего: нет



Скачиваю страницу, код такой:

Код

    String s = String.format( "POST http://%s/%s%s\nHost: %s\nProxy-Connection: close\n\n", host, SITE_REQ, req, host );

    socket = new Socket( host, 80 );
    OutputStream os = socket.getOutputStream();
    os.write( s.getBytes() );
    InputStream is = socket.getInputStream();

    siteCache = new StringBuffer();
    byte[] bytes = new byte[10 * 1024];    // тут пробовал разные значения, не помогло
    int len = 1;
    while ( len > 0 )
    {
        len = is.read( bytes );
        if ( len > 0 ) siteCache.append( new String( bytes, 0, len ) );
    }

    socket.close();

В результате на странице пять - десять рандомных квадратиков, типа такого: "Санкт-Пете��бург" (через браузер всё ОК)
Почему так получается?



Это сообщение отредактировал(а) i_SweP - 26.10.2010, 20:10
PM MAIL   Вверх
jk1
Дата 26.10.2010, 22:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1168
Регистрация: 17.10.2008
Где: Санкт-Петербург

Репутация: 2
Всего: 75



Цитата

Почему так получается?

Потому что Вы читаете символы как байты, да еще и используете строки как контейнеры массивов байт, чего делать не следует.
Раз вас интересуют символы, так читайте символы при помощи Reader:
Код

new BufferedReader(new InputStreamReader(socket.getInputStream()));

Во избежание проблем рекомендуется также задавать Reader'у кодировку, у него есть конструктор, который помимо потока принимает еще и кодировку. Если явно её не задать, считывание будет происходить в кодировке по умолчанию, которая совершенно необязательно должна совпадать с кодировкой запрашиваемой страницы.


--------------------
Opinions are like assholes — everybody has one
PM MAIL   Вверх
Kircul
Дата 27.10.2010, 12:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 166
Регистрация: 20.2.2007

Репутация: нет
Всего: 7



Я так понимаю что прочтенные данные пойдут дальше в поток os, я предлагаю сделать так:
Код

String s = String.format("POST http://%s/%s%s\nHost: %s\nProxy-Connection: close\n\n", host, SITE_REQ, req, host);
Socket socket = new Socket(host, 80);
OutputStream os = socket.getOutputStream();
os.write(s.getBytes());
InputStream is = socket.getInputStream();
byte[] bytes = new byte[10 * 1024];    // тут не надо пробовать, "new String( bytes, 0, len )" - вот так делать не нужно
for (int len; (len = is.read(bytes)) != -1;) {
    os.write(bytes, 0, len);
}
socket.close();

Не используя строковый буффер.
PM   Вверх
i_SweP
Дата 28.10.2010, 19:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 126
Регистрация: 23.6.2007

Репутация: нет
Всего: нет



jk1, 
Проблема ушла, спасибо. Честно говоря new String это было на скорую руку. Видать конструктор String не всегда нормально понимает байтовый массив.


Kircul, 
Sorry за  smile, но: в коде посылается запрос на страницу и она скачивается. Откуда предположение, что мы её, скачав, будем посылать обратно? )

Это сообщение отредактировал(а) i_SweP - 28.10.2010, 19:04
PM MAIL   Вверх
jk1
Дата 28.10.2010, 20:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1168
Регистрация: 17.10.2008
Где: Санкт-Петербург

Репутация: 2
Всего: 75



Цитата

Видать конструктор String не всегда нормально понимает байтовый массив.

Дело ведь не в конструкторе, а в самой идее: Вы превращаете в строку не весь массив, а по частям. Каждый символ в зависимости от кодировки может быть закодирован несколькими байтами, и даже переменным количеством байт. Вот не повезет Вам в очередной раз, разрежете искусственным буфером
Код

byte[] bytes = new byte[10 * 1024];

 символ пополам и все, в каждой из двух строк он невалиден.
Тут надо использовать посимвольное чтение с учетом кодировки, чтобы не резать байтовый массив в неудачных местах.


--------------------
Opinions are like assholes — everybody has one
PM MAIL   Вверх
Kircul
Дата 29.10.2010, 09:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 166
Регистрация: 20.2.2007

Репутация: нет
Всего: 7



Цитата(i_SweP @  28.10.2010,  18:03 Найти цитируемый пост)
Kircul, 
Sorry за  smile, но: в коде посылается запрос на страницу и она скачивается. Откуда предположение, что мы её, скачав, будем посылать обратно? )

Однозначно моя промашка.
В общем идея была такая, если в программе не нужно обробатывать скачаную страницу, то считывать бинарные данные из is.
Код

String s = String.format("POST http://%s/%s%s\nHost: %s\nProxy-Connection: close\n\n", host, SITE_REQ, req, host);
Socket socket = new Socket(host, 80);
OutputStream os = socket.getOutputStream();
os.write(s.getBytes());
InputStream is = socket.getInputStream();
byte[] bytes = new byte[10 * 1024];
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
for (int len; (len = is.read(bytes)) != -1;) {
    buffer.write(bytes, 0, len);
}
final String result = new String(buffer.toByteArray()); // так делать тоже не надо, 
                        // но это просто показывает что в таком случае вашей проблеммы не станет.
socket.close();

Но если нужно обрабатывать скачаные данные как строку, то вероятнее всего лучше использовать вариант предложеный jk1, т.е. обернуть Stream в Reader. 
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Работа с сетью | Следующая тема »


 




[ Время генерации скрипта: 0.0472 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.