2013-05-30 34 views
6

Tôi cần một cách để lấy đường dẫn của kịch bản chạy (thư mục chứa các tập tin nguồn), nhưngVợt: Cách lấy đường dẫn của tệp đang chạy?

(current-directory) 

không bao giờ chỉ có (trong trường hợp này một ổ đĩa ngoài), nhưng thay vì để một số vị trí được xác định trước .

Tôi đã tạo tệp để thử tất cả 'đường dẫn tìm hệ thống, nhưng không có tệp nào trong số đó là tệp đang chạy! Các tài liệu Racket không giúp đỡ.

#lang web-server/insta 
(define (start request) 
    (local [{define (build-ul items) 
     `(ul ,@(map itemize items))} 
     {define (itemize item) 
     `(li ,(some-system-path->string (find-system-path item)))}] 
(response/xexpr 
`(html 
    (head (title "Directories")) 
    (body (h1 ,"Some Paths") 
     (p ,(build-ul special-paths))))))) 

(define special-paths (list 'home-dir 
         'pref-dir 
         'pref-file 
         'temp-dir 
         'init-dir 
         'init-file 
         ;'links-file ; not available for Linux 
         'addon-dir 
         'doc-dir 
         'desk-dir 
         'sys-dir 
         'exec-file 
         'run-file 
         'collects-dir 
         'orig-dir)) 

Mục đích là dành cho ứng dụng web-server cục bộ (máy chủ nhạc) sẽ sửa đổi thư mục con trong thư mục chứa tệp nguồn. Tôi sẽ mang theo ứng dụng trên một thanh USB, vì vậy nó cần để có thể xác định vị trí thư mục riêng của nó khi tôi mang nó giữa các máy và hệ điều hành với Racket được cài đặt.

Trả lời

10

Cách dễ dàng: lấy tên chạy kịch bản, làm cho nó thành một con đường hoàn thành, sau đó đi thư mục của nó:

(path-only (path->complete-path (find-system-path 'run-file))) 

Nhưng bạn có nhiều khả năng quan tâm đến không có trong tập tin đó đã được sử dụng để thực hiện điều (máy chủ web), nhưng trong tệp nguồn thực tế mà bạn đang đặt mã của mình. Tức là, bạn muốn một số tài nguyên ở gần nguồn của bạn. Một cách cũ để làm điều này là:

(require mzlib/etc) 
(this-expression-source-directory) 

Cách tốt hơn để làm điều này là để sử dụng `runtime-path', đó là một cách để xác định các nguồn lực như:

(require racket/runtime-path) 
(define-runtime-path my-picture "pic.png") 

Đây là sin tốt hơn nó cũng đăng ký đường dẫn như một cái gì đó mà kịch bản của bạn phụ thuộc vào - vì vậy nếu bạn đã đóng gói mã của bạn như là một trình cài đặt, ví dụ, Racket sẽ biết để đóng gói tập tin png đó quá.

Và cuối cùng, bạn có thể sử dụng nó để trỏ vào toàn bộ một thư mục:

(define-runtime-path HERE ".") 
... (build-path HERE "pic.png") ... 
+0

@SquareCrow: Re chỉnh sửa được đề xuất của bạn - không cần thiết, định nghĩa 'HERE' mà tôi đã đề cập ở phần cuối thực hiện chính xác điều đó mà không sử dụng' chỉ đường dẫn'. –

+0

'(đường dẫn-path-> hoàn thành đường dẫn (tìm-hệ thống-đường dẫn 'chạy tập tin)))' không hoạt động khi chạy trên DrRacket. Nó trả về đường dẫn đến DrRacket thay thế. –

1

Nếu bạn muốn đường dẫn tuyệt đối, sau đó tôi nghĩ rằng điều này sẽ làm điều đó:

(build-path (find-system-path 'orig-dir) 
      (find-system-path 'run-file)) 
+1

Điều này không hoạt động đáng tin cậy. Với ''run-file',' find-system-path' trả về đường dẫn đến 'racket' thực thi khi chạy với' vợt 'và' 'nếu mô đun được chạy dưới dạng tập lệnh. –