[sapug] linux/win difference

Tim Wegener twegener at fastmail.fm
Wed Feb 1 12:25:08 CET 2012

Hi Garry,

On 01/02/12 18:34, Garry Trethewey wrote:
> I've got this irritating problem that I can't imagine can exist. I'm 
> doing a small conversion to a gpx file that is produced by a Windows 
> program & gets used by another Windows program.

This is almost certainly because you are opening the file in text mode 
(the default).

I.e. open('blah.txt') is equivalent to open('blah.txt', 'r') and open 
('blah.txt', 'rt')
Compare with open('blah.txt', 'rb') which is binary mode, and 
open('blah.txt', 'rU') which is universal newline mode.

On Windows, text mode converts all new lines (cr-lf) to new lines (lf), 
whereas binary mode leaves things exactly as they are.
On Linux it always behaves like binary mode, i.e. no magic.
With universal newline mode all the various platform new line combos are 
normalised to '\n'.
The file object attribute somefile.newlines gives the newline character 
encountered (or a tuple of distinct line endings encountered if there 
are different types present).

See also 'pydoc file' and 'pydoc open'.

Here's some examples from the REPL to make it clear:
Python 2.7.2 (default, Jun 12 2011, 15:08:59) [MSC v.1500 32 bit 
(Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
 >>> import os
 >>> os.chdir('c:\\Python27')
 >>> open('NEWS.txt', 'r').read(60)
"Python News\n+++++++++++\n\n\nWhat's New in Python 2.7.2?\n======"
 >>> open('NEWS.txt', 'rt').read(60)
"Python News\n+++++++++++\n\n\nWhat's New in Python 2.7.2?\n======"
 >>> open('NEWS.txt', 'rb').read(60)
"Python News\r\n+++++++++++\r\n\r\n\r\nWhat's New in Python 2.7.2?\r\n="
 >>> f = open('NEWS.txt', 'rU')
 >>> f.read(60)
"Python News\n+++++++++++\n\n\nWhat's New in Python 2.7.2?\n======"
 >>> f.newlines

(YMMV with Python 3, it seems to be universal newline modes mode by 
default according to the docs, but I haven't tried it out. See 'pydoc3 
open' for further details if necessary.)

The official documentation for this could do with some work. You asked a 
good question.

For your situation you probably want to do something like:

old_html = '</trkseg>\n<trkseg>'
new_html = old_html + ' \n\n<trk>\n<trkseg>'
input_file = open(filename, 'rU')
updated_html = input_file.read().replace(old_html, new_html)

Then depending on your needs, either:

# Use line ending style from current platform.
updated_html = updated_html.replace('\n', os.linesep)


# Force Windows line ending style.
updated_html = updated_html.replace('\n', '\r\n')

BTW, the above example was performed running Python for Windows under Wine:

$ wine msiexec /i ~/Downloads/python-2.7.2.msi
$ wine .wine/drive_c/Python27/python.exe


> this code:-
> LF_CR = chr(13) + chr(10)
> oldStrWin = '</trkseg>' + LF_CR + '<trkseg>'
> newStrWin = '</trkseg>' + LF_CR + '</trk>' + LF_CR *2 + '<trk>' + 
> LF_CR + '<trkseg>'
> outStr = inStr.replace(oldStrWin, newStrWin)
> - works as I'd expect in linux, but in Win Vista or Win 7 it doesn't.
> So result in win vista & 7 :-
> </trkseg>
> <trkseg>
> Results in linux :-
> </trkseg>
> </trk>
> <trk>
> <trkseg>

More information about the sapug mailing list