2010-06-12 39 views
8

Tôi đang viết một chương trình danh sách việc cần làm. Nó giữ một tập tin với một điều cần làm trên mỗi dòng, và cho phép người dùng thêm hoặc xóa các mục. Vấn đề là vì lý do nào đó, tôi kết thúc với rất nhiều byte không ở đầu tệp, mặc dù mục đó bị xóa một cách chính xác. Tôi sẽ chỉ cho bạn một vài ảnh chụp màn hình để đảm bảo rằng tôi đang làm rõ.Ghi vào một tệp bằng Python chèn các byte rỗng

Đây là tập tin trong Notepad ++ trước khi chạy chương trình:

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

Đây là tập tin sau khi xóa mục 3 (tính từ 1):

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

Đây là mã có liên quan. Chương trình thực tế lớn hơn, nhưng chỉ chạy phần này sẽ kích hoạt lỗi.

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() 

Bạn có thể vui lòng chỉ ra đâu là sai lầm?

Trả lời

9

Có vẻ như tôi đang quên tua lại luồng tệp của bạn. Sau f.truncate(0), hãy thêm f.seek(0). Nếu không, tôi nghĩ bài viết tiếp theo của bạn sẽ cố gắng bắt đầu từ vị trí mà bạn rời đi, điền vào các byte trống trên đường đến đó.

(Chú ý rằng số ký tự null trong ví dụ của bạn bằng với số ký tự trong dòng bị xóa của bạn cộng với một chiếc xe ngựa-lợi nhuận và dòng nguồn cấp dữ liệu ký tự cho mỗi một.)

6

Từ Python manual:

file.truncate([size])
Cắt bớt kích thước của tệp. Nếu tham số kích thước tùy chọn có sẵn, tệp sẽ bị cắt bớt thành (tối đa) kích thước đó. Kích thước mặc định là vị trí hiện tại. Vị trí tệp hiện tại không bị thay đổi. Lưu ý rằng nếu kích thước được chỉ định vượt quá kích thước hiện tại của tệp, kết quả phụ thuộc vào nền tảng: khả năng bao gồm tệp có thể không thay đổi, tăng kích thước được chỉ định như không được lấp đầy hoặc tăng kích thước được chỉ định với nội dung mới chưa được xác định . Tính khả dụng: Windows, nhiều biến thể Unix.

Bạn đang cắt bớt tệp và sau đó viết item1 và item2 ở cuối tệp cũ. Tất cả mọi thứ trước khi kết thúc lên đệm với 0 byte.

f.seek(0) 

Gọi điện thoại này để đặt lại vị trí tệp sau khi cắt bớt.

+0

Cảm ơn rất nhiều. Câu trả lời của bạn tốt như của Forest, nhưng tôi phải chọn một cái để chấp nhận vì vậy tôi đã chọn câu trả lời trước đó. Không có gì cá nhân. – Javier

3

Lấy gợi ý. Đừng làm thế.

Trong những ngày xa xưa (30 năm trước - nghiêm túc) chúng tôi "cập nhật" các tệp có logic thêm/thay đổi/xóa phức tạp.

Ngày nay, cuộc sống đơn giản hơn nếu bạn viết chương trình mà

  1. Đọc toàn bộ tập tin vào bộ nhớ.

  2. Làm việc trên các đối tượng trong bộ nhớ.

  3. Viết các đối tượng vào một tệp định kỳ và khi người dùng muốn lưu.

Nó nhanh hơn và đơn giản hơn. Sử dụng pickle để kết xuất đối tượng của bạn vào một tệp. Đừng gây rối với "hồ sơ" hoặc bất kỳ nỗ lực nào để thay đổi một tệp "tại chỗ".

Nếu bạn thực sự nghĩ rằng bạn cần các khả năng SQL (Chèn, Cập nhật, Xóa), sau đó sử dụng SQLite. Nó đáng tin cậy hơn những gì bạn đang cố gắng làm.

+1

Điều này là để thực hành, nhưng đây là một điểm thú vị. Tôi sẽ xem nếu tôi thay đổi nó để cư xử như bạn nói. – Javier

Các vấn đề liên quan