Manipulación de archivos con caracteres no ascii en XP
Oswaldo Hernández
listas en soft-com.es
Mie Sep 2 15:18:40 CEST 2009
Hola a todos,
Disculpad por el rollo que va a continuación ya que este mensaje creo que es mas un desahogo que una
consulta ya que llevo un montón de horas dándole vueltas a esto. Imagino que estará documentado en
alguna parte, pero no lo he encontrado.
El problema: Manipulación de archivos con acentos u otros caracteres no ascii en el nombre.
Sistema: Python 2.5, Windows XP SP3
Condiguración de encoding y locale:
>>> sys.getdefaultencoding()
'UTF-8'
>>> sys.getfilesystemencoding()
'mbcs'
>>> locale.getlocale()
('es_ES', 'cp1252')
1ª Parte: Abrir archivo con en nombre directamente en codigo
--------
- Intento Abrir directamente el archivo:
>>> file = "c:\\temp\\Imágenes.txt"
>>> file
'c:\\temp\\Im\xc3\xa1genes.txt'
>>> open(file, "r")
Traceback (most recent call last):
File "<input>", line 1, in <module>
IOError: [Errno 2] No such file or directory: 'c:\\temp\\Im\xc3\xa1genes.txt'
- Intento abrir condificando el nombre del archivo a cp1252:
file = "c:\\temp\\Imágenes.txt".encode("cp1252")
file
'c:\\temp\\Im\xe1genes.txt'
open(file, "r")
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "C:\Python25\Lib\site-packages\wx-2.8-msw-unicode\wx\py\shell.py", line 1160, in writeOut
self.write(text)
File "C:\Python25\Lib\site-packages\wx-2.8-msw-unicode\wx\py\shell.py", line 950, in write
self.AddText(text)
File "C:\Python25\Lib\site-packages\wx-2.8-msw-unicode\wx\stc.py", line 1425, in AddText
return _stc.StyledTextCtrl_AddText(*args, **kwargs)
File "c:\python25\lib\encodings\utf_8.py", line 16, in decode
return codecs.utf_8_decode(input, errors, True)
UnicodeDecodeError: 'utf8' codec can't decode bytes in position 22-24: invalid data
- Intento abrir definiendo la cadena como unicode
>>> file = u"c:\\temp\\Imágenes.txt"
>>> file
u'c:\\temp\\Im\xc3\xa1genes.txt'
>>> open(file, "r")
Traceback (most recent call last):
File "<input>", line 1, in <module>
IOError: [Errno 2] No such file or directory: u'c:\\temp\\Im\xc3\xa1genes.txt'
- Intento abrir convirtiendo la cadena mediante la funcion unicode()
>>> file = "c:\\temp\\Imágenes.txt"
>>> file
'c:\\temp\\Im\xc3\xa1genes.txt'
>>> file = unicode(file)
>>> file
u'c:\\temp\\Im\xe1genes.txt'
>>> open(file, "r")
<open file u'c:\\temp\\Im\xe1genes.txt', mode 'r' at 0x01DAD218>
Funciona !!!. He tenido que convertir explicitamente con unicode(), la sintaxis u"..." no funciona.
2ª Parte: Abrir archivos con los nombres obtenidos con os.listdir()
---------
- Obtengo el nombre del archivo leyendo el directorio
>>> dir = "c:\\temp"
>>> archivos = os.listdir(dir)
>>> archivos
['Im\xe1genes.txt']
>>> file = os.path.join(dir, archivos[0])
>>> file
'c:\\temp\\Im\xe1genes.txt'
- Intento abrir el file que ha devuelto os.listdir()
>>> open(file, "r")
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "C:\Python25\Lib\site-packages\wx-2.8-msw-unicode\wx\py\shell.py", line 1160, in writeOut
self.write(text)
File "C:\Python25\Lib\site-packages\wx-2.8-msw-unicode\wx\py\shell.py", line 950, in write
self.AddText(text)
File "C:\Python25\Lib\site-packages\wx-2.8-msw-unicode\wx\stc.py", line 1425, in AddText
return _stc.StyledTextCtrl_AddText(*args, **kwargs)
File "c:\python25\lib\encodings\utf_8.py", line 16, in decode
return codecs.utf_8_decode(input, errors, True)
UnicodeDecodeError: 'utf8' codec can't decode bytes in position 22-24: invalid data
- Intento convertir el nombre del archivo a unicode:
>>> unicode(file)
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "c:\python25\lib\encodings\utf_8.py", line 16, in decode
return codecs.utf_8_decode(input, errors, True)
UnicodeDecodeError: 'utf8' codec can't decode bytes in position 10-12: invalid data
- Depues de investigar un poco veo que os.listdir() ha devuelto el nombre del archivo en cp1252,
intento decodificarlo:
>>> file = file.decode("cp1252")
>>> file
u'c:\\temp\\Im\xe1genes.txt'
>>> open(file, "r")
<open file u'c:\\temp\\Im\xe1genes.txt', mode 'r' at 0x01DAD770>
Funciona !!!, os.listdir ha devuelto los nombres de archivo como str en la codificación local y es
necesario decodificarlos.
3ª parte: Ejecución del archivos con subprocess.popen()
---------
Al ejecutarse el archivo con shell el sistema debe abrirlo con la aplicación asociada.
- Intento ejecutar el archivo obtenido con listdir() utilizando las mismas reglas que para open().
>>> dir = "c:\\temp"
>>> archivos = os.listdir(dir)
>>> file = os.path.join(dir, archivos[0])
>>> file = file.decode("cp1252")
>>> file
u'c:\\temp\\Im\xe1genes.txt'
>>> proc = subprocess.Popen(file, shell=True, env=os.environ.copy())
>>> proc.poll()
1
No ha funcionado, iluso de mi.
- Intento ejecutar tal cual ha devuelto os.listdir(), es decir como str y en codificacion cp1252
>>> dir = "c:\\temp"
>>> archivos = os.listdir(dir)
>>> file = os.path.join(dir, archivos[0])
>>> file
'c:\\temp\\Im\xe1genes.txt'
>>> proc = subprocess.Popen(file, shell=True, env=os.environ.copy())
>>> proc.poll()
0
Funciona !!!
- Intento ahora el popen indicando directamente el archivo a ejecutar:
>>> file = "c:\\temp\\Imágenes.txt"
>>> proc = subprocess.Popen(file, shell=True, env=os.environ.copy())
>>> proc.poll()
1
No funciona
- Intento convertir la cadena a unicode tal cual funcionaba con open()
>>> file = "c:\\temp\\Imágenes.txt"
>>> file = unicode(file)
>>> file
u'c:\\temp\\Im\xe1genes.txt'
>>> proc = subprocess.Popen(file, shell=True, env=os.environ.copy())
>>> proc.poll()
1
Tampoco funciona
- Intento confertir la cadena a cp1252
>>> file = "c:\\temp\\Imágenes.txt"
>>> file = file.encode("cp1252")
>>> file
'c:\\temp\\Im\xe1genes.txt'
>>> proc = subprocess.Popen(file, shell=True, env=os.environ.copy())
>>> proc.poll()
0
Funciona !!!
Conclusión para trabajar con archivos con caracteres no ascii en windows XP:
* open() precisa que el nombre de archivo sea una unicode.
* os.listdir() devuelve los nombres de archivo como str y en el locale
* subprocess.popen() requiere str en el locale
* No he comprobado el modulo shutil cuando hay acentos en los directorios, eso lo dejo para otro dia. :(
No se si se ha escapado algo en cuanto a la manipulación de archivos con caracteres no ascii, espero
que este follon solo sea cosa del XP de las narices y que en linux no suceda lo mismo.
Bueno, ya me he deshaogado. Disculpad el rollo como decia al principio.
Saludos,
--
*****************************************
Oswaldo Hernández
oswaldo (@) soft-com (.) es
*****************************************
PD:
Antes de imprimir este mensaje, asegúrese de que es necesario.
El medio ambiente está en nuestra mano.
_______________________________________________
Lista de correo Python-es
http://listas.aditel.org/listinfo/python-es
FAQ: http://listas.aditel.org/faqpyes
Más información sobre la lista de distribución Python-es