shutil.move deletes the file on windows when new name contains a colon (and an extension)
尝试:
1 2 3 4 5 6 7 | import os, shutil wd = os.path.abspath(os.path.curdir) newfile = os.path.join(wd, 'testfile') print str(newfile) with open(newfile, 'w') as f: f.write('Hello bugs') shutil.move(newfile, os.path.join(wd, 'testfile:.txt')) # note the : |
现在检查目录 - 删除newfile并且不创建其他文件 - 进程以退出代码0结束。
如果您发出以下情况:
1 | shutil.move(newfile, os.path.join(wd, 'testfile:')) # note no extension |
它吹嘘:
1 2 3 4 5 6 7 8 9 10 | Traceback (most recent call last): File"C:/Users/MrD/.PyCharm40/config/scratches/scratch_3", line 9, in <module> shutil.move(newfile, os.path.join(wd, 'testfile:')) File"C:\_\Python27\lib\shutil.py", line 302, in move copy2(src, real_dst) File"C:\_\Python27\lib\shutil.py", line 130, in copy2 copyfile(src, dst) File"C:\_\Python27\lib\shutil.py", line 83, in copyfile with open(dst, 'wb') as fdst: IOError: [Errno 22] invalid mode ('wb') or filename: 'C:\\Users\\MrD\\.PyCharm40\\config\\scratches\\testfile:' |
正如它应该。
这是一个错误吗?
上下文:当我发出非法文件名时,我正在测试代码的行为(
我不知道为什么在我的情况下文件是在运行脚本时创建的。
这不是Python的
看来冒号用于将常规文件的路径与隐藏文件分开。例如,如果在命令行中写入:
1 | > notepad foo |
然后关闭记事本,然后写
1 | > notepad foo.txt:bar |
记事本将打开隐藏文件。继续写下一些内容,保存并关闭。键入
1 | > notepad foo.txt:bar.txt |
您刚刚编辑的文件将会出现,您的更改将保持不变。
那么你的Python代码会发生什么?
src is copied (usingshutil.copy2() ) todst and then removed.
因此,当您将
下面的代码片段可能会更清楚(我已将其保存为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | import os, shutil with open('test', 'w') as f: f.write('Hello bugs') shutil.copy2('test', 'test:foo.txt') with open('test:foo.txt') as f: print(f.read()) print 'test: exists? ', os.path.exists('test') print 'test:foo.txt exists? ', os.path.exists('test:foo.txt') print os.listdir('.') print('removing...') os.remove('test') print 'test: exists? ', os.path.exists('test') print 'test:foo.txt exists? ', os.path.exists('test:foo.txt') print os.listdir('.') |
这打印:
1 2 3 4 5 6 7 8 | Hello bugs test exists? True test:foo.txt exists? True ['demo.py', 'test'] removing... test: exists? False test:foo.txt exists? False ['demo.py'] |
这表明我们可以创建一个普通文件,写入它,然后将该普通文件复制到其隐藏流中,打开并正常读取,结果如预期。然后我们看到
最后,您无法创建没有名称的隐藏数据流,因此
因此,Python代码实际上在Windows下运行 -"备用数据流"就是这样一个鲜为人知的"功能",这种行为令人惊讶。