Jak uzyskać znak nowej linii zależny od platformy?

542

Jak uzyskać zależną od platformy nową linię w Javie? Nie mogę używać "\n"wszędzie.

Łup
źródło
Proszę rozważyć zmianę zaakceptowanych odpowiedzi. Druga odpowiedź jest bardziej odpowiednia.
Gray

Odpowiedzi:

363

Oprócz właściwości line.separator, jeśli używasz Java 1.5 lub nowszej i String.format (lub innych metod formatowania ) możesz użyć %njak w

Calendar c = ...;
String s = String.format("Duke's Birthday: %1$tm %1$te,%1$tY%n", c); 
//Note `%n` at end of line                                  ^^

String s2 = String.format("Use %%n as a platform independent newline.%n"); 
//         %% becomes %        ^^
//                                        and `%n` becomes newline   ^^

Więcej informacji można znaleźć w interfejsie API Java 1.8 dla Formatter .

Alex B.
źródło
7
Dziękuję Ci! Jestem pewien, że System.getProperty („line.separator”); ma swoje zastosowania, ale znudzi zobaczyć: "Line 1" + System.getProperty ( "line.separator") + "Linia 2"
Buttons840
43
O mój, „Linia 1” + System.getProperty („line.separator”) + „Linia 2” jest rzeczywiście jedną z najbrzydszych rzeczy, jakie kiedykolwiek widziałem. Samo zadeklarowanie stałej gdzie indziej byłoby mniej bolesne.
abahgat
4
to nie działa, przynajmniej w przypadku, gdy ciąg znaków przechodzi do instrukcji log4j. Utworzenie przykładu z nową linią na końcu potencjalnie ukrywa problem. Również String s2 jest po prostu mylący, używając '%% n'
Stealth Rabbi
6
Nie używaj tego, jeśli łańcuch może zawierać %dane wprowadzone przez użytkownika!
Konstantin Weitz
8
@KonstantinWeitz, problem String.format(s + "%n")można łatwo rozwiązać String.format("%s%n", s). Zawsze ryzykowne jest angażowanie danych wejściowych użytkownika jako treści formatu (w taki sam sposób jak eval()).
Franklin Yu,
709

Java 7 ma teraz System.lineSeparator()metodę.

StriplingWarrior
źródło
8
Byłoby bardzo miło z ich strony, gdyby zapewniły metodę przeciążoną, lineSeperator(int)która zwraca pewną liczbę separatorów linii, ponieważ często używam 2 jednocześnie.
Kon
10
@Kon Na podstawie tej odpowiedzi :String.join("", Collections.nCopies(5, System.lineSeparator()))
Samuel Harmer
4
W Javie 11:System.lineSeparator().repeat(5)
Jacob G.
4
@JobobG Przestań się cieszyć ... niektórzy z nas nadal tkwią w Javie 7.
Andrew T Finnell
@AndrewTFinnell Znalazłbym lepszą pracę <:-P Bez kontenerów -> bez Java 11, więc zostajesz po lepszą pensję, możemy się napawać :-D
Aubergine
649

Możesz użyć

System.getProperty("line.separator");

aby uzyskać separator linii

abahgat
źródło
4
Chcesz dodać System.lineSeparator()szczegóły dotyczące Java 7, więc oto ostateczna odpowiedź na to pytanie?
Gray,
43

Jeśli próbujesz zapisać nowy wiersz w pliku, możesz po prostu użyć metody newLine () BufferedWriter .

Michael Myers
źródło
31

Jest to również możliwe: String.format("%n").

Lub, String.format("%n").intern()aby zapisać niektóre bajty.

Ceving
źródło
7
To jest to samo, co odpowiedź Alexa B.
Spoike 29.04.13
16
Och, teraz to widzę. Wokół swojej odpowiedzi napisał tyle niezbadanych rzeczy. ;-)
Ceving
Próbowałem to zrobić, ale kiedy przeglądałem plik w notatniku, nie rozpoznaje on nowego wiersza.
mr5
1
@ mr5 notepadnie jest odpowiednim narzędziem do przeglądania zawartości pliku. Użyj hexdumplub od.
ceving
@ceving Jestem w środowisku Windows i spodziewałem się, że nowa linia będzie kombinacją\r\n
mr5,
22

Biblioteka commons-lang ma dostępne stałe pole o nazwie SystemUtils.LINE_SEPARATOR

leksykalny
źródło
19
Tak, zainstaluj bibliotekę strony trzeciej, aby uzyskać nową linię niezależną od platformy! #facepalm
Shervin Asgari
23
@Shervin oczywiście tego nie zrobiłbyś, ale wiele projektów, nad którymi pracowałem, używa już commons-lang i starszej wersji Javy. Jeśli więc używasz już języka wspólnego, jest to rozsądna odpowiedź. Nie czułem potrzeby, aby to podkreślać, oczywiście się myliłem.
leksykalny
2
To naprawdę dobra propozycja dla projektów, które już korzystają z tej biblioteki, dzięki!
Alexis Leclerc,
13
StringBuilder newLine=new StringBuilder();
newLine.append("abc");
newline.append(System.getProperty("line.separator"));
newline.append("def");
String output=newline.toString();

Powyższy fragment kodu będzie miał dwa ciągi znaków oddzielone nową linią niezależnie od platform.

Sathesh Balakrishnan Manohar
źródło
13

Jeśli piszesz do pliku, używając BufferedWriterinstancji, użyj newLine()metody tej instancji. Zapewnia niezależny od platformy sposób zapisu nowej linii w pliku.

Damaji kalunge
źródło
1
Ta odpowiedź jest duplikatem odpowiedzi Mike'a Meyersa .
Agi Hammerthief,
-3

Unikaj dodawania łańcuchów za pomocą String + String itp. Zamiast tego użyj StringBuilder.

String separator = System.getProperty( "line.separator" );
StringBuilder lines = new StringBuilder( line1 );
lines.append( separator );
lines.append( line2 );
lines.append( separator );
String result = lines.toString( );
Gary Davies
źródło
20
W rzeczywistości w większości przypadków to nie ma znaczenia, Jeff Atwood z Coding Horror opublikował post na blogu na temat tego rodzaju mikrooptymalizacji . Zawsze rób dane przed zgłaszaniem roszczeń, takich jak „nie rób string + string”.
Spoike
6
Powiedziałbym, że artykuł Jeffa może być trochę nieaktualny, ponieważ dotyczy on tylko czasu wykonania. Łączenie łańcuchów w Javie dotyczy nie tylko szybkości wykonywania, ale także ilości śmieci pozostawionych w pamięci do czyszczenia GC, co może powodować częstsze działanie GC. W zależności od środowiska i konfiguracji może to stanowić problem.
Lajcik,
7
Lajcik, podejrzewam, że jest to wstępna optymalizacja dla wszystkich przypadków, z wyjątkiem tych, którzy naprawdę dużo manipulują ciągiem. StringBuffer jest anty-wzorem dla drobnych wymagań konkatenacji. W wielu przypadkach wolałbym mieć czytelny separator String1 + separator + String2 niż wyżej wspomniany przykład zawierający wiele wierszy. Poza tym sugeruję przetestowanie, czy dodanie SB ma pozytywny wpływ na pamięć i GC. W wielu przypadkach chyba tak nie jest. Jeśli nie warto testować, to prawdopodobnie wstępnie optymalizuje i skupiłbym się na czytelności.
Richard Watson,
31
Wykonanie String1 + String2 jest tym samym, co robienie nowego StringBuilder (String1) .append (String2) we współczesnych kompilatorach, więc nie ma żadnej optymalizacji dla jednego konkordu łańcucha liniowego. StringBuilder jest ogólnie warty tylko pętli lub metod rekurencyjnych. Ale i tak może to być poza zakresem pierwotnego pytania.
user327961
@ user327961: prawdziwa historia. Można to łatwo udowodnić za pomocą swojego ulubionego IDE i debuggera.
Atmocreations,