Гость
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Получить текст из bytea / 6 сообщений из 6, страница 1 из 1
25.10.2021, 00:47
    #40106519
DbDude
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить текст из bytea
В поле content типа bytea сохранен текст HTML-файла.
При попытке преобразовать его в текст выражением content::text первая строка файла выглядит так

<\000!\000D\000O\000C\000T\000Y\000P\000E\000 \000h\000t\000m\000l\000>

А должно быть

<!DOCTYPE html>

То есть появились нули для каждого символа. ! отображается как \000! и т.д..
Как это исправить?
...
Рейтинг: 0 / 0
25.10.2021, 13:04
    #40106622
Swa111
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить текст из bytea
DbDude,

попробуйте так , функции можно будет перенести в public

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
-- convert from bytea, containing UTF-16-BE data
CREATE OR REPLACE FUNCTION pg_temp.convert_from_utf16be(utf16_data bytea, invalid_replacement text DEFAULT '?')
  RETURNS text
  LANGUAGE sql
  IMMUTABLE
  STRICT
AS $function$
WITH source(unit) AS (
  SELECT (get_byte(utf16_data, i) << 8) | get_byte(utf16_data, i + 1)
  FROM generate_series(0, octet_length(utf16_data) - 2, 2) i
),
codes(lag, unit, lead) AS (
  SELECT lag(unit, 1) OVER (), unit, lead(unit, 1) OVER ()
  FROM source
)
SELECT string_agg(CASE
  WHEN unit >= 56320 AND unit <= 57343 THEN CASE
    WHEN lag >= 55296 AND lag <= 56319 THEN '' -- already processed
    ELSE invalid_replacement
  END
  WHEN unit >= 55296 AND unit <= 56319 THEN CASE
    WHEN lead >= 56320 AND lead <= 57343 THEN chr((unit << 10) + lead - 56613888)
    ELSE invalid_replacement
  END
  ELSE chr(unit)
END, '')
FROM codes
$function$;

-- convert from bytea, containing UTF-16-LE data
CREATE OR REPLACE FUNCTION pg_temp.convert_from_utf16le(utf16_data bytea, invalid_replacement text DEFAULT '?')
  RETURNS text
  LANGUAGE sql
  IMMUTABLE
  STRICT
AS $function$
WITH source(unit) AS (
  SELECT get_byte(utf16_data, i) | (get_byte(utf16_data, i + 1) << 8)
  FROM generate_series(0, octet_length(utf16_data) - 2, 2) i
),
codes(lag, unit, lead) AS (
  SELECT lag(unit, 1) OVER (), unit, lead(unit, 1) OVER ()
  FROM source
)
SELECT string_agg(CASE
  WHEN unit >= 56320 AND unit <= 57343 THEN CASE
    WHEN lag >= 55296 AND lag <= 56319 THEN '' -- already processed
    ELSE invalid_replacement
  END
  WHEN unit >= 55296 AND unit <= 56319 THEN CASE
    WHEN lead >= 56320 AND lead <= 57343 THEN chr((unit << 10) + lead - 56613888)
    ELSE invalid_replacement
  END
  ELSE chr(unit)
END, '')
FROM codes
$function$;

-- convert from bytea, containing UTF-16 data (with or without BOM)
CREATE OR REPLACE FUNCTION pg_temp.convert_from_utf16(utf16_data bytea, invalid_replacement text DEFAULT '?')
  RETURNS text
  LANGUAGE sql
  IMMUTABLE
  STRICT
AS $function$
SELECT CASE COALESCE(octet_length(utf16_data), 0)
  WHEN 0 THEN ''
  WHEN 1 THEN invalid_replacement
  ELSE CASE substring(utf16_data FOR 2)
    WHEN E'\\xFFFE' THEN pg_temp.convert_from_utf16le(substring(utf16_data FROM 3), invalid_replacement)
    ELSE pg_temp.convert_from_utf16be(substring(utf16_data FROM 3), invalid_replacement)
  END
END
$function$;



select pg_temp.convert_from_utf16be('\000<\000!\000D\000O\000C\000T\000Y\000P\000E\000 \000h\000t\000m\000l\000>'::bytea,'?')

...
Рейтинг: 0 / 0
25.10.2021, 13:35
    #40106647
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить текст из bytea
DbDude
То есть появились нули для каждого символа. ! отображается как \000! и т.д..

Это только отображение в результате перевода в текст. Смотрите настоящее содержимое, в байтах.
...
Рейтинг: 0 / 0
26.10.2021, 18:36
    #40107116
DbDude
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить текст из bytea
Swa111,
К сожалению работает не очень быстро.
Но другого способа я не нашел.
Спасибо.
...
Рейтинг: 0 / 0
26.10.2021, 18:38
    #40107118
DbDude
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить текст из bytea
Dimitry Sibiryakov,

Нужно
1) определить, что там за кодировка
2) преобразовать содержимое в читаемый текст
...
Рейтинг: 0 / 0
27.10.2021, 13:37
    #40107338
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить текст из bytea
Да. Для этого:
1) Посмотреть на содержимое в виде байт;
2) Применить правильный способ отображения.

Подсказываю: некоторые приложения способны правильно отображать UTF-16 без каких-либо дополнительных преобразований.
...
Рейтинг: 0 / 0
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Получить текст из bytea / 6 сообщений из 6, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]