TCL:无法将数据写入文件

时间:2015-12-01 10:50:00

标签: tcl

我正在尝试将消息写入现有文件。 执行检查以查看某些变量值,然后相应地将消息附加到文件,但$ data值不会写入文件。 请告诉我我的代码有问题吗?

proc run_sanity {} {
    global rundir typep corner_name reflib compLib
    cd $rundir
    set filename "sanity.txt"
    set fileId [open $filename "w"]
    if {[file exists $filename]} {
        exec rm -rf $rundir/sanity.txt
    }
    exec grep operating_conditions -A 3 $compLib | grep -v default | grep -v lu | grep -v variable > $rundir/sanity.txt
    exec grep nom $compLib >> $rundir/sanity.txt
    exec grep library $compLib | grep -v slew | grep -v features >> $rundir/sanity.txt
    set driver [exec grep -c driver_waveform $compLib]
    set recovery [exec grep -c recovery $compLib]
    set removal [exec grep -c removal $compLib]
    if {$driver > 0 && $recovery > 0 && $removal > 0} {
        set data "No data found for Driver waveform, Recovery and Removal Table.\n"
        puts $fileId $data
    } else {
        set data "Driver waveform, Recovery and Removal table is present in .lib.\n"
        puts $fileId $data
    }
    close $fileId
    exec emacs $rundir/sanity.txt &
}

由于 丹

2 个答案:

答案 0 :(得分:2)

基本上,您的代码是

set fileId [open $filename "w"]      ; 1
if {[file exists $filename]} {       ; 2
    exec rm -rf $rundir/sanity.txt   ; 3
}
puts $fileId $data                   ; 4

所以,

  1. 您打开文件进行写作。

    “w”模式确保在文件不存在时创建文件 如果确实如此,则被截断。

  2. 然后检查文件是否存在。

    由于第一步,此检查始终通过 (除非你在你的文件系统上与其他人竞争 在此检查发生之前删除文件的过程。)

  3. 删除文件。

    因为这应该发生在具有POSIX语义的文件系统上 (也就是说,在某些Unix-y操作系统上),任何文件描述符都打开了 删除的文件计为该文件的实时引用,因此在文件中 条目从文件系统上的目录中删除,其数据不是 并且读取和写入这些数据恰好发生 - 它只是 在您的流程之外无法访问,因为此数据不再具有任何数据 文件系统上的名称。

    顺便说一句,这个技巧通常被Unix软件用来保存 临时数据:创建一个文件,然后立即将其删除 文件系统,同时保持打开文件描述符。

  4. 您写入该文件。写入正常,数据实际上是 存储在文件系统上。

    关闭文件后,其数据会丢失对其的最后一次实时引用 所以在那个时刻数据被删除了。

  5. 因此,您应该重新考虑管理此文件的方法。 到目前为止,在处理“sanity.txt”方面没有什么理智。 ; - )

    顺便说一句,为什么你从Tcl使用rm -rf(以及为什么-r?)而不只是file delete?那会更快一点。

答案 1 :(得分:1)

这段代码的工作原理是我在if循环中移动了fileId,处理了POSIX语义。

for(int i = 1; i <= calendar.getActualMaximum(Calendar.DAY_OF_MONTH); i++ )
        {
            calendar.set(Calendar.DAY_OF_MONTH, i);
            switch (calendar.get(Calendar.DAY_OF_WEEK))
            {
                case Calendar.MONDAY:
                    weekDays.add("Пн#"
                    + Integer.toString(calendar.get(Calendar.DAY_OF_MONTH)));
                        break;
                case Calendar.TUESDAY:
                    weekDays.add("Вт#"
                    + Integer.toString(calendar.get(Calendar.DAY_OF_MONTH)));
                        break;
                case Calendar.WEDNESDAY:
                    weekDays.add("Ср#" 
                    + Integer.toString(calendar.get(Calendar.DAY_OF_MONTH)));
                        break;
                case Calendar.THURSDAY:
                    weekDays.add("Чт#"
                    + Integer.toString(calendar.get(Calendar.DAY_OF_MONTH)));
                        break;
                case Calendar.FRIDAY:
                    weekDays.add("Пт#"
                    + Integer.toString(calendar.get(Calendar.DAY_OF_MONTH)));
                        break;
                case Calendar.SATURDAY:
                    weekDays.add("Сб#"
                    + Integer.toString(calendar.get(Calendar.DAY_OF_MONTH)));
                        break;
            }
    }