Java更改系统新行字符

Java更改系统新行字符,java,windows,unix,newline,text-formatting,Java,Windows,Unix,Newline,Text Formatting,在Windows上,使用System.out.println()打印\n\r,而在Unix系统上,您将获得\n 有没有办法告诉java您想使用哪些新行字符?您可以尝试使用: String str = "\n\r"; System.out.print("yourString"+str); 但您可以使用以下方法:- System.getProperty("line.separator"); 得到 返回系统相关的行分隔符字符串。它总是回来 相同值-系统属性的初始值 行分隔符 在UNIX系统上,它返

在Windows上,使用
System.out.println()
打印
\n\r
,而在Unix系统上,您将获得
\n

有没有办法告诉java您想使用哪些新行字符?

您可以尝试使用:

String str = "\n\r";
System.out.print("yourString"+str);
但您可以使用以下方法:-

System.getProperty("line.separator");
得到

返回系统相关的行分隔符字符串。它总是回来 相同值-系统属性的初始值 行分隔符

在UNIX系统上,它返回“\n”;Microsoft Windows系统上的it 返回“\r\n”


方法
System.lineSeparator()
返回系统使用的行分隔符。从文档中指定它使用系统属性行.separator

是的,有一种方法,我刚刚尝试过

有一个系统属性
行。分隔符
。您可以使用
System.setProperty(“line.separator”,随便什么)设置它。

为了确保它确实会导致JVM使用其他分隔符,我实现了以下练习:

    PrintWriter writer = new PrintWriter(new FileWriter("c:/temp/mytest.txt"));
    writer.println("hello");
    writer.println("world");
    writer.close();
我现在在windows上运行,因此结果是14字节长的文件:

03/27/2014  10:13 AM                14 mytest.txt
               1 File(s)             14 bytes
               0 Dir(s)  409,157,980,160 bytes free
但是,当我在代码开头添加以下行时:

    System.setProperty("line.separator", "\n");
我得到了14字节长的文件:

03/27/2014  10:13 AM                14 mytest.txt
               1 File(s)             14 bytes
               0 Dir(s)  409,157,980,160 bytes free
2014年3月27日上午10:13 14 mytest.txt 1个文件14字节 0目录409157980160字节可用


我用记事本打开了这个文件,记事本不将单个
\n
识别为新行,看到的是一行文本
helloworld
,而不是两行。所以,这是可行的

如其他人所述,系统属性
line.separator
包含实际的行分隔符。奇怪的是,其他答案忽略了一个简单的结论:您可以通过在启动时更改该系统属性来覆盖该分隔符

例如,如果您在命令行中使用选项
-Dline.separator=X
运行程序,您将获得
System.out.println(…)的有趣行为
X
结束行

棘手的部分是如何在命令行中指定像
\n
\r
这样的字符。但这是特定于系统/环境的,不再是Java问题。

如中所述:

要修改现有的系统属性集,请使用 System.setProperties。此方法接受具有 已初始化为包含要设置的属性。这种方法 用新的系统属性集替换整个系统属性集 由Properties对象表示

警告:更改系统 属性具有潜在危险,应使用 自由裁量权许多系统属性在启动和关闭后不会重新读取 这些信息仅供参考。更改某些属性可能会 有意想不到的副作用

对于
System.out.println()
,将使用系统启动时存在的行分隔符。这可能是因为用于终止该行。从文件中:

private static void initPhase1() {
    lineSeparator = props.getProperty("line.separator");
}

public static String lineSeparator() {
    return lineSeparator;
}
返回系统相关的行分隔符字符串。它总是回来 相同值-系统属性的初始值 行分隔符

在UNIX系统上,它返回“\n”;Microsoft Windows系统上的it 返回“\r\n”


作为Holger,您需要在JVM启动时覆盖此属性。

检查Java 11实现:

private static void initPhase1() {
    lineSeparator = props.getProperty("line.separator");
}

public static String lineSeparator() {
    return lineSeparator;
}
因此,在运行时更改系统属性不会改变
system.lineSeparator()

因此,一些项目直接重新读取系统属性,请参见我的答案:

唯一可行的选择是在应用程序启动期间设置系统属性

对于Bash,它非常简单:
java-Dline.separator=$'\n'-jar my.jar

对于POSIX shell,最好先将该字符保存在某个变量中:

LF='
'

java -Dline.separator="$LF" -jar my.jar
如果您不确定是否调试它:

printf %s "$LF" | wc -c
1

printf %s "$LF" | od -x
0000000 000a
对于Gradle,我使用:

tasks.withType(Test).configureEach {
    systemProperty 'line.separator', '\n'
}

bootRun {
    systemProperty 'line.separator', '\n'
}

正如其他人在我之前指出的那样,因为接受的答案根本不起作用,JDK只初始化一次值,然后再也不会读取属性,只读取一个内部静态字段,所以很明显,更改属性的干净方法是在启动JVM时在命令行上设置它。到目前为止,一切顺利

我之所以要写另一个答案,是因为我想提出一种反思性的方法来更改字段,它确实适用于依赖于
System.lineSeparator()
的流和编写器。更新系统属性也没有坏处,但字段更重要

我知道反射很难看,因为Java 16+需要一个额外的JVM命令行参数才能允许反射,并且只在OpenJDK中
系统
的内部不改变的情况下才能工作。但是FWIW,这是我的解决方案-不要在家里这样做,孩子们:

import java.io.*;
导入java.lang.reflect.Field;
导入java.nio.file.Files;
/**
*“assert”需要VM参数“-ea”(启用assert)
*系统上的'Field.setAccessible'需要'--add在java 16上打开java.base/java.lang=ALL-UNNAMED'+
*/
公共类ChangeLineSeparator{
publicstaticvoidmain(字符串[]args)抛出IOException、NoSuchFieldException、IllegalAccessException{
断言System.lineSeparator().equals(“\r\n”):“默认Windows行分隔符应为CRLF”;
Field lineSeparator=System.class.getDeclaredField(“lineSeparator”);
lineSeparator.setAccessible(true);
lineSeparator.set(空,“\n”);
断言System.lineSeparator().equals(“\n”):“修改的分隔符应为LF”;
File tempFile=Files.createTempFile(null,null).toFile();
tempFile.deleteOnExit();
try(PrintWriter out=new PrintWriter(new FileWriter(tempFile))){
out.println(“foo”);
out.println(“酒吧”);
}
assert tempFile.length()==“foo\nbar\n”.length():“意外的文件大小”;
}
}
字符串换行符=“\n\r”
或任何你想要的,后跟
System.out.print(“你的字符串”+换行符)这是一项工作