Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Java Новый топик    Ответить
 Чтение строки порциями и объединение результата  [new]
faustgreen
Member

Откуда:
Сообщений: 377
Алгоритм:
1). Читаем данные из файла в буфер, размером например [1023] байта.
buffer = read bytes ...

2). Преобразуем его в строку в нужной кодировке.
String value = new String(buffer, "some encoding");

3). Выводим на экран.
4). Повторяем шаги 1-3 до конца файла.

Правильно ли я понимаю, что:
Разные кодировки используют различное количество байт для кодирования, и, если мы будем читать данные порциями, то для нашего алгоритма какой нибудь символ может "порваться". Если да, то как можно "стыковать" считываемые блоки (При условии, что кодировка может быть любой)?

[][] [][] [][] []  | [] [][] [][]
[ a] [b ] [c ] [ d |  ]  [e]  [f ]
{первая порция}    | {вторая порция}


Набросал небольшой код, который преобразует строку в набор байт в кодировке "UTF-16". А потом в цикле считывает байты от 0 до длины буфера-i и преобразовывает в строку:
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;

public class Newc {
	public static void main(String[] args) throws UnsupportedEncodingException {
		
		String str = "Hello"; // Utf-8 is default.
		
		byte[] buffer = str.getBytes(StandardCharsets.UTF_16);

		System.out.println("Buffer length: " +  buffer.length + " bytes");
		
		String s2=null;
		
		for (int i=0; i<buffer.length; i++) {	
			s2 = new String(buffer, 0, buffer.length-i, StandardCharsets.UTF_16);
			System.out.println(i + " - " + s2);
		}
	}
}

Результат:
Buffer length: 12 bytes
0 - Hello
1 - Hell&#65533;
2 - Hell
3 - Hel&#65533;
4 - Hel
5 - He&#65533;
6 - He
7 - H&#65533;
8 - H
9 - &#65533;
10 - 
11 - &#65533;

Результат, если читаем с i-того байта до конца:
Buffer length: 12 bytes
0 -  Hello
1 - &#65280;&#18432;&#25856;&#27648;&#27648;&#65533;
2 -  Hello
3 -  &#18432;&#25856;&#27648;&#27648;&#65533;
4 -   ello
5 -   &#25856;&#27648;&#27648;&#65533;
6 -    llo
7 -    &#27648;&#27648;&#65533;
8 -     lo
9 -      &#27648;&#65533;
10 -     o
11 -     &#65533;
27 фев 20, 18:17    [22088612]     Ответить | Цитировать Сообщить модератору
 Re: Чтение строки порциями и объединение результата  [new]
mayton
Member

Откуда: loopback
Сообщений: 45514
faustgreen, нет нет все неправильно. Парсер Utf-8 - это конечный
автомат который помнит состояние в переходах между байтами.
И если ты неудачно порезал текстовый файл на куски то теоретически
ты разрезал 1 символ на 2 байта которые порознь не имеют смысла
и это состояние парсера надо передавать между блочными итерациями алгоритма.

Но чтобы ты не изобретал велосипед - в JDK уже есть коробоные механизмы которые работают.

Посмотри на следующий стек из компонентов.
// Байты и массивы байтов
InputStream inputStream = new FileInputStream("file.txt");        
// Символы и массивы символов
InputStreamReader reader = new InputStreamReader(inputStream, "UTF-8");
// Строки
BufferedReader bufferedReader = new BufferedReader(reader);

Вот работай на уровне reader или bufferedReader.

Читать текстовый файл двоичными операциями это либо баловство либо просто студенческая
работа из серии "посмотреть что будет". В обоих случаях качество твоего кода на выходе будет
плохим т.к. тебе сложно поддержать на 100% спецификации Unicode. Их много и они нудные.
27 фев 20, 18:31    [22088626]     Ответить | Цитировать Сообщить модератору
 Re: Чтение строки порциями и объединение результата  [new]
iJava
Member [заблокирован]

Откуда:
Сообщений: 48
faustgreen


Правильно ли я понимаю, что:

гуглить не пробовал ? ты правильно понимаешь - разный кодировки на то и разные )
где то на символ 2 байта ,где то 8
27 фев 20, 23:17    [22088748]     Ответить | Цитировать Сообщить модератору
 Re: Чтение строки порциями и объединение результата  [new]
Leonid Kudryavtsev
Member

Откуда:
Сообщений: 8475
iJava
....где то 8

Где?
27 фев 20, 23:41    [22088754]     Ответить | Цитировать Сообщить модератору
 Re: Чтение строки порциями и объединение результата  [new]
asv79
Member

Откуда: Тверь
Сообщений: 2991
Leonid Kudryavtsev
iJava
....где то 8

Где?

UTF-8 например?
28 фев 20, 10:06    [22088841]     Ответить | Цитировать Сообщить модератору
 Re: Чтение строки порциями и объединение результата  [new]
Basil A. Sidorov
Member

Откуда:
Сообщений: 10009
asv79
UTF-8 например?
Опять мимо - от одного до четырёх байт на кодовую точку.
28 фев 20, 11:06    [22088885]     Ответить | Цитировать Сообщить модератору
 Re: Чтение строки порциями и объединение результата  [new]
Alexander A. Sak
Member

Откуда: Омск
Сообщений: 1085
asv79
Leonid Kudryavtsev
пропущено...

Где?

UTF-8 например?


Логично. В UTF-8 до 8 байт. Тогда в UTF-16 до 16 байт, а в UTF-32 - до 32 байт.
Гуглить не пробовал? (с)
28 фев 20, 11:54    [22088943]     Ответить | Цитировать Сообщить модератору
 Re: Чтение строки порциями и объединение результата  [new]
mayton
Member

Откуда: loopback
Сообщений: 45514
Alexander A. Sak
asv79
пропущено...

UTF-8 например?


Логично. В UTF-8 до 8 байт. Тогда в UTF-16 до 16 байт, а в UTF-32 - до 32 байт.
Гуглить не пробовал? (с)

Твоя репутация подмочена.
28 фев 20, 12:11    [22088959]     Ответить | Цитировать Сообщить модератору
 Re: Чтение строки порциями и объединение результата  [new]
asv79
Member

Откуда: Тверь
Сообщений: 2991
Basil A. Sidorov
asv79
UTF-8 например?
Опять мимо - от одного до четырёх байт на кодовую точку.

я имел ввиду бит а не байт) простите великодушно)
28 фев 20, 20:54    [22089530]     Ответить | Цитировать Сообщить модератору
 Re: Чтение строки порциями и объединение результата  [new]
вадя
Member

Откуда: Екатеринбург
Сообщений: 17568
asv79
я имел ввиду бит а не байт) простите великодушно)
прежде чем писать - гугли

UTF-8 является самосинхронизирующейся кодировкой: при потере одного байта последующие байты будут 
раскодированы корректно.

Текст, состоящий только из символов Юникода с номерами меньше 128, при записи в UTF-8 превращается в
обычный текст ASCII. И наоборот, в тексте UTF-8 любой байт со значением меньше 128 изображает символ ASCII
с тем же кодом. Остальные символы Юникода изображаются последовательностями длиной от 2 до 6 байт
(реально только до 4 байт, поскольку использование кодов больше 221 не планируется), в которых первый байт
всегда имеет вид 11xxxxxx, а остальные — 10xxxxxx.

Проще говоря, в формате UTF-8 символы латинского алфавита, знаки препинания и управляющие символы ASCII
записываются кодами US-ASCII, a все остальные символы кодируются при помощи нескольких байтов со старшим
битом 1.
Подробнее: http://wikireality.ru/wiki/UTF-8


Сообщение было отредактировано: 28 фев 20, 21:27
28 фев 20, 21:25    [22089539]     Ответить | Цитировать Сообщить модератору
 Re: Чтение строки порциями и объединение результата  [new]
Basil A. Sidorov
Member

Откуда:
Сообщений: 10009
asv79
я имел ввиду бит а не байт) простите великодушно)
С количеством бит на байт определились вскоре после изобретения тыртырнетов.
Древний RFC на FTP ещё рассматривает системы с разной разрядностью, а всё более-менее современное, если требуется, явно оговаривает "clear eight bit" и пользуется терминами октет и байт как синонимами.
29 фев 20, 06:56    [22089639]     Ответить | Цитировать Сообщить модератору
 Re: Чтение строки порциями и объединение результата  [new]
Roman Mejtes
Member

Откуда: г. Пермь
Сообщений: 3787
asv79
Basil A. Sidorov
пропущено...
Опять мимо - от одного до четырёх байт на кодовую точку.

я имел ввиду бит а не байт) простите великодушно)

но только в UTF-8 символы не 8 битами кодируются, опять мимо, в зависимости от самого символа, это может быть 8, 16 и 32 бита
2 мар 20, 17:40    [22090938]     Ответить | Цитировать Сообщить модератору
 Re: Чтение строки порциями и объединение результата  [new]
Basil A. Sidorov
Member

Откуда:
Сообщений: 10009
Roman Mejtes
но только в UTF-8 символы не 8 битами кодируются, опять мимо, в зависимости от самого символа, это может быть 8, 16 и 32 бита
Только кодируются не символы, а кодовые точки или просто коды.
Код юникода, как ему и положено, является целым числом. Разрядность этого числа ограничена - двадцать один бит.
Сколько байт будет использовать кодировка юникода - зависит от кодировки.
Только всё это никак не меняет того простого факта, что "байт" и "октет" уже давно - синонимы.
2 мар 20, 17:58    [22090959]     Ответить | Цитировать Сообщить модератору
 Re: Чтение строки порциями и объединение результата  [new]
asv79
Member

Откуда: Тверь
Сообщений: 2991
Roman Mejtes

но только в UTF-8 символы не 8 битами кодируются, опять мимо, в зависимости от самого символа, это может быть 8, 16 и 32 бита

ты сам себе противоречишь)
не кодируются 8 битами,кодируются 8 ,16,32
и почему ты пропустил 3 октета ,тобишь 24 бита?
тоесть вы прямо сейчас поставил китайцев ,японцев ,грузинов и прочих людей перед выбором писать латиницей или забыть свой алфавит?)))
3 мар 20, 11:26    [22091405]     Ответить | Цитировать Сообщить модератору
Все форумы / Java Ответить