假设有一个test.txt
包含字符串的文件'test'
。
现在,考虑以下Python代码:
f = open('test', 'r+')
f.read()
f.truncate(0)
f.write('passed')
f.flush();
现在,我希望现在test.txt
包含它'passed'
,但是另外还有一些奇怪的符号!
更新:截断后刷新无济于事。
这是因为截断不会更改流的位置。
当你read()
的文件,你移动位置到结束。因此,连续的write
s将从该位置写入文件。
但是,当您调用时
flush()
,似乎不仅尝试将缓冲区写入文件,而且还会进行一些错误检查并修复当前文件位置。在
Flush()
之后调用时
truncate(0)
,将不写入任何内容(缓冲区为空),然后检查文件大小并将该位置放置在第一个适用的位置(即
0
)。
更新
Python的文件功能不仅是与C标准库等效物的包装,而且了解C函数有助于更准确地了解正在发生的事情。
在ftruncate手册页中:
调用ftruncate()不会修改seek指针的值。
从笨拙的手册页:
如果流指向输入了最新操作的输入流或更新流,则在可搜索且尚未到达文件末尾的情况下刷新该流。刷新输入流将丢弃所有缓冲的输入,并调整文件指针,以使下一个输入操作在最后一次读取后访问该字节。
这意味着如果您放置flush
在truncate
它之前没有效果。我检查了,是这样。
但是为了flush
追求truncate
:
如果流指向未输入最新操作的输出流或更新流,则fflush()会将该流的任何未写入数据写入文件,并标记基础文件的st_ctime和st_mtime字段进行更新。
手册页在解释未输入最后操作的输出流时没有提及查找指针。(这是我们的最后一个操作是truncate
)
更新2
我在python源代码中找到了一些东西: Python-3.2.2\Modules\_io\fileio.c:837
#ifdef HAVE_FTRUNCATE
static PyObject *
fileio_truncate(fileio *self, PyObject *args)
{
PyObject *posobj = NULL; /* the new size wanted by the user */
#ifndef MS_WINDOWS
Py_off_t pos;
#endif
...
#ifdef MS_WINDOWS
/* MS _chsize doesn't work if newsize doesn't fit in 32 bits,
so don't even try using it. */
{
PyObject *oldposobj, *tempposobj;
HANDLE hFile;
////// THIS LINE //////////////////////////////////////////////////////////////
/* we save the file pointer position */
oldposobj = portable_lseek(fd, NULL, 1);
if (oldposobj == NULL) {
Py_DECREF(posobj);
return NULL;
}
/* we then move to the truncation position */
...
/* Truncate. Note that this may grow the file! */
...
////// AND THIS LINE //////////////////////////////////////////////////////////
/* we restore the file pointer position in any case */
tempposobj = portable_lseek(fd, oldposobj, 0);
Py_DECREF(oldposobj);
if (tempposobj == NULL) {
Py_DECREF(posobj);
return NULL;
}
Py_DECREF(tempposobj);
}
#else
...
#endif /* HAVE_FTRUNCATE */
查看我指示的两行(///// This Line /////
)。如果您的平台是Windows,则它将保存位置并在截断后将其返回。
令我惊讶的是,flush
Python
3.2.2函数中的大多数函数什么都不做,或者根本没有调用fflush
C函数。3.2.2截短部分也没有记录。但是,我确实在Python
2.7.2源中发现了一些有趣的东西。首先,我Python-2.7.2\Objects\fileobject.c:812
在truncate
实现中发现了这一点:
/* Get current file position. If the file happens to be open for
* update and the last operation was an input operation, C doesn't
* define what the later fflush() will do, but we promise truncate()
* won't change the current position (and fflush() *does* change it
* then at least on Windows). The easiest thing is to capture
* current pos now and seek back to it at the end.
*/
因此,总而言之,我认为这是完全依赖平台的事情。我检查了适用于Windows x64的默认Python 3.2.2,并获得了与您相同的结果。不知道在*
nixes上会发生什么。
问题内容: 这是来自Zed Shaw的Python教程的练习16。在这种情况下,我很难理解该功能的确切作用。因此逻辑是我们打开一个文件,然后…将其缩短?为了什么?这里到底发生了什么? 问题答案: 保持可疑是对的。 首先,这样做: 截断文件的大小。如果存在可选的 size 参数,则文件将被截断为(最多)该大小。尺寸默认为当前位置… 与Zed的描述不太相同- 仅在当前位置是文件的开头时才“清空文件”,
本文向大家介绍Python删除windows垃圾文件的方法,包括了Python删除windows垃圾文件的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了Python删除windows垃圾文件的方法。分享给大家供大家参考。具体如下: 希望本文所述对大家的Python程序设计有所帮助。
问题内容: 和Python和有什么不一样? 我尝试环顾四周,但没有在这些线上找到具体问题。如果已经回答,则链接就足够了。 问题答案: 0和1是退出代码。 意味着干净出口,没有任何错误/问题 表示存在一些问题/错误/问题,这就是程序退出的原因。 这不是特定于Python的,非常普遍。非零退出代码被视为异常退出,有时,错误代码指示问题所在。错误代码为零表示成功退出。 这对于其他程序,shell,调用方
问题内容: 我正在寻找一种每天自动在MySQL中自动清理表的方法。不使用cron可以做到吗?最佳解决方案将是触发器,但是任何解决方案均适用。 问题答案: 一种选择是MySQL的调度程序: 如何启用事件计划程序
我目前在Spring批处理作业中有以下处理: FlatFileItemReader读取CSV文件 我不想写入新文件,但我想更新处理过程中读取的同一文件。 我的问题是,在Spring中有没有一种典型的方法可以使用FlatFileItemReader,然后在运行时在处理器中每行更新相同的文件? 谢谢你的帮助。
问题内容: 我正在尝试编写python脚本来删除X天之前的文件夹中的所有文件。这是我到目前为止所拥有的: 运行脚本时,我得到: , 并给出文件名。我究竟做错了什么? 问题答案: 返回裸文件名列表。它们没有完整的路径,因此您需要将其与包含目录的路径合并。您在删除文件时执行此操作,但在文件删除时(或在执行任一操作时)则不执行此操作。 最简单的解决方案是在循环的顶部执行一次: 现在是文件的完整路径,您可