Muszę wielokrotnie dołączać tekst do istniejącego pliku w Javie. Jak mogę to zrobić?
źródło
Muszę wielokrotnie dołączać tekst do istniejącego pliku w Javie. Jak mogę to zrobić?
Czy robisz to dla celów logowania? Jeśli tak, istnieje kilka bibliotek do tego . Dwa najbardziej popularne to Log4j i Logback .
Jeśli musisz to zrobić tylko raz, klasa Files ułatwia to:
try {
Files.write(Paths.get("myfile.txt"), "the text".getBytes(), StandardOpenOption.APPEND);
}catch (IOException e) {
//exception handling left as an exercise for the reader
}
Ostrożnie : powyższe podejście wyrzuci a, NoSuchFileException
jeśli plik jeszcze nie istnieje. Nie dołącza także automatycznie nowego wiersza (co często jest potrzebne podczas dołączania do pliku tekstowego). Odpowiedź Steve'a Chambersa dotyczy tego, jak możesz to zrobić z Files
klasą.
Jeśli jednak będziesz wielokrotnie zapisywał ten sam plik, powyższe musi wielokrotnie otwierać i zamykać plik na dysku, co jest powolną operacją. W takim przypadku buforowany program piszący jest lepszy:
try(FileWriter fw = new FileWriter("myfile.txt", true);
BufferedWriter bw = new BufferedWriter(fw);
PrintWriter out = new PrintWriter(bw))
{
out.println("the text");
//more code
out.println("more text");
//more code
} catch (IOException e) {
//exception handling left as an exercise for the reader
}
Uwagi:
FileWriter
konstruktora każe mu dołączyć się do pliku, zamiast pisać nowy plik. (Jeśli plik nie istnieje, zostanie utworzony).BufferedWriter
jest zalecane dla drogiego pisarza (takiego jak FileWriter
).PrintWriter
daje dostęp do println
składni, z której prawdopodobnie jesteś przyzwyczajony System.out
.BufferedWriter
i PrintWriter
opakowania nie są absolutnie konieczne.try {
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("myfile.txt", true)));
out.println("the text");
out.close();
} catch (IOException e) {
//exception handling left as an exercise for the reader
}
Jeśli potrzebujesz solidnej obsługi wyjątków dla starszych wersji Java, robi się to bardzo szczegółowe:
FileWriter fw = null;
BufferedWriter bw = null;
PrintWriter out = null;
try {
fw = new FileWriter("myfile.txt", true);
bw = new BufferedWriter(fw);
out = new PrintWriter(bw);
out.println("the text");
out.close();
} catch (IOException e) {
//exception handling left as an exercise for the reader
}
finally {
try {
if(out != null)
out.close();
} catch (IOException e) {
//exception handling left as an exercise for the reader
}
try {
if(bw != null)
bw.close();
} catch (IOException e) {
//exception handling left as an exercise for the reader
}
try {
if(fw != null)
fw.close();
} catch (IOException e) {
//exception handling left as an exercise for the reader
}
}
new BufferedWriter(...)
rzuca wyjątek; CzyFileWriter
będzie zamknięty? Myślę, że nie zostanie zamknięty, ponieważclose()
metoda (w normalnych warunkach) zostanie wywołana naout
obiekcie, który w tym przypadku nie zostanie zainicjowany - a więcclose()
metoda nie zostanie wywołana -> plik zostanie otwarty, ale nie będzie zamknięty. Więctry
oświadczenie IMHO powinno wyglądać taktry(FileWriter fw = new FileWriter("myFile.txt")){ Print writer = new ....//code goes here }
I powinienflush()
on napisać przed wyjściem ztry
bloku !!!StandardOpenOption.APPEND
nie utworzy go - to coś w rodzaju cichej awarii, ponieważ nie spowoduje też wyjątku. (2) Używanie.getBytes()
oznacza, że nie ma znaku powrotu przed lub po dołączonym tekście. Dodałem alternatywną odpowiedź, aby rozwiązać te problemy.Możesz użyć
fileWriter
z flagą ustawioną natrue
, do dołączania.źródło
close
powinien być umieszczony wfinally
bloku, tak jak pokazano w odpowiedzi @ etech, na wypadek gdyby został zgłoszony wyjątek między tworzeniem FileWriter a wywoływaniem close.try(FileWriter fw = new FileWriter(filename,true)){ // Whatever }catch(IOException ex){ ex.printStackTrace(); }
Czy wszystkie odpowiedzi tutaj z blokami try / catch nie powinny zawierać elementów .close () w bloku na końcu?
Przykład oznaczonej odpowiedzi:
Począwszy od wersji Java 7, można także użyć instrukcji try-with-resources . W końcu nie jest wymagany blok do zamykania zadeklarowanych zasobów, ponieważ jest on obsługiwany automatycznie, a ponadto jest mniej szczegółowy:
źródło
out
wykracza poza zakres, jest automatycznie zamykane, gdy zostanie zebrane śmieci, prawda? W twoim przykładzie zfinally
blokiem, myślę, że potrzebujesz kolejnej zagnieżdżonej metody próbowania / łapania,out.close()
jeśli dobrze pamiętam. Rozwiązanie Java 7 jest całkiem sprytne! (Nie tworzyłem żadnego oprogramowania Java od Java 6, więc nie byłem zaznajomiony z tą zmianą.)flush
metody?Edycja - od Apache Commons 2.1 poprawnym sposobem jest:
Zaadaptowałem rozwiązanie @ Kip, aby w końcu włączyć prawidłowe zamykanie pliku:źródło
Aby nieco rozwinąć odpowiedź Kipa , oto prosta metoda Java 7+, aby dodać nową linię do pliku, tworząc go, jeśli jeszcze nie istnieje :
Uwaga: Powyższe wykorzystuje
Files.write
przeciążenie, które zapisuje wiersze tekstu do pliku (tj. Podobnie jakprintln
polecenie). Aby po prostu napisać tekst na końcu (tj. Podobny doprint
polecenia), można zastosować alternatywneFiles.write
przeciążenie, przekazując tablicę bajtów (np"mytext".getBytes(StandardCharsets.UTF_8)
.).źródło
.CREATE
robi to za ciebie.Upewnij się, że strumień został poprawnie zamknięty we wszystkich scenariuszach.
To trochę niepokojące, ile z tych odpowiedzi pozostawia otwarty uchwyt pliku w przypadku błędu. Odpowiedź https://stackoverflow.com/a/15053443/2498188 dotyczy pieniędzy, ale tylko dlatego, że
BufferedWriter()
nie można rzucać. Gdyby mógł, wyjątek pozostawiłbyFileWriter
obiekt otwarty.Bardziej ogólny sposób robienia tego, który nie obchodzi, czy
BufferedWriter()
można rzucić:Edytować:
Począwszy od wersji Java 7, zalecanym sposobem jest użycie opcji „spróbuj z zasobami” i pozwolenie JVM sobie z tym poradzić:
źródło
PrintWriter.close()
nie jest zadeklarowany jakthrows IOException
w dokumentacji . Patrząc na źródło ,close()
metoda rzeczywiście nie może rzucićIOException
, ponieważ łapie ją ze strumienia i ustawia flagę. Więc jeśli pracujesz nad kodem dla następnego promu kosmicznego lub systemu pomiaru dawki promieniowania rentgenowskiego, powinieneś użyć goPrintWriter.checkError()
po próbieout.close()
. To powinno być naprawdę udokumentowane.XX.close()
powinien mieć własną próbę złapania, prawda? Na przykładout.close()
może rzucić wyjątek, w którym to przypadkubw.close()
ifw.close()
nigdy nie zostanie wywołany, ifw
to ten, który jest najbardziej krytyczny do zamknięcia.W Javie-7 można to również zrobić:
// ---------------------
źródło
java 7+
Moim skromnym zdaniem, ponieważ jestem fanem zwykłego języka Java, sugerowałbym coś, co jest kombinacją powyższych odpowiedzi. Może jestem spóźniony na przyjęcie. Oto kod:
Jeśli plik nie istnieje, tworzy go i jeśli już istnieje, dołącza sampleText do istniejącego pliku. Dzięki temu nie musisz dodawać niepotrzebnych bibliotek do ścieżki klasy.
źródło
Można to zrobić w jednym wierszu kodu. Mam nadzieję że to pomoże :)
źródło
Korzystanie z java.nio. Pliki wraz z plikiem java.nio.file. StandardOpenOption
Powoduje to utworzenie
BufferedWriter
plików, które akceptująStandardOpenOption
parametry i automatyczne opróżnianiePrintWriter
z wynikowejBufferedWriter
.PrintWriter
„sprintln()
metoda, może być następnie powołany do zapisu pliku.Te
StandardOpenOption
parametry stosowane w tym kodzie: otwiera plik do zapisu, dołącza się tylko do pliku, i tworzy plik, jeśli nie istnieje.Paths.get("path here")
można zastąpićnew File("path here").toPath()
. ICharset.forName("charset name")
może być modyfikowany w celu dostosowania do pożądanegoCharset
.źródło
Dodam tylko mały szczegół:
2. parametr (true) to funkcja (lub interfejs) o nazwie appendable ( http://docs.oracle.com/javase/7/docs/api/java/lang/Appendable.html ). Odpowiada za możliwość dodawania zawartości na końcu określonego pliku / strumienia. Ten interfejs jest implementowany od wersji Java 1.5. Każdy obiekt (tj. BufferedWriter, CharArrayWriter, CharBuffer, FileWriter, FilterWriter, LogStream, OutputStreamWriter, PipedWriter, PrintStream, PrintWriter, StringBuffer, StringBuilder, StringWriter, Writer ) może być używany do dodawania treści
Innymi słowy, możesz dodać trochę zawartości do pliku gzip lub jakiegoś procesu http
źródło
Próbka za pomocą Guava:
źródło
Spróbuj z bufferFileWriter.append, działa ze mną.
źródło
zrobi to, co zamierzasz ...
źródło
Lepiej używać try-with-resources, niż cała ta wersja wcześniejsza niż Java 7
źródło
Jeśli korzystamy z Javy 7 i nowszych, a także znamy zawartość do dodania (dołączenia) do pliku, możemy skorzystać z metody newBufferedWriter w pakiecie NIO.
Warto zwrócić uwagę na kilka punktów:
StandardCharsets
.try-with-resource
instrukcji, w której zasoby są automatycznie zamykane po próbie.Chociaż OP nie zapytał, ale na wszelki wypadek chcemy wyszukać wiersze zawierające określone słowo kluczowe, np.
confidential
Możemy użyć interfejsów API strumieni w Javie:źródło
write(String string)
jeśli ktoś spodziewa się nowego wiersza po każdym zapisanym ciągu,newLine()
należy gotrue pozwala na dołączenie danych do istniejącego pliku. Jeśli napiszemy
Zastąpi istniejący plik. Więc idź do pierwszego podejścia.
źródło
źródło
Następnie złap wyjątek IOException gdzieś powyżej.
źródło
Utwórz funkcję w dowolnym miejscu w projekcie i po prostu wywołaj tę funkcję, gdziekolwiek jej potrzebujesz.
Chłopaki, musicie pamiętać, że dzwonicie do aktywnych wątków, których nie wywołujecie asynchronicznie, a ponieważ byłoby to dobre 5 do 10 stron, aby zrobić to dobrze. Dlaczego nie poświęcić więcej czasu na swój projekt i zapomnieć o pisaniu wszystkiego, co już napisano. Prawidłowo
trzy wiersze kodu dwa naprawdę, ponieważ trzeci faktycznie dodaje tekst. : P
źródło
źródło
Możesz także spróbować tego:
źródło
Mogę zasugerować projekt Apache Commons . Ten projekt już zapewnia ramy do robienia tego, czego potrzebujesz (tj. Elastyczne filtrowanie kolekcji).
źródło
Następująca metoda pozwala dołączyć tekst do jakiegoś pliku:
Alternatywnie używając
FileUtils
:To nie jest wydajne, ale działa dobrze. Podziały linii są obsługiwane poprawnie, a nowy plik jest tworzony, jeśli jeszcze nie istniał.
źródło
Ten kod spełni twoje potrzeby:
źródło
Jeśli chcesz DODAĆ NIEKTÓRY TEKST W OKREŚLONYCH LINIACH , możesz najpierw przeczytać cały plik, dołączyć tekst gdziekolwiek chcesz, a następnie zastąpić wszystko jak w poniższym kodzie:
źródło
Moja odpowiedź:
źródło
źródło
Możesz użyć następującego kodu, aby dodać zawartość do pliku:
źródło
1.7 Podejście:
źródło