Настройка строки Java VM.разделитель

кто-нибудь нашел способ указать Java line.separator свойство при запуске виртуальной машины? Я думал о чем-то подобном:--3-->

java -Dline.separator="n"

но это не интерпретирует символ" n " как символ строки. Есть идеи?

3 ответов


попробуйте использовать java -Dline.separator=$'\n'. Это должно сработать, по крайней мере, в Баш.

вот тестовый прогон:

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 Quoting. Он расширяет символы обратной косой черты, таким образом $'\n' создает символ строки (код ASCII 10), заключенный в одинарные кавычки. См. руководство Bash, раздел 3.1.2.4 ANSI-C цитирование.


чтобы преодолеть разрыв между ответами aioobe и Божо, я бы также посоветовал не устанавливать line.separator параметр при запуске JVM, поскольку это потенциально нарушает многие фундаментальные предположения, которые код JVM и библиотеки делает о среде, в которой выполняется. Например, если библиотека, от которой вы зависите, зависит от line.separator чтобы сохранить файл конфигурации кросс-платформенным способом, вы только что нарушили это поведение. Да, это крайний случай, но это делает его еще более гнусными, когда, лет теперь возникает проблема, и теперь весь ваш код зависит от этой настройки, в то время как ваши библиотеки (правильно) предполагают, что это не так.

тем не менее, иногда эти вещи находятся вне вашего контроля, например, когда библиотека использует line.separator и не предоставляет вам возможности явно переопределить это поведение. В таком случае вы застряли, переопределяя значение или что-то более болезненное, например, повторная реализация или исправление кода вручную.

для тех, ограниченные случаи, допустимо переопределить line.separator, но мы должны следовать двум правилам:

  1. минимизировать область переопределения
  2. отменить переопределение независимо от того, что

оба эти требования хорошо обслуживается AutoCloseable и try-with-resources синтаксис, поэтому я реализовал PropertiesModifier класс, чисто обеспечивает.

/**
 * 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() Я могу четко указать разделитель строк, который я хочу использовать, не рискуя подвергать это воздействию каких-либо других частей моего приложения (обратите внимание, конечно, что это все еще не потокобезопасно).

try(PropertiesModifier pm = new PropertiesModifier("line.separator", "\n")) {
  Files.write(file, ImmutableList.of(line), Charsets.UTF_8);
}

UNIX_LINE_SEPARATOR константа где-то и использовать его вместо этого.