What should I see when I use the following?
System.out.println("LineSeperator1: "+System.getProperty("line.separator"));
System.out.println("LineSeperator2: "+System.lineSeparator());
I get the following back:
LineSeperator1:
LineSeperator2:
Is it empty? invisible? shouldn there be something like \r or \n?
I use windows 7, eclipse and jdk 1.8.
As you expect, the line separator contains special characters such as '\r' or '\n' that denote the end of a line. However, although they would be written in Java source code with those backslash escape sequences, they do not appear that way when printed. The purpose of a line separator is to separate lines, so, for example, the output of
System.out.println("Hello"+System.lineSeparator()+"World");
is
Hello
World
rather than, say
Hello\nWorld
You can even see this in the output of your code: the output of
System.out.println("LineSeperator1: "+System.getProperty("line.separator"));
had an extra blank line before the output of the next statement, because there was a line separator from System.getProperty("line.separator") and another from the use of println.
If you really want to see what the escaped versions of the line separators look like, you can use escapeJava from Apache Commons. For example:
import org.apache.commons.lang3.StringEscapeUtils;
public class LineSeparators {
public static void main(String[] args) {
String ls1 = StringEscapeUtils.escapeJava(System.getProperty("line.separator"));
System.out.println("LineSeperator1: "+ls1);
String ls2 = StringEscapeUtils.escapeJava(System.lineSeparator());
System.out.println("LineSeperator2: "+ls2);
}
}
On my system, this outputs
LineSeparator1: \n
LineSeparator2: \n
Note that I had to run it in the same folder as the .jar file from the Apache download, compiling and running with these commands
javac -cp commons-lang3-3.4.jar LineSeparators.java
java -cp commons-lang3-3.4.jar:. LineSeparators
Printing something afterwards will show the effect:
System.out.println("a" + System.lineSeparator() + "b");
Gives
a
b
Related
I want to print a string to a text using out.print but the \n in the string are not working.
Here is the code:
import java.io.PrintWriter;
public class LetterRevisited{
public static void main(String[] args)throws Exception
{
PrintWriter out = new PrintWriter("Test.txt");
out.println("This is the first line\n" +
"This is the second line" );
out.close();
}
}
But in the saved file no new line is created, all the lines are after each other.
Any idea how to fix this? (beside adding out.println to all lines.)
Edit: I compile and run the code with windows command prompt and open the file with notepad.
Different platforms use different line separators.
Windows use \r\n
Unix-like platforms use \n
Mac now uses \n too, but it used to use \r.
(You can see more information and variants here)
You can get your "local" line separator by using
System.getProperty("line.separator")
e.g.
out.println("Hello" + System.getProperty("line.separator") + "World");
However, it is easier to use %n in a string formatter:
out.printf("Hello%nWorld%n");
If you are targeting a particular platform, you can just use the literal.
If you are using Java 7 then you can use System.lineSeparator()..see if this helps. For older versions of Java you can use - System.getProperty("line.separator")
Example :
System.out.println(System.lineSeparator()+"This is the second line");
I have an array list defined as
List<String> cmd = new ArrayList<String>();
I am adding other strings to this List this way
cmd.add("/c");
cmd.add(command);
However if command contains " " or ' ' and a white space in between them the quotes are truncated.
How do I workaround this behaviour?
For example, if the command is
grep "Hello world" /sratch/temp
the cmd contains these Strings /c grep Hello World /scratch/temp
However if the command is grep "Hello\ world" /sratch/temp
the strings in cmd are
/c grep " Hello World " /scratch/temp
How do I program it such that the " " are not truncated?
So you want your String object to contain quotes? Try escaping them with backslash:
cmd.add("some string with \"quotes\"");
This problem is not related to ArrayList, you simple have to escape your single and double quotes when you assign them to the String object or retrieve them from user input. For more information on escape sequences in Java, have a look at this tutorial on the Oracle web site, for example.
This is actually not about Java, but about the shell you're using.
On the shell (i.e. bash, command prompt, etc.) arguments are generally broken up using spaces.
For instance,
java my.class The quick brown fox
would result in an argument list of
String[] { "The", "quick", "brown", "fox" }
However, the shell usually allows the user to make multiple spaced strings a single argument by surrounding them with double quotes - the behavior you're seeing.
For instance,
java my.class The quick "brown fox"
would result in an argument list of
String[] { "The", "quick", "brown fox" }
This means double quotes are removed from the argument list and are not literally inserted into the string.
If my assumption is correct, and you're running shell commands via your program given some sort of other command system, then you can simply surround every piece of the command in double quotes.
You can escape the quotes, just write:
"grep \"Hello world\" /sratch/temp"
You can take a look at this, for more information
EDIT
If you're parsing the user input Java will escape this special characters automatically. For example, with this code:
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String s = in.nextLine();
System.out.println("Input:"+s);
}
}
And the input: Testing "Quotes"
You will get this String:
On Windows, using System.out.println() prints out \n\r while on a Unix system you would get \n.
Is there any way to tell java what new-line characters you want to use?
As already stated by others, the system property line.separator contains the actual line separator. Strangely, the other answers missed the simple conclusion: you can override that separator by changing that system property at startup time.
E.g. if you run your program with the option -Dline.separator=X at the command line you will get the funny behavior of System.out.println(…); ending the line with an X.
The tricky part is how to specify characters like \n or \r at the command line. But that’s system/environment specific and not a Java question anymore.
Yes, there is a way and I've just tried it.
There is a system property line.separator. You can set it using System.setProperty("line.separator", whatever)
To be sure that it indeed causes JVM to use other separator I implemented the following exercise:
PrintWriter writer = new PrintWriter(new FileWriter("c:/temp/mytest.txt"));
writer.println("hello");
writer.println("world");
writer.close();
I am running on windows now, so the result was 14 bytes long file:
03/27/2014 10:13 AM 14 mytest.txt
1 File(s) 14 bytes
0 Dir(s) 409,157,980,160 bytes free
However when I added the following line to the beginning of my code:
System.setProperty("line.separator", "\n");
I got 14 bytes long file:
03/27/2014 10:13 AM 14 mytest.txt
1 File(s) 14 bytes
0 Dir(s) 409,157,980,160 bytes free
I opened this file with notepad that does not recognize single \n as a new line and saw one-line text helloworld instead of 2 separate lines. So, this works.
Because the accepted answer simply does not work, as others pointed out before me, and the JDK only initialises the value once and then never reads the property anymore, only an internal static field, it became clear that the clean way to change the property is to set it on the command line when starting the JVM. So far, so good.
The reason I am writing yet another answer is that I want to present a reflective way to change the field, which really works with streams and writers relying on System.lineSeparator(). It does not hurt to update the system property, too, but the field is more important.
I know that reflection is ugly, as of Java 16+ needs an extra JVM command line parameter in order to allow it, and only works as long as the internals of System do not change in OpenJDK. But FWIW, here is my solution - don't do this at home, kids:
import java.io.*;
import java.lang.reflect.Field;
import java.nio.file.Files;
/**
* 'assert' requires VM parameter '-ea' (enable assert)
* 'Field.setAccessible' on System requires '--add-opens java.base/java.lang=ALL-UNNAMED' on Java 16+
*/
public class ChangeLineSeparator {
public static void main(String[] args) throws IOException, NoSuchFieldException, IllegalAccessException {
assert System.lineSeparator().equals("\r\n") : "default Windows line separator should be CRLF";
Field lineSeparator = System.class.getDeclaredField("lineSeparator");
lineSeparator.setAccessible(true);
lineSeparator.set(null, "\n");
assert System.lineSeparator().equals("\n") : "modified separator should be LF";
File tempFile = Files.createTempFile(null, null).toFile();
tempFile.deleteOnExit();
try (PrintWriter out = new PrintWriter(new FileWriter(tempFile))) {
out.println("foo");
out.println("bar");
}
assert tempFile.length() == "foo\nbar\n".length() : "unexpected file size";
}
}
You may try with:
String str = "\n\r";
System.out.print("yourString"+str);
but you can instead use this:-
System.getProperty("line.separator");
to get the line seperator
Returns the system-dependent line separator string. It always returns
the same value - the initial value of the system property
line.separator.
On UNIX systems, it returns "\n"; on Microsoft Windows systems it
returns "\r\n".
As stated in the Java SE tutorial:
To modify the existing set of system properties, use
System.setProperties. This method takes a Properties object that has
been initialized to contain the properties to be set. This method
replaces the entire set of system properties with the new set
represented by the Properties object.
Warning: Changing system
properties is potentially dangerous and should be done with
discretion. Many system properties are not reread after start-up and
are there for informational purposes. Changing some properties may
have unexpected side-effects.
In the case of System.out.println(), the line separator that existed on system startup will be used. This is probably because System.lineSeparator() is used to terminate the line. From the documentation:
Returns the system-dependent line separator string. It always returns
the same value - the initial value of the system property
line.separator.
On UNIX systems, it returns "\n"; on Microsoft Windows systems it
returns "\r\n".
As Holger pointed out, you need to overwrite this property at startup of the JVM.
Windows cmd: Credit jeb at https://superuser.com/a/1519790 for a technique to specify a line-feed character in a parameter using a cmd variable. This technique can be used to specify the java line.separator.
Here's a sample javalf.cmd file
#echo off
REM define variable %\n% to be the linefeed character
(set \n=^^^
^
)
REM Start java using the value of %\n% as the line.separator System property
java -Dline.separator=%\n% %1 %2 %3 %4 %5 %6 %7 %8 %9
Here's a short test progam.
public class ReadLineSeparator {
public static void main(String... ignore) {
System.out.println(System.lineSeparator().chars()
.mapToObj(c -> "{"+Character.getName(c)+"}")
.collect(java.util.stream.Collectors.joining()));
}
}
On Windows,
java ReadLineSeparator produces
{CARRIAGE RETURN (CR)}{LINE FEED (LF)}
.\javalf.cmd ReadLineSeparator produces
{LINE FEED (LF)}
The method System.lineSeparator() returns the line separator used by the system. From the documentation it specifies that it uses the system property line.separator.
Checked Java 11 implementation:
private static void initPhase1() {
lineSeparator = props.getProperty("line.separator");
}
public static String lineSeparator() {
return lineSeparator;
}
So altering system property at runtime doesn't change System.lineSeparator().
For this reason some projects re-read system property directly, see my answer: How to avoid CRLF (Carriage Return and Line Feed) in Logback - CWE 117
The only viable option is to set system property during app startup.
For Bash it is as simple as: java -Dline.separator=$'\n' -jar my.jar.
For POSIX shell it is better to save that character in some variable first:
LF='
'
java -Dline.separator="$LF" -jar my.jar
If you are not sure debug it:
printf %s "$LF" | wc -c
1
printf %s "$LF" | od -x
0000000 000a
For Gradle I use:
tasks.withType(Test).configureEach {
systemProperty 'line.separator', '\n'
}
bootRun {
systemProperty 'line.separator', '\n'
}
I'm triying to read the text file below with a java.util.Scanner in a simple Java Program.
0001;GUAJARA-MIRIM;RO
0002;ALTO ALEGRE DOS PARECIS;RO
0003;PORTO VELHO;RO
I read the text file using the code below:
scanner = new Scanner(filerader).useDelimiter("\\;|\\n");
while (scanner.hasNext()) {
int id= scanner.nextInt();
String name = scanner.next();
String code = scanner.next();
System.out.printf(".%s.%s.%d.\n", name, code, id);
}
The results are:
.GUAJARA-MIRIM.RO.1
.
.ALTO ALEGRE DOS PARECIS.RO.2
.
.PORTO VELHO.RO.3
.
But the result of the third token of each line has an incovenient '\r' caracther at the end (ANSI code 13). I have no idea why (I used the '.' character on the formatting string to to make it clear where the '\r' is).
So,
Why there's a '\r' at the end of the third token?
How to bypass it.
It is very simple to use an workaround like code.substring(0, 2), but instead I want to understand why there's a '\r' character there.
In some file systems(specially Windows), \r\n is used a new line character. You are using \n only a delimiter so \r remain out. Add \r also in your delimiters.
To make your code little more robust, use System.lineSeparator() to get the new line characters and use the delimiters accordingly.
You are using a Windows file, which uses \r\n as line delimiters (aka Carriage Return Line Feed). Unix uses only \n (Line Feed).
To fix this, add \r to your scanner delimiter.
The reason why it happens is already given, Other way to avoid this is to use scanner.nextLine() and then split by ; .
So, I've got the following code to write to a file:
Formatter output = ....... // Creating the formatter works, writes to appropriate file.
output.format("%d\n", records.length);
for(GradeRecord gR:records)
{
output.format(gR.toString() + "\n");
}
Only problem is, the output doesn't have newline characters.
Doesn't work if I replace "\n" with "\r", either.
...I don't know why this doesn't work. Output is created and writes correctly. (I see the file created and everything is written in it, except for newline characters.)
you can use the format "%n" to output the platform specific newline using a formatter.
You want to use the correct line break string regardless of what platform it's being run on. You can do this dynamically using
String newline = System.getProperty("line.separator");
So you can later do
output.format(gR.toString() + newline);
You can try using \\n instead of \n