13 de mayo de 2016

23. Escritura de archivos. Otros modos de trabajo. Archivos binarios.

Abriendo ficheros en varios modos

Los ficheros se pueden abrir en varios modos:
  1. Modo de lectura (r). Sólo se pueden leer los datos.
  2. Modo de escritura (w). Sólo se escriben datos, pero se borra lo anterior que estuviera escrito.
  3. Modo de añadir datos (a). Se escriben datos, añadiéndolos a los anteriores, al final del fichero.
  4. Si se añade a cualquiera de los anteriores un signo "+" (r+, w+, a+) se obtiene un modo doble de lectura - escritura. Pero hay que tener en cuenta que no son iguales. Usar w+ implicaría también que al escribir datos se borren los datos anteriores.
  5. Si en modo lectura se intenta abrir un archivo inexistente, se generará un error.
  6. Si en modo w o a se abre un archivo inexistente, se creará.
  7. Si no se especifica el modo, por defecto se abren en modo de sólo lectura (r).
Para escribir en un archivo se pueden usar dos órdenes:
  1. archivo.write("Esto se guarda"), para escribir una cadena o...
  2. archivo.writelines(lista_de_cadenas), para escribir una lista de cadenas.
Por ejemplo, en este programa, se crean 50 números pares, y a continuación se añaden 50 números impares, y se leen todos desde el fichero.
# -*- coding: utf-8 -*-

archivo = open("numeros.txt", "w")

for i in range(50):
    # genera números pares
    archivo.write(str((i+1)*2)+"\n")

archivo.close()
# cierra el archivo

# lo abre otra vez en modo añadir y lectura
archivo = open("numeros.txt", "a+")

for i in range(50):
    # genera números impares
    archivo.write(str((i+1)*2-1)+"\n")

archivo.close()

archivo = open("numeros.txt", "a+")

i=1
for linea in archivo:
    linea = linea.rstrip("\n")
    print ("%d: %s") % (i, linea)
    i += 1

archivo.close()
===
Si eres observador, habrás notado que he abierto dos veces el archivo en modo a+... ¿por qué? ¿Por qué no poner el código de lectura a continuación del de escritura? Puedo hacerlo, pero antes hay que indicarle al archivo que apunte a la primera dirección del fichero. Si no, tendrá un funcionamiento incorrecto.
# -*- coding: utf-8 -*-

archivo = open("numeros.txt", "w")

for i in range(50):
    # genera números pares
    archivo.write(str((i+1)*2)+"\n")

archivo.close()
# cierra el archivo

# lo abre otra vez en modo añadir y lectura
archivo = open("numeros.txt", "a+")

for i in range(50):
    # genera números impares
    archivo.write(str((i+1)*2-1)+"\n")

archivo.seek(0) #apunta el fichero a la primera línea
i=1
for linea in archivo:
    linea = linea.rstrip("\n")
    print ("%d: %s") % (i, linea)
    i += 1

archivo.close()
= = =

Archivos binarios

Los ficheros suelen contener información en caracteres alfanuméricos o de cadena, pero también pueden ser ficheros binarios. La información se guarda directamente en bytes.
Los modos anteriormente escritos son válidos, agregando la letra b al parámetro de modo (rb, ab, wb...) aunque pueda funcionar sin agregar el parámetro en intérpretes modernos.
Las funciones a usar con archivos binarios son:
  1. contenido = archivo.read(n) , para leer n bytes.
  2. archivo.write(contenido), escribe en la posición actual.
  3. archivo.tell(), posición actual
  4. archivo.seek(inicio, desde), posiciona el puntero en el archivo. Inicio, la cantidad de bytes a desplazar, desde puede ser al principio, al final o la posición actual.
Otros métodos
  1. archivo.name, retorna el nombre del fichero actual.
  2. archivo.mode, el modo en el que fue abierto
  3. archivo.encoding, la codificación de caracteres usada.
= = =
Ejemplo: Guarda la siguiente imagen png en la carpeta donde guardas los programas. Nombre coche.png.
coche_png
Bien. Ahora ejecuta el siguiente programa. La línea en la que se lee cada byte del fichero puede convertirse o no a su número de orden ASCII o directamente a su código. Comenta / descomenta en cada caso.
# -*- coding: utf-8 -*-
imagen = open("coche.png", "rb")

print imagen.name
print imagen.mode
print imagen.encoding

print imagen.tell()
data = imagen.read()
print len(data)

imagen.seek(0)
lista = []
for i in range(len(data)):
    # lista.append(imagen.read(1))
    lista.append(ord(imagen.read(1)))

print lista
print len(lista)

print "terminó fichero"

imagen.close()
= = =
Aunque no saldrá ninguna imagen coherente, intenta generar esta foto de prueba en formato bmp.
# -*- coding: utf-8 -*-
import random

imagen = open("prueba.bmp", "wb")

lista = []
for i in range(1000):
    lista.append(random.randrange(0,256))
    imagen.write(str(lista[i]))

print lista

imagen.close()

No hay comentarios:

Publicar un comentario