在 dm 脚本中将文本附加到文件的最佳方法

Best way to append text to file in dm-script

向文件追加行的最佳方法是什么?


目前我正在使用以下脚本:

/**
 * Append the `line` to the file given at the `path`.
 * 
 * @param path 
 *     The absolute or relative path to the file with 
 *     extension
 * @param line
 *     The line to append
 * @param [max_lines=10000]
 *     The maximum number of lines to allow  for a file 
 *     to prevent an infinite loop
 */
void append(string path, string line, number max_lines){
    number f = OpenFileForReadingAndWriting(path);

    // go through file until the end is reached to set the 
    // internal pointer to this position
    number line_counter = 0;
    string file_content = "";
    string file_line;
    while(ReadFileLine(f, file_line) && line_counter < max_lines){
        line_counter++;
        // file_content += file_line;
    }
    
    // result("file content: \n" + file_content + "{EOF}");
    
    // append the line
    WriteFile(f, line + "\n");
    CloseFile(f);
}
void append(string path, string line){
    append(path, line, 10000);
}

string path = "path/to/file.txt";
append(path, "Appended line");

对我来说,读取整个文件内容只是附加一行似乎有点奇怪。如果文件很大,这可能很慢1。所以我想对此有更好的解决方案。有人知道这个解决方案吗?


一些背景

我的应用程序是用 python 中的 but executed in Digital Micrograph. My python application is logging its steps. Sometimes I am executing 编写的。在那里我无法看到发生了什么。由于存在错误,我需要一些东西来找出发生了什么。因此,我也想将日志记录添加到 dm-script

这也解释了为什么我每次都想打开和关闭文件。这需要更多时间,但我不关心调试时的执行速度。像往常一样,普通版本的日志将被删除或关闭。但另一方面,我正在交替执行 dm-scriptpython,所以我必须防止 python 阻塞文件 dm-script,反之亦然。


1如后台所写,我对速度不是很感兴趣。所以目前的剧本对我来说已经足够了。我仍然对如何更好地做到这一点很感兴趣,只是为了学习和好奇。

处理 DM 脚本(二进制或文本)中的任何文件的最佳方法是使用流对象。以下示例应该可以回答您的问题:

void writeText()
{
 string path
 if ( !SaveAsDialog( "Save text as" , path , path ) ) return
 number fileID = CreateFileForWriting( path )
 object fStream = NewStreamFromFileReference( fileID , 1 )   // 1 for auto-close file when out of scope

 // Write some text
 number encoding = 0 // 0 = system default

 fStream.StreamWriteAsText( encoding , "The quick brown dog jumps over the lazy fox" )
 // Replace last 'fox' by 'dog'

 fStream.StreamSetPos( 1 , -3 )        // 3 bytes before current position
 fStream.StreamWriteAsText( encoding, "dog" )
 
 // Replace first 'dog' by 'fox'
 fStream.StreamSetPos( 0 , 16 )        // 16 bytes after start
 fStream.StreamWriteAsText( encoding, "fox" )

 // Append at end
 fStream.StreamSetPos( 2 , 0 )        // end position (0 bytes from end)
 fStream.StreamWriteAsText( encoding, "." )
}

writeText()