Manipulación de archivos con caract eres no ascii en XP

Oswaldo Hernández <[email protected]>
Newsgroups gmane.comp.python.general.castellano
Message-ID <[email protected]>
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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.