Tcl在用';打开的文件中查找和写入;a和x2B';

Tcl在用';打开的文件中查找和写入;a和x2B';,tcl,Tcl,我需要将一些日志存储在一个可以随每次执行而增长的文件中。一种合乎逻辑的方法是在打开时使用A+选项,因为使用w+将截断文件。但是,使用a+选项(Tcl 8.4),我无法在文件中的任何位置写入搜索工作正常。我可以使用tell验证指针是否已移动。但是输出总是在文件的末尾进行 有没有办法解决这个问题?也就是说,能够在任何地方查找和写入,并且能够在打开时保留旧文件。使用r+打开-它以读取模式打开(因此不会翻转文件),但也允许写入 有关更多信息,请参阅open的文档:我已验证使用a+选项是否允许我读取/写入

我需要将一些日志存储在一个可以随每次执行而增长的文件中。一种合乎逻辑的方法是在打开时使用
A+
选项,因为使用
w+
将截断文件。但是,使用
a+
选项(Tcl 8.4),我无法在文件中的任何位置写入<代码>搜索工作正常。我可以使用
tell
验证指针是否已移动。但是输出总是在文件的末尾进行


有没有办法解决这个问题?也就是说,能够在任何地方查找和写入,并且能够在打开时保留旧文件。

使用
r+
打开-它以读取模式打开(因此不会翻转文件),但也允许写入


有关更多信息,请参阅
open
的文档:

我已验证使用
a+
选项是否允许我读取/写入文件中的任何位置。但是,通过在文件的中间(或开始)写入,我覆盖了那里的数据,而不是插入。以下代码说明了这一点:

#!/usr/bin/env tclsh

# Open the file, with truncation
set f [open foo w]
puts $f "one"
puts $f "two"
close $f

# Open again, with a+ ==> read/write/append
set f [open foo a+]
puts $f "three" ;# This goes to the end of the file
seek $f 4       ;# Seek to the beginning of the word "two"
puts $f "2.0"   ;# Overwrite the word "two"
close $f

# Open and verify the contents
set f [open foo r]
puts [read $f]
close $f
输出:

one
2.0
three

如果您想插入文件的中间,您可能需要查看<代码> > FieluTyl <代码>包,其中包含“代码>::FielUTIL::INSERTINTINFIOF命令。

< P>在TCL 8.5中,更改了UNIX上的TCL行为,以便将<代码> OyAppEng/<代码>标志传递给<代码>打开()/<代码>系统调用。这使得操作系统总是将数据附加到文件中,并在将FD传递给子进程时被继承;对于日志来说,这正是正确的选择。(在8.4及之前的版本中,以及在Windows上的所有版本中,该行为都是在Tcl的文件通道实现中模拟的,它将在内部
seek()
直到
write()之前结束)
;当有多个进程登录到同一文件时,这显然会受到竞争条件的潜在问题的影响,当FD被传递到子进程时,这肯定是不安全的。)您可以使用
chan truncate
(8.5中新增)管理打开文件的截断,它在
a+
打开的文件上运行良好

如果不希望seek结束行为,则不应使用
a+
(或
a
)。尝试
r+
或以下组合:

set f [open $filename {RDWR CREAT}]

为了进行比较,
a+
选项现在与标志
RDWR create APPEND
完全相同,并且并非所有较长标志的组合都可以用短格式标志说明符来描述。如果您没有指定
APPEND
,您需要自己执行
seek$f end
(如果您要附加到日志中,请注意多个进程的问题;此时需要
APPEND
,并且很难正确模拟任何其他方式).

请注意,
open
支持另一种告诉它访问模式的方式,例如,您可以这样调用它:
open$fname{RDWR CREAT}
,以获得您想要的。但是真正的
r+
是@slebtman建议的方法。我在Mac上用Tcl 8.4和8.5进行了尝试。你在运行什么操作系统?Linux 2.6.18-274.el5#1 SMP周五7月22日04:43:29美国东部夏令时2011年x86 _64x86 _64x86 _64GNU/LinuxYeah,在Windows上的8.4和8.5以及LinuxCan上的8.5上都适用于我你可以在tcl上运行
info patchlevel
,看看它说了些什么吗?它也适用于Red Hat:Linux autobot 2.6.9-89.0.11.ELsmp#1 SMP周一8月31日11:01:10 EDT 2009 i686 i686 i386 i386 GNU/Linux和tcl 8.4.19我刚刚找到了(文档非常不完整)
FILE\u APPEND\u DATA
标记到
CreateFile
可能允许在Windows上正确追加数据。或许不是;从它的文档中找出Win32 API中的某些东西实际上做了什么,这真的是相当棘手的…