2010-06-12 32 views
8

Estoy escribiendo un programa de lista de tareas pendientes. Mantiene un archivo con una cosa que hacer por línea y permite al usuario agregar o eliminar elementos. El problema es que, por algún motivo, termino con muchos bytes cero al comienzo del archivo, aunque el elemento se eliminó correctamente. Le mostraré un par de capturas de pantalla para asegurarme de que me aclaro.Escribir en un archivo en Python inserta bytes nulos

Este es el archivo en Notepad ++ antes de ejecutar el programa:

Normal todo list http://img683.imageshack.us/img683/2812/beforew.png

Este es el archivo después de eliminar el punto 3 (contando desde 1):

Item 3 is gone, but there are NUL bytes http://img190.imageshack.us/img190/9387/afterj.png

Este es el código relevante. El programa real es más grande, pero ejecutar solo esta parte desencadena el error.

import os 
TODO_FILE = r"E:\javi\code\Python\todo-list\src\todo.txt" 

def del_elems(f, delete): 
    """Takes an open file and either a number or a list of numbers, and deletes the 
    lines corresponding to those numbers (counting from 1).""" 
    if isinstance(delete, int): 
     delete = [delete] 
    lines = f.readlines() 
    f.truncate(0) 
    counter = 1 
    for line in lines: 
     if counter not in delete: 
      f.write(line) 
     counter += 1 

f = open(TODO_FILE, "r+") 
del_elems(f, 3) 
f.close() 

¿Podría por favor señalar dónde está el error?

Respuesta

9

Me parece que te olvidas de rebobinar tu secuencia de archivos. Después de f.truncate(0), agregue f.seek(0). De lo contrario, creo que tu próxima escritura tratará de comenzar en la posición desde la que lo dejaste, rellenando los bytes nulos en su camino hacia allí.

(Tenga en cuenta que el número de caracteres nulos en el ejemplo es igual al número de caracteres en sus líneas eliminadas más un carácter de retorno de carro y avance de línea para cada uno.)

6

Desde el Python manual:

file.truncate([size])
Truncar el tamaño del archivo. Si el argumento opcional tamaño está presente, el archivo se trunca (como máximo) a ese tamaño. El tamaño predeterminado es la posición actual. La posición actual del archivo no se cambia. Tenga en cuenta que si un tamaño específico excede el tamaño actual del archivo, el resultado depende de la plataforma: las posibilidades incluyen que el archivo permanezca inalterado, aumente hasta el tamaño especificado como si estuviera lleno de cero o aumente al tamaño especificado con contenido nuevo indefinido . Disponibilidad: Windows, muchas variantes de Unix.

Está truncando el archivo y luego escribiendo item1 y item2 en el extremo anterior del archivo. Todo lo anterior termina rellenado con 0 bytes.

f.seek(0) 

Llámalo para restablecer la posición del archivo después del truncado.

+0

Muchas gracias. Tu respuesta fue tan buena como la de Forest, pero tuve que elegir una para aceptar, así que elegí la anterior. Nada personal. – Javier

3

Tome la pista. No hagas esto

En la antigüedad (hace 30 años, en serio) "actualizábamos" los archivos con una compleja lógica de agregar/cambiar/eliminar.

Hoy en día, la vida es más simple si se escribe programas que

  1. leer el archivo en la memoria.

  2. Trabaja en los objetos en la memoria.

  3. Escriba los objetos en un archivo periódicamente y cuando el usuario quiera guardarlos.

Es más rápido y más simple. Use pickle para volcar sus objetos a un archivo. No te metas con "registros" o cualquier intento de cambiar un archivo "en su lugar".

Si realmente crees que necesitas capacidades SQL (Insertar, Actualizar, Eliminar) entonces usa SQLite. Es más confiable que lo que estás intentando hacer.

+1

Esto fue para la práctica, pero este es un punto interesante. Veré si lo cambio para comportarme como dices. – Javier

Cuestiones relacionadas