Tạo một tệp tạm thời cung cấp cho bạn một tệp trống có tên ngẫu nhiên bên trong O.S. (Hệ điều hành) thư mục tạm thời.
Tệp này bị xóa tự động .
Làm thế nào bạn có thể làm điều này trong Ruby?
Như thế này :
require 'tempfile' Tempfile.create { |f| f << "abc\n" }
Ở đâu f
là tệp của bạn &<<
ghi vào nó.
Điều này được tích hợp vào Ruby nên bạn không phải cài đặt bất kỳ viên ngọc nào.
Được rồi.
Đơn giản vậy thôi, nhưng bạn vẫn có thể có thắc mắc.
Thích :
- Khi nào tệp bị xóa chính xác?
- Tại sao tôi không thể đọc lại từ tệp tạm thời của mình?
- Các tệp mẫu có được đảm bảo là duy nhất không?
Tôi sẽ trả lời những câu hỏi này và một số câu hỏi khác để bạn có thể hiểu sâu hơn!
Sự khác biệt giữa Tạo mới và Tạo là gì?
Bạn sẽ nhận thấy rằng Tempfile
có hai phương pháp để tạo tệp.
Một là new
và cái còn lại là create
.
Sự khác biệt là gì?
Theo tài liệu, new
tạo một Tempfile
đối tượng (như bạn mong đợi), nhưng create
cung cấp cho bạn một File
đối tượng.
Tôi không nghĩ điều đó thực sự quan trọng, bởi vì Tempfile
ủy quyền cho File
.
Sự khác biệt thực sự là create
chấp nhận một khối.
Nhưng new
không.
Hãy thử điều này :
Tempfile.new {}
Bạn sẽ nhận được cảnh báo hữu ích này :
# warning: Tempfile.new doesn't call the given block.
Bạn có thể sử dụng một khối với create
để đảm bảo rằng tệp tạm thời của bạn sẽ bị xóa sau khi quá trình chặn kết thúc.
Điều này dẫn đến câu hỏi sau…
Khi nào thì tệp tạm thời bị xóa?
Bạn có thể kiểm soát khi nào tệp bị xóa bằng cách tự xóa nó giống như một tệp thông thường (delete
) hoặc sử dụng create
với một khối.
Tự động xóa hoạt động khi :
- Chương trình của bạn kết thúc
- Tệp của bạn được "thu dọn rác", nói cách khác, tệp sẽ bị thuật toán xóa khỏi bộ nhớ để giải phóng dung lượng
Việc muộn hơn chỉ có thể xảy ra nếu bạn không có bất kỳ tham chiếu nào đến tệp.
Giống như một biến.
Ý tôi là như vậy :
t = Tempfile.new
Khi t
vượt ra khỏi phạm vi thì tệp tạm thời có thể bị xóa.
Nếu bạn đang sử dụng Linux, một công cụ rất thú vị để xem tệp nào đang được tạo và xóa trong thời gian thực là inotify-tools.
Hãy thử lệnh này :
inotifywait /tmp -m --format "%w %e %f %T" --timefmt "%H:%m:%S"
Sau đó, chạy một số mã Ruby để tạo tệp.
Ví dụ :
ruby -rtempfile -e "def c; t = Tempfile.new('testing'); end; c; sleep 10"
Bạn sẽ thấy cái này :
/tmp/ CREATE testing20190506-11391-1wqcng0 14:51:48 /tmp/ OPEN testing20190506-11391-1wqcng0 14:51:48 /tmp/ CLOSE_WRITE,CLOSE testing20190506-11391-1wqcng0 14:51:58 /tmp/ DELETE testing20190506-11391-1wqcng0 14:51:58
Tại sao bạn không thể đọc lại từ tệp tạm thời của mình?
Nếu bạn cố gắng đọc lại từ một trong các tệp tạm thời của mình, bạn sẽ nhận được một chuỗi trống.
Ví dụ :
Tempfile.create { |f| f << "abc\n"; f.read } # ""
Tại sao vậy?
Hóa ra là File
là IO
đối tượng.
Các đối tượng IO có một con trỏ vị trí &khi bạn ghi vào tệp, vị trí này sẽ tăng lên.
Vì vậy, nếu bạn muốn đọc, bạn phải tua lại con trỏ này.
Như thế này :
Tempfile.create { |f| f << "abc\n"; f.rewind; f.read } # "abc\n"
Bạn cũng có thể cần xóa nội dung tệp của mình.
Ví dụ :
temp = Tempfile.new temp << "1" temp << "2" temp.flush
Các khuôn mẫu có thực sự độc đáo không?
Tempfile tạo một tên tệp duy nhất và đặt chế độ quyền thành 600, có nghĩa là chỉ người dùng đã tạo tệp này mới có thể đọc nó.
Nhưng có khi nào có tên trùng lặp không?
Tài liệu cho biết điều này :
“Phương pháp chọn tên tệp của Tempfile vừa an toàn theo chuỗi vừa an toàn giữa các quy trình:nó đảm bảo rằng không có chuỗi hoặc quy trình nào khác sẽ chọn cùng một tên tệp.”
Và mô tả cho new
cũng nói rằng nó có thể phát sinh lỗi nếu nó không thể tìm thấy một tên tệp duy nhất.
Cũng nên biết rằng bạn có thể đặt tiền tố cho tệp của mình.
Như thế này :
Tempfile.new("banana-").path # "/tmp/banana-20190426-25403-1cm7sjt"
Điều này làm giảm khả năng xảy ra xung đột tên.
Mở tệp Tempfile ở chế độ nhị phân
Nếu bạn đang làm việc với hình ảnh, nhạc hoặc bất kỳ thứ gì khác ngoài văn bản thuần túy, bạn có thể muốn đặt chế độ tệp của mình thành nhị phân.
Chế độ tệp nhị phân sẽ ngừng chuyển đổi cuối dòng.
Do đó, dữ liệu sẽ "thô" hơn và bạn sẽ tránh được việc phá vỡ các phần của tệp nhị phân.
Chế độ nhị phân không được bật theo mặc định :
temp = Tempfile.new temp.binmode? # false
Bạn có thể bật nó như thế này :
temp = Tempfile.new temp.binmode temp.binmode? # true
Điều này cũng hoạt động với create
phương pháp:
Tempfile.create do |f| f.binmode f << "bacon\n" end
Tóm tắt
Bạn đã tìm hiểu về các tệp tạm thời trong Ruby bằng cách sử dụng Tempfile
lớp học!
Bây giờ đến lượt bạn luyện tập.
Cảm ơn vì đã đọc 🙂