【问题标题】:Convert UTF-16 to UTF-8 and remove BOM?将 UTF-16 转换为 UTF-8 并删除 BOM?
【发布时间】:2012-02-08 06:57:25
【问题描述】:

我们有一个数据录入人员,他在 Windows 上使用 UTF-16 编码,希望使用 utf-8 并删除 BOM。 utf-8 转换有效,但 BOM 仍然存在。我将如何删除它?这是我目前拥有的:

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-|

在结果文件中。如何删除 BOM?

谢谢

【问题讨论】:

    标签: python unicode utf-8 utf-16


    【解决方案1】:

    这是UTF-16LEUTF-16之间的区别

    • UTF-16LE 是小端没有 BOM
    • UTF-16 是大端还是小端带有 BOM

    所以当您使用UTF-16LE 时,BOM 只是文本的一部分。请改用UTF-16,因此会自动删除 BOM。 UTF-16LEUTF-16BE 存在的原因是人们可以在没有 BOM 的情况下携带“正确编码”的文本,这不适用于您。

    请注意,当您使用一种编码进行编码并使用另一种编码进行解码时会发生什么。 (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)
    

    或者您可以在 shell 中执行此操作:

    for x in * ; do iconv -f UTF-16 -t UTF-8 <"$x" | dos2unix >"$x.tmp" && mv "$x.tmp" "$x"; done
    

    【讨论】:

      【解决方案2】:

      只需使用str.decodestr.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 将为您摆脱 BOM(并推断字节序)。

      【讨论】:

      • cool - 效果很好,你知道如何在读取中添加 crlf -> lf 转换工具吗?谢谢,如果你能提供帮助
      • 如果您正在处理大文件,这种方法(将整个文件存储在内存中两次)效率不高。
      猜你喜欢
      • 2014-02-11
      • 2015-09-21
      • 2015-09-19
      • 2021-12-21
      • 1970-01-01
      • 2017-09-24
      • 1970-01-01
      • 2013-05-20
      相关资源
      最近更新 更多