2016-08-26 3 views
4

Я писал программу Racket, которая должна была записывать информацию, но я хотел сохранить журналы в файле. Моя первая попытка состояла в том, чтобы использовать «with-logging-to-port» и использовать «open-output-file» для создания выходного порта.Racket: Запись в файл

#lang racket 
(require racket/logging) 
(define (identity/log x) 
    (log-info "returning ~a" x) x) 

(with-logging-to-port (open-output-file "testing.txt") 
    (λ() (identity/log 4)) 'info) 

Однако, когда я открываю файл, он пуст! Кроме того, я не могу запускать это более одного раза, потому что «open-output-file» дает мне ошибку, что файл уже существует.

ответ

1

Открыть файл с флагом 'append. Например:

(open-output-file "testing.txt" #:exists 'append) 
3

Я уверен, причина в том, что вы не закрываете файл должным образом. Это должно работать:

(let ((out (open-output-file "testing.txt" 
          ; just to not get an error on consecutive runs 
          #:exists 'append))) 
    (with-logging-to-port out 
    (λ() (identity/log 4)) 'info) 
    (close-output-port out)) 

Вместо того, чтобы делать домашнее хозяйство вы можете использовать call-with-output-file

(call-with-output-file "testing.txt" 
    (λ (out) 
    (with-logging-to-port out 
     (λ() (identity/log 4)) 'info)) 
    #:exists 'append) 
1

Если информация журнала находится в списке строк, скажем, LST, можно также использовать следующие функции:

(display-lines-to-file lst "mylog.txt" 
    #:exists 'append) 

См: https://docs.racket-lang.org/reference/Filesystem.html?q=lines-file#%28def._%28%28lib._racket%2Ffile..rkt%29._display-lines-to-file%29%29

(require racket/file) 
(display-lines-to-file lst  path     
    [ #:separator separator     
     #:mode mode-flag     
     #:exists exists-flag])  →  void? 
2

Я даю вам источник мой журнал Func в:

(define my_logger (make-logger 'my-log)) 

(define logger_thread #f) 

(define (log fmt . content) 
    (log-message my_logger 'info "" (string-append (format-time (now)) " " (apply format (cons fmt content))))) 

(define (start-logger log_path) 
    (let ([r (make-log-receiver my_logger 'info)] 
     [riqi (format-riqi (now))]) 
    (set! logger_thread 
      (thread 
      (lambda() 
      (let ([log_dir (build-path log_path (substring riqi 0 4))]) 
       (when (not (directory-exists? log_dir)) 
       (make-directory log_dir)) 
       (with-output-to-file 
        (build-path log_path (substring riqi 0 4) riqi) #:exists 'append 
        (lambda() 
        (let loop() 
         (match (sync r) 
         [(vector l m v v1) 
          (printf "~a\n" v) 
          (flush-output)]) 
         (loop)))))))))) 

(define (restart-logger) 
    (kill-thread logger_thread) 
    (start-logger)) 

(define (launch-log-daemon log_path) 
    (start-logger log_path) 
    (thread 
    (lambda() 
    (let loop() 
     (sync 
     (alarm-evt (+ (current-inexact-milliseconds) (* 1000 60 60)))) 
     (when (= 0 (date-hour (seconds->date (current-seconds)))) 
     (restart-logger)) 
     (loop))))) 

В начале приложения, вы должны запустить:

(launch-log-daemon log_path) 

, то вы можете использовать его как это:

(log "~a:~a" "some1" "some2") 

Я использую дату как каталог и имя файла журнала,

он автоматически запустит новый файл журнала при изменении даты.

foramt-riqi и формат времени здесь:

(define (format-riqi the_date) 
    (format "~a~a~a" 
      (date-year the_date) 
      (~a (date-month the_date) #:min-width 2 #:pad-string "0" #:align 'right) 
      (~a (number->string (date-day the_date)) #:min-width 2 #:pad-string "0" #:align 'right))) 

(define (format-time the_date) 
    (format "~a:~a:~a" 
      (~a (date-hour the_date) #:min-width 2 #:pad-string "0" #:align 'right) 
      (~a (date-minute the_date) #:min-width 2 #:pad-string "0" #:align 'right) 
      (~a (date-second the_date) #:min-width 2 #:pad-string "0" #:align 'right))) 
+0

Что такое 'формат-time' и' формат-riqi'? –

+1

извините, пожалуйста, простите меня, долго не проверять сообщение, format-riqi и format-time - моя функция chinglish, означает формат даты и времени. – simmone