2011-12-15 26 views
7

Tôi nhận được một đối tượng ngâm (một danh sách với một vài mảng có nhiều mảng) được tạo trên Windows và dường như được lưu vào một tệp được tải dưới dạng văn bản chứ không phải ở chế độ nhị phân (ví dụ: với open(filename, 'w') thay vì open(filename, 'wb')). Kết quả là bây giờ tôi không thể giải nén nó (thậm chí không phải trên Windows) vì nó bị nhiễm với \r ký tự (và có thể nhiều hơn)? Khiếu nại chính làPickle Python: sửa các ký tự trước khi tải

ImportError: No module named multiarray 

được cho là vì nó đang tìm kiếm numpy.core.multiarray\r, tất nhiên là không tồn tại. Đơn giản chỉ cần loại bỏ các \r nhân vật đã không làm các trick (thử cả sed -e 's/\r//g' và trong python s = file.read().replace('\r', ''), nhưng cả hai phá vỡ các tập tin và tạo ra một cPickle.UnpicklingError sau này)

Vấn đề là tôi thực sự cần phải lấy dữ liệu ra khỏi các đối tượng. Bất kỳ ý tưởng làm thế nào để sửa chữa các tập tin?

Edit: Theo yêu cầu, vài trăm byte đầu tiên của tập tin của tôi, Octal:

\x80\x02]q\x01(}q\x02(U\r\ntotal_timeq\x03G?\x90\x15r\xc9(s\x00U\rreaction_timeq\x04NU\x0ejump_directionq\x05cnumpy.core.multiarray\r\nscalar\r\nq\x06cnumpy\r\ndtype\r\nq\x07U\x02f8K\x00K\x01\x87Rq\x08(K\x03U\x01<NNNJ\xff\xff\xff\xffJ\xff\xff\xff\xffK\x00tbU\x08\x025\x9d\x13\xfc#\xc8?\x86Rq\tU\x14normalised_directionq\r\nh\x06h\x08U\x08\xf0\xf9,\x0eA\x18\xf8?\x86Rq\x0bU\rjump_distanceq\x0ch\x06h\x08U\x08\x13\x14\xea&\xb0\x9b\[email protected]\x86Rq\rU\x04jumpq\x0ecnumpy.core.multiarray\r\n_reconstruct\r\nq\x0fcnumpy\r\nndarray\r\nq\x10K\x00\x85U\x01b\x87Rq\x11(K\x01K\x02\x85h\x08\x89U\x10\x87\x16\xdaEG\xf4\xf3?\x06`OC\xe7"\[email protected]\x0emovement_speedq\x12h\x06h\x08U\x08\\p\xf5[2\xc2\xef?\x86Rq\x13U\x0ctrial_lengthq\[email protected]\t\x98\x87\xf8\x1a\xb4\xbaU\tconditionq\x15U\x0bhigh_mentalq\x16U\x07subjectq\x17K\x02U\x12movement_directionq\x18h\x06h\x08U\x08\xde\x06\xcf\x1c50\xfd?\x86Rq\x19U\x08positionq\x1ah\x0fh\x10K\x00\x85U\x01b\x87Rq\x1b(K\x01K\x02\x85h\x08\x89U\x10K\xb7\xb4\x07q=\x1e\xc0\xf2\xc2YI\xb7U&\xc0tbU\x04typeq\x1ch\x0eU\x08movementq\x1dh\x0fh\x10K\x00\x85U\x01b\x87Rq\x1e(K\x01K\x02\x85h\x08\x89U\x10\xad8\x9c9\x10\xb5\xee\xbf\xffa\xa2hWR\xcf?tbu}q\x1f(h\[email protected]\t\xba\xbc\xb8\xad\xc8\x14h\x04G?\xd9\x99%]\xadV\x00h\x05h\x06h\x08U\x08\xe3X\xa9=\xc1\xb1\xeb?\x86Rq h\r\nh\x06h\x08U\x08\x88\xf7\xb9\xc1\t\xd6\xff?\x86Rq!h\x0ch\x06h\x08U\x08v\x7f\xeb\x11\xea5\[email protected]\x86Rq"h\x0eh\x0fh\x10K\x00\x85U\x01b\x87Rq#(K\x01K\x02\x85h\x08\x89U\x10\xcd\xd9\x92\x9a\x94=\[email protected]]C\xaf\xef\xeb\xef\[email protected]\x12h\x06h\x08U\x08-\x9c&\x185\xfd\xef?\x86Rq$h\[email protected]\r\xb8W\xb2`V\xach\x15h\x16h\x17K\x02h\x18h\x06h\x08U\x08\x8e\x87\xd1\xc2 

Bạn cũng có thể tải về whole file (22k).

Trả lời

11

Giả sử rằng các tập tin được tạo ra với các giao thức mặc định = phương pháp 0 ASCII-tương thích, bạn sẽ có thể tải nó bất cứ nơi nào bằng cách sử dụng open('pickled_file', 'rU') nghĩa là các dòng mới phổ dụng.

Nếu cách này không hiệu quả, hãy hiển thị cho chúng tôi vài trăm byte đầu tiên: print repr(open('pickled_file', 'rb').read(200)) và dán kết quả vào bản chỉnh sửa câu hỏi của bạn.

Cập nhật sau khi nội dung tập tin đã được công bố:

tập tin của bạn bắt đầu với '\x80\x02'; nó đã được bán với giao thức 2, mới nhất/tốt nhất. Giao thức 1 và 2 là các giao thức nhị phân. Tệp của bạn được viết bằng chế độ văn bản trên Windows. Điều này đã dẫn đến mỗi '\n' được chuyển đổi thành '\r\n' theo thời gian chạy C. Tệp sẽ được mở ở chế độ nhị phân như sau:

with open('result.pickle', 'wb') as f: # b for binary 
    pickle.dump(obj, f, pickle.HIGHEST_PROTOCOL) 

with open('result.pickle', 'rb') as f: # b for binary 
    obj = pickle.load(f) 

Tài liệu là here. Mã này sẽ hoạt động ổn định trên cả Windows và các hệ thống không phải Windows.

Bạn có thể khôi phục ảnh gốc bằng cách đọc tệp ở chế độ nhị phân và sau đó đảo ngược thiệt hại bằng cách thay thế tất cả các lần xuất hiện của '\r\n' bởi '\n'. Lưu ý: Quy trình khôi phục này là cần thiết cho dù bạn đang cố đọc nó trên Windows hay không.

+0

+1 để biết thông tin về phiên bản giao thức tẩy. @Nkosinathi, bạn nên đánh dấu đây là câu trả lời. –

0

Bạn không thể - trên Windows - chỉ cần mở tệp ở chế độ văn bản, giống như cách viết, đọc và sau đó ghi nó ra tệp khác được mở đúng cách ở chế độ nhị phân?

0

Bạn đã thử bỏ ghim ở chế độ văn bản chưa? Đó là,

x = pickle.load(open(filename, 'r')) 

(Trên Windows, tất nhiên.)

+0

Không, dường như Windows không thích kết thúc dòng riêng ...? –

5

Các dòng mới trong Windows không chỉ là '\r', là CRLF hoặc '\r\n'.

Tặng thử file.read().replace('\r\n', '\n'). Trước đây bạn đã xóa các khoản trả về vận chuyển có thể không thực sự là một phần của dòng mới.

+0

+1: bạn đã hiểu! Điều này làm việc trên Mac OS X. Có thực sự cô lập '\ r' ký tự trong tập tin dưa chuột. – EOL

+0

Rực rỡ, đã giải quyết nó! Cảm ơn một triệu, bạn đã tiết kiệm được 4 giờ công việc rất tốn kém (và không, chắc chắn không phải vì tiền lương của tôi ... ;-) –

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