Luồng zipfile Python

Vì vậy, đây là vấn đề, bạn có một luồng [đối tượng giống như tệp] trong Python và bạn muốn chuyển nội dung của luồng đó vào kho lưu trữ zip. Âm thanh như một yêu cầu phổ biến? . Tôi đề xuất một giải pháp ở đây với móc

Có hai phương pháp để ghi dữ liệu vào tệp zip trong mô-đun zipfile của Python

ZipFile.write[filename[, arcname[, compress_type]]]

ZipFile.writestr[zinfo_or_arcname, bytes[, compress_type]]

Cái đầu tiên lấy tên của một tệp, mở nó và chuyển nội dung vào kho lưu trữ theo khối 8K. Nghe có vẻ phù hợp với những gì tôi muốn ngoại trừ việc tôi có một đối tượng giống như tệp, không phải tên tệp và ZipFile. viết sẽ không chấp nhận điều đó. Tôi có thể tạo một tệp tạm thời trên đĩa và ghi dữ liệu của mình vào đó, sau đó chuyển tên của tệp thay vào đó nhưng điều đó giả sử [a] rằng tôi có quyền truy cập vào hệ thống tệp để ghi và [b] tôi không ngại lưu trữ tệp

Trước khi bạn phản đối, đối tượng ZipFile chỉ yêu cầu một đối tượng giống như tệp có hỗ trợ tìm kiếm và cho biết, nó không thực sự phải là một tệp trong hệ thống tệp nên [a] vẫn là một kịch bản hợp lệ. Mặc dù vậy, chúng tôi sẽ phải loại bỏ mọi ý tưởng thông minh về việc lưu trực tiếp tệp zip qua kết nối mạng. Xem xét kỹ hơn quá trình triển khai cho chúng ta thấy rằng một khi dữ liệu đã được nén và ghi vào kho lưu trữ, luồng sẽ được quay trở lại tiêu đề của mục lưu trữ để cập nhật thông tin về kích thước nén và không nén. Tuy nhiên, ngay cả khi bạn đang đệm đầu ra thì ít nhất bạn đang xử lý dữ liệu nén nhỏ hơn chứ không phải nguồn không nén ban đầu

Vì vậy, nếu ZipFile. ghi không hoạt động đối với các luồng, còn việc sử dụng ZipFile thì sao. writetr thay thế? . Đối với các tệp lớn hơn, điều này khó có thể thực hiện được. Tôi đã thắc mắc về việc đánh lừa phương thức này bằng một đối tượng giống như chuỗi nhưng ngay cả khi tôi có thể làm điều này thì phương thức vẫn sẽ cố gắng tạo một chuỗi thông thường với toàn bộ dữ liệu được nén, điều này sẽ không hoạt động đối với các luồng lớn

Giải pháp 1

Giải pháp đầu tiên được lấy từ một gợi ý trên StackOverflow. Ý tưởng là bọc đối tượng ZipFile và viết một phương thức mới. Rõ ràng đó sẽ là một điều tốt để những người bảo trì mô-đun xem xét nhưng nó đòi hỏi phải sao chép mã đáng kể. Nếu tôi quá phụ thuộc vào nội bộ của việc triển khai đối tượng ZipFile, tôi cũng có thể xem liệu có cách nào tốt hơn không

Giải pháp 2

Nhìn vào việc triển khai ZipFile, phương thức ghi rõ ràng rất gần với những gì tôi muốn làm. Giá như nó chấp nhận một đối tượng giống như tệp. Nhìn kỹ hơn sẽ thấy rằng nó chỉ thực hiện hai việc với tên tệp đã truyền. Nó gọi hệ điều hành. stat và sau đó, ngay sau đó, gọi open để lấy một đối tượng giống như tệp

Điều này khiến tôi suy nghĩ liệu tôi có thể đánh lừa phương thức ghi để chấp nhận một thứ khác ngoài tên của tệp hay không. Tôi đã tạo một đối tượng [mà tôi gọi là VirtualFilePath] và đặt cho nó một phương thức stat và open. Việc triển khai không quan trọng, nhưng đối tượng này về cơ bản bao bọc đối tượng giống như tệp của tôi mô phỏng hai chức năng hệ điều hành này

Thật không may, tôi không thể chuyển VirtualFilePath tới chức năng mở hệ điều hành. Tôi sẽ gặp lỗi không mong đợi một phiên bản. Điều tương tự cũng xảy ra với hệ điều hành. thống kê. Tuy nhiên, tôi có thể viết các hook để chặn các cuộc gọi này và chuyển hướng các cuộc gọi đến các phương thức của mình nếu đối số là VirtualFilePath. Về cơ bản, giải pháp của tôi trông như thế nào

import os,__builtin__

stat_pass=os.stat
open_pass=__builtin__.open

def stat_hook[path]:
 if isinstance[path,VirtualFilePath]:
  return path.stat[]
 else:
  return stat_pass[path]

def open_hook[path,*params]:
 if isinstance[path,VirtualFilePath]:
  return path.open[*params]
 else:
  return open_pass[path,*params]

class ZipHooks[object]:
 hookCount=0
 
 def __init__[self]:
  if not ZipHooks.hookCount:
   os.stat=stat_hook
   __builtin__.open=open_hook
  ZipHooks.hookCount+=1
  
 def __enter__[self]:
  return self
 
 def __exit__[self, type, value, traceback]:
  self.Unhook[]
      
 def Unhook[self]:
  ZipHooks.hookCount-=1
  if not ZipHooks.hookCount:
   os.stat=stat_pass
   __builtin__.open=open_pass

Mã này thêm các móc phát hiện đối tượng VirtualFilePath của tôi khi nó được chuyển sang open hoặc stat và chuyển hướng các cuộc gọi đó. Để quản lý các hook dễ dàng hơn, chúng ta tạo một đối tượng ZipHooks với các phương thức __enter__ và __exit__ cho phép nó được sử dụng trong câu lệnh 'with' như thế này

with ZipHooks[] as zh:
 # add stuff to an archive using VirtualFilePath here

Còn một chi tiết cuối cùng cần làm sáng tỏ. stat được cho là trả về kích thước của tệp nhưng nếu tôi không biết nó vì tôi đang đọc dữ liệu từ một luồng thì sao? . việc triển khai phương thức ghi cho thấy rằng nó không thực sự phụ thuộc vào kích thước được trả về bởi stat vì nó giám sát cả kích thước nén và không nén và nhồi lại tiêu đề khi nó theo dõi lại

Các bit thống kê duy nhất khác mà ZipFile. write quan tâm là ngày sửa đổi của tệp và chế độ [mà nó sử dụng để xác định xem tệp có thực sự là một thư mục hay không]. Vì vậy, nếu đối tượng giống như tệp của bạn hoàn toàn không giống tệp thì điều đó sẽ không quá quan trọng vì bạn chỉ phải giả mạo các trường này trong kết quả thống kê

Các tệp ZIP có thể được phát trực tuyến không?

Hạn chế. Không thể ghi hoàn toàn các tệp ZIP theo luồng . Các bit siêu dữ liệu nhỏ cho mỗi tệp thành viên, chẳng hạn như tên của nó, phải được đặt ở cuối ZIP. Để làm được điều này, stream-zip sẽ đệm siêu dữ liệu này trong bộ nhớ cho đến khi nó có thể được xuất ra.

Làm cách nào để đọc tệp ZIP trong Python?

Để làm việc trên các tệp zip bằng python, chúng tôi sẽ sử dụng mô-đun python có sẵn có tên zipfile. .
từ zipfile nhập ZipFile. ZipFile là một lớp mô-đun zipfile để đọc và ghi các tệp zip. .
với ZipFile[file_name, 'r'] dưới dạng zip. .
khóa kéo. printdir[].
khóa kéo. giải nén []

Tệp ZIP có được bao gồm trong Python không?

Chúng bao gồm các thư viện cấp thấp để nén và giải nén dữ liệu bằng các thuật toán nén cụ thể, chẳng hạn như zlib , bz2 , lzma và các thuật toán khác. Python cũng cung cấp một mô-đun cấp cao gọi là zipfile được thiết kế đặc biệt để tạo, đọc, viết, trích xuất và liệt kê nội dung của tệp ZIP.

Làm cách nào để đọc tệp ZIP trong gấu trúc Python?

Phương pháp #1. Sử dụng nén=zip trong gấu trúc. phương thức read_csv[] . Bằng cách gán đối số nén trong phương thức read_csv[] dưới dạng zip, trước tiên, gấu trúc sẽ giải nén zip và sau đó sẽ tạo khung dữ liệu từ tệp CSV có trong tệp nén.

Chủ Đề