Cách kiểm tra xem thư mục / tệp / liên kết tượng trưng có tồn tại hay không bằng một lệnh trong Ruby


81

Có một cách duy nhất để phát hiện nếu một thư mục / tệp / liên kết biểu tượng / vv. thực thể (khái quát hơn) tồn tại?

Tôi cần một hàm duy nhất vì tôi cần kiểm tra một mảng đường dẫn có thể là thư mục, tệp hoặc liên kết tượng trưng. Tôi biết File.exists?"file_path"hoạt động cho các thư mục và tệp nhưng không hoạt động cho các liên kết tượng trưng (đó là File.symlink?"symlink_path").


1
Bạn đang sử dụng phiên bản Ruby nào? File tồn tại? hoạt động cho các liên kết tượng trưng cho tôi trong Ruby 1.9.2 trong OS X 10.6.6

1
Để làm rõ: đối với các liên kết tượng trưng, ​​bạn đang yêu cầu một thứ gì đó trả về truenếu liên kết tượng trưng tồn tại, bất kể liệu nó có thể được giải quyết cuối cùng thành một liên kết không phải là liên kết tượng trưng hay không. Tức là nó cũng sẽ trở lại truecho các liên kết bị hỏng. File.exists?sẽ chỉ trả về truecho một liên kết biểu tượng không bị hỏng.
Kelvin

Câu trả lời:


146

Mô-đun Tệp tiêu chuẩn có sẵn các bài kiểm tra tệp thông thường :

RUBY_VERSION # => "1.9.2"
bashrc = ENV['HOME'] + '/.bashrc'
File.exist?(bashrc) # => true
File.file?(bashrc)  # => true
File.directory?(bashrc) # => false

Bạn sẽ có thể tìm thấy những gì bạn muốn ở đó.


OP: "Cảm ơn nhưng tôi cần cả ba đúng hoặc sai"

Rõ ràng là không. Ok, hãy thử một cái gì đó như:

def file_dir_or_symlink_exists?(path_to_file)
  File.exist?(path_to_file) || File.symlink?(path_to_file)
end

file_dir_or_symlink_exists?(bashrc)                            # => true
file_dir_or_symlink_exists?('/Users')                          # => true
file_dir_or_symlink_exists?('/usr/bin/ruby')                   # => true
file_dir_or_symlink_exists?('some/bogus/path/to/a/black/hole') # => false

1
Tôi khuyên bạn không nên thực hiện nối chuỗi thô ( ENV['HOME'] + '/.bashrc') có thể không hoạt động trên nhiều nền tảng. Bạn nên sử dụng các phép nối tệp Ruby và tại sao không bắt đầu từ Rails.rootnếu bạn đang sử dụng Rails. File.exists?(Rails.root.join('db', 'my_seeds.csv')
Cyril Duchon-Doris

2
Nó được đảm bảo sẽ không hoạt động trên nhiều nền tảng vì Windows không biết về Bash và do đó, về .bashrc. Nhưng nó sẽ hoạt động trên nền tảng * nix. Việc sử dụng /không phải là vấn đề, vì IO của Ruby tự động chuyển đổi từ dấu gạch chéo lên thành dấu gạch chéo ngược trên Windows .
Tin Man

Có lẽ đó là sự thật vào tháng năm 2016, nhưng Windows chắc chắn không biết về Bash những ngày này. :-) Tôi có thể gõ bashvào Start Menu và trong cửa sổ console hiện cat ~/.bashrcra , tạo ra kết quả. ¯ \ _ (ツ) _ / ¯
Jonathan Gilbert,

Câu trả lời của Cyril rất tiếc là không hoàn toàn chính xác - nối chuỗi KHÔNG hoạt động trên windows làm cho "File.exist?" kiểm tra, như Tin Man đã chỉ ra. Tôi chỉ thêm bình luận này ở đây để xác nhận nó.
shevy

13

Tại sao không xác định chức năng của riêng bạn File.exists?(path) or File.symlink?(path)và sử dụng nó?


2
@Clawsy Tôi nghĩ bạn đang thiếu quan điểm của Gintautas: bạn là một lập trình viên - nếu chức năng bạn cần không tồn tại, bạn có thể tạo nó.
Telemachus

4
Tại sao phải phát minh lại bánh xe khi nó đã là một phần của ngôn ngữ?
the Tin Man

11
Tôi thấy nó rất hữu ích để không bị ám ảnh về chi tiết quá nhiều trong lập trình. Nếu bạn biết một cách đơn giản và dễ hiểu để giải quyết một vấn đề, hãy cứ làm. Nếu bạn tìm thấy cách tốt hơn một thời gian sau, bạn luôn có thể quay lại và sửa chữa. Việc xác định một chức năng mới là điều không cần bàn cãi trong tình huống này.
Gintautas Miliauskas

5
Tuy nhiên, chức năng này đã được tích hợp sẵn trong ngôn ngữ và rất dễ sử dụng. Sau đó, nó trở thành một trường hợp đọc để xem những gì có sẵn và thêm cuộc gọi. Viết mã để triển khai chức năng đã tồn tại chỉ vì bạn không dành thời gian để đọc RDoc đi kèm với ngôn ngữ ... chỉ là không bổ sung cho tôi. Theo logic đó, bạn có thể viết lại thư viện chuẩn.
the Tin Man

2
Sử dụng File.exist? thay vì File.exists? vì tính năng này không được dùng nữa trong ruby ​​2.2.0: ruby-doc.org/core-2.2.0/File.html#method-c-exists-3F
atw
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.