8

I was just perusing through questions, and I found System.getProperty(line.separator) used in place of \n with the author's comment that the code was "portable". Reading through various forums, I've seen two groups:

  1. People who say there's a difference between Linux's and Windows' interpretation of newline characters, and this compensates for that (with no clear evidence).
  2. People who say there's no difference by showing code and output examples, which obviously only applies to that code example and not universally.

My feeling is: it's probably non-standard OS's, like for example your company's industrial scanner's OS for example, where you'll notice a difference. When am I going to see a difference between \n and line.separator? Can you show an example, please? How did you go about discovering where the variation occurs?

Wolfpack'08
  • 3,982
  • 11
  • 46
  • 78
  • Try writing several text files, with with `\n`, one with `\r` and with `\n\r` as line endings, open this in NotePad on Windows to see the difference – MadProgrammer May 17 '14 at 02:30
  • Windows and Unix have indeed different codes for end of line. This difference will or will not manifest itself depending on the consuming application. – PM 77-1 May 17 '14 at 02:31
  • 5
    Line separators are also very important in certain network protocols. It's best to respect the standards. – Palpatim May 17 '14 at 02:47
  • Just use `\n`. When Windows users tell you that your program doesn't work, just tell them it doesn't support Windows or pre-OSX Mac and they need to switch to a different system. The Windows way is really quite silly—(just about) no one uses an old-school teletype machine anymore, and Windows end-of-line processing is more complicated for no good reason. – dfeuer May 17 '14 at 03:07
  • More practical note: be careful not to assume anything about the length of the system line separator! – dfeuer May 17 '14 at 03:13

3 Answers3

11

Here's the standard line separators by OS:

Windows: '\r\n'
Mac (OS 9-): '\r'
Mac (OS 10+): '\n'
Unix/Linux: '\n'

What that means is that if you hard code your line separators as \n, you're going to get the expected results in Linux and OS X, but Windows won't recognize the line endings properly. However, by using the more general line.separator to represent your line endings, they'll resolve to whatever the executing operating system's expected implementation of line endings may happen to be.

Sam Hanley
  • 4,707
  • 7
  • 35
  • 63
  • Oddly, the Glasgow Haskell basic text I/O library is able to handle the modern convention, `"\n"`, and the Windows convention, `"\r\n"`, but not the old `"\r"` Mac convention. – dfeuer May 17 '14 at 03:03
  • This is a really nice answer. I like the examples: citation and image. I still think it would be nice to know: where specifically are the lines drawn (because I haven't encountered any issues using `\n` in Windows with Java), and how I can find that information. – Wolfpack'08 May 17 '14 at 07:50
  • I'm happy to try to expand the answer but what do you exactly mean by "where specifically are the lines drawn"? As Keshlam stated in his answer, some high level code will properly convert `\n` to the applicable newline character for the environment, but if you think you're going to potentially want to run on multiple platforms, you're better off not relying on that behavior and just using the global line separator representation. As far as I know there's no comprehensive documentation of where they will and won't be converted for you otherwise. – Sam Hanley May 17 '14 at 14:34
8

Incorrect line endings are a frequent annoyance. For example, this is what Windows Notepad shows when writing a file with \n instead of \r\n (Windows' line.separator):

Notepad with boxes instead of line breaks

Those little boxes were supposed to be line breaks.

The other way around, when \r\n is used in place of \n (Unix' line.separator), is way worse, and breaks shell scripts and config files in weird and wonderful ways.

For example, this is what sh outputs on Debian and derived distros when trying to run a shell script that just contains ls but with \r\n line separators (it looks trashed because the carriage return causes the terminal to overwrite parts of the line):

: not foundsh: ls

There are several questions per day on StackOverflow from people being bitten by this, such as here, here and here.

Community
  • 1
  • 1
that other guy
  • 116,971
  • 11
  • 170
  • 194
  • "Run `ls` from a dos format file" doesn't mean anything. – dfeuer May 17 '14 at 02:37
  • @dfeuer I rewrote it, but what in particular did you object to? – that other guy May 17 '14 at 02:42
  • There's just not enough context to understand easily what that's supposed to mean. What you meant, apparently, was "process a file consisting of the string `"ls\r\n"` as a Bourne shell script", but instead you talked about running something from a file, which does not mean anything in particular. – dfeuer May 17 '14 at 02:51
6

If you get this wrong, you WILL mess up your ability to exchange data with other applications. You need to understand when you can get away with assuming that Java will help you... and when you can't.

Linux applications normally use only the linefeed character (\n) as its line break. Windows applications use the combination of carriage return followed by line feed (\n\r).

If you're using high-level Java I/O routines -- if you're going through Readers and Writers which process characters, rather than low-level Streams and especially byte streams -- the libraries will translate \n (which java, by convention, uses internally as its newline) into the platform-appropriate representation. If you're using lower-level functions, you have to be aware of that distinction and Do The Right Thing yourself.

keshlam
  • 7,931
  • 2
  • 19
  • 33