Конвертировать UTF-16 в UTF-8 и удалить BOM?
У нас есть человек ввода данных, который закодирован в UTF-16 на Windows и хотел бы иметь utf-8 и удалить спецификацию. Преобразование utf-8 работает, но спецификация все еще существует. Как я могу удалить это? Это то, что я сейчас имею:
batch_3={'src':'/Users/jt/src','dest':'/Users/jt/dest/'}
batches=[batch_3]
for b in batches:
s_files=os.listdir(b['src'])
for file_name in s_files:
ff_name = os.path.join(b['src'], file_name)
if (os.path.isfile(ff_name) and ff_name.endswith('.json')):
print ff_name
target_file_name=os.path.join(b['dest'], file_name)
BLOCKSIZE = 1048576
with codecs.open(ff_name, "r", "utf-16-le") as source_file:
with codecs.open(target_file_name, "w+", "utf-8") as target_file:
while True:
contents = source_file.read(BLOCKSIZE)
if not contents:
break
target_file.write(contents)
Если я hexdump -C, я вижу:
Wed Jan 11$ hexdump -C svy-m-317.json
00000000 ef bb bf 7b 0d 0a 20 20 20 20 22 6e 61 6d 65 22 |...{.. "name"|
00000010 3a 22 53 61 76 6f 72 79 20 4d 61 6c 69 62 75 2d |:"Savory Malibu-|
в полученном файле. Как удалить спецификацию?
ТНХ
Ответы
Ответ 1
Просто используйте str.decode
и str.encode
:
with open(ff_name, 'rb') as source_file:
with open(target_file_name, 'w+b') as dest_file:
contents = source_file.read()
dest_file.write(contents.decode('utf-16').encode('utf-8'))
str.decode
избавится от спецификации для вас (и выведет конечность).
Ответ 2
В этом разница между UTF-16LE
и UTF-16
-
UTF-16LE
немного сущ. без спецификация
-
UTF-16
- большой или маленький endian с спецификацией
Поэтому, когда вы используете UTF-16LE
, спецификация только часть текста. Вместо этого используйте UTF-16
, поэтому спецификация автоматически удаляется. Причина UTF-16LE
и UTF-16BE
заключается в том, что люди могут переносить "правильно закодированный" текст без спецификаций, что не относится к вам.
Обратите внимание, что происходит при кодировании с использованием одного кодирования и декодирования с использованием другого. (UTF-16
иногда обнаруживает UTF-16LE
иногда, не всегда.)
>>> u'Hello, world'.encode('UTF-16LE')
'H\x00e\x00l\x00l\x00o\x00,\x00 \x00w\x00o\x00r\x00l\x00d\x00'
>>> u'Hello, world'.encode('UTF-16')
'\xff\xfeH\x00e\x00l\x00l\x00o\x00,\x00 \x00w\x00o\x00r\x00l\x00d\x00'
^^^^^^^^ (BOM)
>>> u'Hello, world'.encode('UTF-16LE').decode('UTF-16')
u'Hello, world'
>>> u'Hello, world'.encode('UTF-16').decode('UTF-16LE')
u'\ufeffHello, world'
^^^^ (BOM)
Или вы можете сделать это в оболочке:
for x in * ; do iconv -f UTF-16 -t UTF-8 <"$x" | dos2unix >"$x.tmp" && mv "$x.tmp" "$x"; done