2012-01-11 11 views
15

हटाएं हमारे पास डेटा एंट्री व्यक्ति है जो विंडोज़ पर यूटीएफ -16 में एन्कोड किया गया है और यूटीएफ -8 और बीओएम को हटाना चाहता है। यूटीएफ -8 रूपांतरण काम करता है लेकिन बीओएम अभी भी वहां है। मैं इसे कैसे हटाऊंगा?कनवर्टिंग utf-16 -> 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 मैं देख रहा हूँ:

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-| 
परिणामी फ़ाइल में

यह मैं वर्तमान में क्या है। मैं बीओएम कैसे हटा सकता हूं?

THX

उत्तर

19

बस 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 आप के लिए बीओएम से छुटकारा मिल जाएगा (और endianness अनुमान)।

+0

शांत - अच्छी तरह से काम करता है, तो आप एक CRLF जोड़ने के लिए कैसे जानते हो -> वामो रूपांतरण पढ़ने में सुविधा? thx अगर आप – timpone

+0

मदद कर सकते हैं (उस फ़ाइल को दो बार स्मृति में संग्रहीत करना) बहुत प्रभावी नहीं है, अगर आप बड़ी फाइलों के साथ काम कर रहे हैं। –

28

यह UTF-16LE और UTF-16

  • UTF-16LE के बीच अंतर है थोड़ा endian के बिना एक बीओएम
  • 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 
संबंधित मुद्दे