首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >设置Java VM line.separator

设置Java VM line.separator
EN

Stack Overflow用户
提问于 2010-09-14 20:48:35
回答 3查看 14.7K关注 0票数 15

有没有人找到了在VM启动时指定Java line.separator属性的方法?我在想这样的事情:

代码语言:javascript
复制
java -Dline.separator="\n"

但这不会将"\n“解释为换行符。有什么想法吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-09-14 21:00:22

尝试使用java -Dline.separator=$'\n'。这应该会起作用,至少在bash中是这样的。

下面是一个测试运行:

代码语言:javascript
复制
aioobe@r60:~/tmp$ cat Test.java 
public class Test {
    public static void main(String[] args) {
        System.out.println("\"" + System.getProperty("line.separator") + "\"");
    }
}
aioobe@r60:~/tmp$ javac Test.java && java -Dline.separator=$'\n' Test
"
"
aioobe@r60:~/tmp$ 

注意:

表达式$''使用Bash功能ANSI-C引用。它扩展了反斜杠转义字符,因此$'\n'生成一个换行符(ASCII码10),用单引号括起来。参见Bash手册,3.1.2.4 ANSI-C Quoting一节。

票数 16
EN

Stack Overflow用户

发布于 2014-05-14 08:25:58

为了弥补aioobe和Bozho的回答之间的差距,我还建议不要在JVM启动时设置line.separator参数,因为这可能会破坏JVM和库代码对运行环境的许多基本假设。例如,如果您依赖于line.separator以跨平台的方式存储配置文件,那么您就打破了这种行为。是的,这是一种边缘情况,但当几年后出现问题,现在所有的代码都依赖于这种调整,而你的库(正确地)假设它不存在时,它就变得更加危险了。

也就是说,有时这些事情是您无法控制的,比如当一个库依赖于line.separator,并且不提供显式覆盖该行为的方法时。在这种情况下,你不得不重写值,或者一些更痛苦的事情,比如手动重新实现或修补代码。

对于那些有限的情况,覆盖line.separator是可以接受的,但我们必须遵循两条规则:

无论是什么,覆盖都会最小化覆盖的范围

AutoCloseabletry-with-resources语法很好地满足了这两个要求,所以我实现了一个PropertiesModifier类,它干净利落地提供了这两个要求。

代码语言:javascript
复制
/**
 * Class which enables temporary modifications to the System properties,
 * via an AutoCloseable.  Wrap the behavior that needs your modification
 * in a try-with-resources block in order to have your properties
 * apply only to code within that block.  Generally, alternatives
 * such as explicitly passing in the value you need, rather than pulling
 * it from System.getProperties(), should be preferred to using this class.
 */
public class PropertiesModifier  implements AutoCloseable {
  private final String original;

  public PropertiesModifier(String key, String value) {
    this(ImmutableMap.of(key, value));
  }

  public PropertiesModifier(Map<String, String> map) {
    StringWriter sw = new StringWriter();
    try {
      System.getProperties().store(sw, "");
    } catch (IOException e) {
      throw new AssertionError("Impossible with StringWriter", e);
    }
    original = sw.toString();
    for(Map.Entry<String, String> e : map.entrySet()) {
      System.setProperty(e.getKey(), e.getValue());
    }
  }

  @Override
  public void close() {
    Properties set = new Properties();
    try {
      set.load(new StringReader(original));
    } catch (IOException e) {
      throw new AssertionError("Impossible with StringWriter", e);
    }
    System.setProperties(set);
  }
}

我的用例是使用Files.write(),这是一个非常方便的方法,只是它显式地依赖于line.separator。通过包装对Files.write()的调用,我可以清楚地指定我想要使用的行分隔符,而不会冒着暴露给应用程序的任何其他部分的风险(当然,请注意,这仍然不是线程安全的)。

代码语言:javascript
复制
try(PropertiesModifier pm = new PropertiesModifier("line.separator", "\n")) {
  Files.write(file, ImmutableList.of(line), Charsets.UTF_8);
}
票数 5
EN

Stack Overflow用户

发布于 2010-09-14 20:57:50

如果我是你,我就不会那么做。行分隔符是特定于平台的,并且应该保持不变。如果你想只写windows或者linux的文件,可以在某个地方定义一个UNIX_LINE_SEPARATOR常量并使用它。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3708991

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档