0

私はファイルを開いた tcl プロシージャを持っています。書き込み用に存在しない場合は作成します。現在、デバッグのためにいくつかの puts ステートメントをログに記録しています。このプロセスの最後で、ファイルを閉じます。しかし、途中で別の proc を呼び出しており、その proc で開いているファイルにも何かを書き込む必要があります。だから私はこのようなことをしたい:

proc ::myproc {args} { 
  set fp [open "C:\\log.txt" w+];
  puts $fp "Checkpoint 1";
  set retVal [::myprocII];
  puts $fp "Checkpoint 2";
  close $fp;
  return 1;
}

proc ::myprocII {} {
  set fp [open "C:\\log.txt" w+];
  puts $fp "Checkpoint 3";
  close $fp;
  return 1;
}

myprocII で同じファイルを開いてデータをログに記録し、それを閉じると、エラーまたは例外の原因になるのではないでしょうか。そして、myprocII でファイルを閉じた後でも、呼び出し元のプロシージャ myproc にデータを記録しています。これをテストしようとしましたが、バッチファイルから実行しているため、エラーが何であるかを理解する前にウィンドウが閉じます。

したがって、これが正しいかどうか、または異なる手順から同じログ ファイルにデータを追加し続けるにはどうすればよいかを知りたかったのです。

4

1 に答える 1

4

いくつかのオプションがあります:

  • 1 つのファイル記述子を使用し、プログラムの最後でそれを閉じます。

    proc log {data} {
        global logfd
        if {![info exists logfd] || $logfd == ""} {
            set logfd [open {C:\log.txt} w]
        }
        puts $logfd $data
    }
    
    # before you exit, close it:
    catch {close $::logfd}
    

    Tcl は、プログラムの終了時に終了時にファイルを閉じる必要があります。

  • 書き込みごとにファイルを開く/閉じる。追加モードでのみ有用

    proc log {data} {
        set fd [open {C:\log.txt} a]
        catch {
            puts $fd $data
        } res opt
        close $fd
        return -options $opt $res
    }
    

    これは最もパフォーマンスの高いソリューションではありませんが、クリーンです。

  • いくつかのハックを使用する

    rename open _open
    rename close _close
    proc open {path args} {
       global sharedfd
       if {$path eq {C:\log.txt}} {
           if {[info exists sharedfd] && [dict exists $sharedfd fd]} {
               dict incr sharedfd refcount
               return [dict get $sharedfd fd]
           } else {
               set fd [_open $path {*}$args]
               dict set sharedfd fd $fd
               dict set sharedfd refcount 1
               return $fd
           }
       }
       return [_open $path {*}$args]
    }
    
    proc close {fd args} {
        global sharedfd
        if {[info exists sharedfd] 
                && [dict exists $sharedfd fd] 
                && [dict get $sharedfd fd] eq $fd} {
            dict incr sharedfd refcount -1
            if {[dict get $sharedfd refcount] <= 0} {
               _close $fd
               unset sharedfd
            }
            return
        }
        _close $fd {*}$args
    }
    

    既に開いている場合は同じ fd を返し、C:\log.txtrefcounter を保持し、refcount が 0 の場合はチャネルを閉じます
    。これはハックであることに注意してください。標準コマンドを変更しないでください。

于 2013-10-25T16:24:55.000 に答える