'Colon in file names in Python

As we all know, filenames in Windows can't contain colons. However, I ran into a problem, that can be reproduced with the following sample code:

import os
os.chdir('./temp')
names = ['a', 'b', 'word1: word2', 'c: file', 'd: file']

for name in names:
    with open(name, 'w') as f:
        f.write('foo')

This script creates three files in the ./temp directory: a, b (with 'foo') and word1 (empty). It also creates a file named file in D:\, which is removable storage. It doesn't create anything in C:\, which requires administrator rights to write in; however, it does create a file in the current working directory.

I don't understand three things:

  1. Why aren't any exceptions thrown (with other forbidden characters, I get IOError)?
  2. Why is the word1 file empty?
  3. Why a file is created in the current working directory?


Solution 1:[1]

Windows NTFS supports file "stream". You basically append data to a file, outside of the file, and can't be viewed normally. When you created the file "word1:word2", the hidden stream "word2" is attached to "word1". If you copied the file word1 to another NTFS machine, the word2 data would come with you

Go here http://technet.microsoft.com/en-us/sysinternals/bb897440.aspx and download the streams program. Running it will show you that word2 is a stream attached to word1

This page also talks about streams: http://www.forensicfocus.com/dissecting-ntfs-hidden-streams

To really prove this easily, you can use Notepad but you need to use the .txt extension:

 file=open('word1.txt:word2.txt','w')
 file.write('Testing streams')
 file.close()

Now, using the cmd program, change directories to where you created the files. Type the following:

 c:\tmp> notepad word1.txt

You will see an empty file. Now, try this:

 c:\tmp> notepad word1.txt:word2.txt

You should see the text Testing streams.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Anders