windows - Ændring af kodning af tekstfiler ved hjælp af Python: Det sker ikke

Indlæg af Hanne Mølgaard Plasc

Problem



Ved kopiering eller stort set rørende filer på nogen måde ændrer Windows deres kodning til standard 1252: Vesteuropæisk. I teksteditoren, jeg bruger EditPad Pro Plus, kan jeg se og konvertere kodningen. Jeg stoler på, at denne konvertering virker, fordi jeg har arbejdet med filer mellem Windows og UNIX, og jeg ved, at når min tekstredigerer ændrer sig kodninger, filerne læses korrekt i UNIX, hvor de førte til problemer før.


Jeg vil gerne konvertere filer en masse. Så jeg forsøger at gøre det ved hjælp af Python i Windows 10, kaldet fra enten Powershell (ved hjælp af Python v 3.6.2) eller CygWin (ved hjælp af Python v 2.7.13). Jeg ser både codecs og io]] bruges til jobbet og kommenterer at io er den rigtige måde for Python 3.


Men filerne er ikke konverteret - codecs eller io. Skriften nedenfor kopierer kopierne filerne, men min tekstredigerer rapporterer dem som 1252 stadig. Og UniversalDetectoren (i de kommenterede dele af scriptet nedenfor) rapporterer deres kodning som 'ascii'.


Hvad skal der ske for at få disse til at konvertere med succes?


import sys
import os
import io
#from chardet.universaldetector import UniversalDetector

BLOCKSIZE = 1048576
#detector = UniversalDetector()

#def get\_encoding( current\_file ):
#    detector.reset()
#    for line in file(current\_file):
#        detector.feed(line)
#        if detector.done: break
#    detector.close()
#    return detector.result['encoding']

def main():
    src\_dir = ""

    if len( sys.argv ) > 1:
        src\_dir = sys.argv[1]

    if os.path.exists( src\_dir ):
        dest\_dir = src\_dir[:-2]
        for file in os.listdir( src\_dir ):
            with io.open( os.path.join( src\_dir, file ), "r", encoding='cp1252') as source\_file:
                with io.open( os.path.join( dest\_dir, file ), "w", encoding='utf8') as target\_file:
                    while True:
                        contents = source\_file.read( BLOCKSIZE )
                        if not contents:
                            break
                        target\_file.write( contents )
#print( "Encoding of " + file + ": " + get\_encoding( os.path.join( dest\_dir, file ) ) )
    else:
        print( 'The specified directory does not exist.' )

if \_\_name\_\_ == "\_\_main\_\_":
    main()


Jeg har prøvet nogle variationer som f.eks. Åbning af filen som UTF8, kaldende læsning () uden blokeringsstørrelsen, og oprindelig blev kodningerne specificeret lidt anderledes. De kopierer alle kopierne filerne, men de må ikke kode dem efter hensigten.

Bedste reference


ASCII er den fælles delmængde til en hel del kodninger. Det er en delmængde af UTF-8, Latin-1 og cp1252-- og af hele ISO-8859-familien, der har kodninger til russisk, græsk osv. Hvis dine filer er virkelig ASCII, er der intet at konvertere og dit system det siger kun 'cp1252', fordi filerne er kompatible med dette. Du kan tilføje en BOM til at tagge en fil som UTF (kodning utf-8-sig), men ærligvis ser jeg ikke . UTF har ikke brug for det, fordi UTF-filer er genkendelige af strukturen af ​​multi-byte tegn. [10]


Hvis du vil eksperimentere med kodninger, skal du bruge tekst, der indeholder ikke-ASCII-tegn: fransk, russisk, kinesisk eller endda engelsk med nogle accentede ord (eller de dumme rettede citater, som Microsoft-applikationer gerne vil indsætte). Gem ordene 'Wikipédia en français' i en fil og gentag dine eksperimenter, og du får meget forskellige resultater.


Jeg stærkt anbefaler at bruge Python 3 til dette og for noget andet at gøre med tegnkoder. Python 2-tilgangen til kodning resulterer i en masse meningsløs forvirring, og var faktisk en af ​​hovedårsagerne til at bryde kompatibilitet og indføre Python 3.
Som en bonus, i Python 3 kan du bare bruge open() med et encoding argument. Du behøver ingen moduler til at ændre kodninger.