Muszę wielokrotnie dołączać tekst do istniejącego pliku w Javie. Jak mogę to zrobić?
Muszę wielokrotnie dołączać tekst do istniejącego pliku w Javie. Jak mogę to zrobić?
Odpowiedzi:
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; Czy FileWriter
będzie zamknięty? Myślę, że nie zostanie zamknięty, ponieważ close()
metoda (w normalnych warunkach) zostanie wywołana na out
obiekcie, który w tym przypadku nie zostanie zainicjowany - a więc close()
metoda nie zostanie wywołana -> plik zostanie otwarty, ale nie będzie zamknięty. Więc try
oświadczenie IMHO powinno wyglądać tak try(FileWriter fw = new FileWriter("myFile.txt")){ Print writer = new ....//code goes here }
I powinien flush()
on napisać przed wyjściem z try
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ą na true
, do dołączania.
try
{
String filename= "MyFile.txt";
FileWriter fw = new FileWriter(filename,true); //the true will append the new data
fw.write("add a line\n");//appends the string to the file
fw.close();
}
catch(IOException ioe)
{
System.err.println("IOException: " + ioe.getMessage());
}
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:
PrintWriter out = null;
try {
out = new PrintWriter(new BufferedWriter(new FileWriter("writePath", true)));
out.println("the text");
} catch (IOException e) {
System.err.println(e);
} finally {
if (out != null) {
out.close();
}
}
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:
try(PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("writePath", true)))) {
out.println("the text");
} catch (IOException e) {
System.err.println(e);
}
out
wykracza poza zakres, jest automatycznie zamykane, gdy zostanie zebrane śmieci, prawda? W twoim przykładzie z finally
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:
FileUtils.writeStringToFile(file, "String to append", true);
Zaadaptowałem rozwiązanie @ Kip, aby w końcu włączyć prawidłowe zamykanie pliku:
public static void appendToFile(String targetFile, String s) throws IOException {
appendToFile(new File(targetFile), s);
}
public static void appendToFile(File targetFile, String s) throws IOException {
PrintWriter out = null;
try {
out = new PrintWriter(new BufferedWriter(new FileWriter(targetFile, true)));
out.println(s);
} finally {
if (out != null) {
out.close();
}
}
}
Aby nieco rozwinąć odpowiedź Kipa , oto prosta metoda Java 7+, aby dodać nową linię do pliku, tworząc go, jeśli jeszcze nie istnieje :
try {
final Path path = Paths.get("path/to/filename.txt");
Files.write(path, Arrays.asList("New line to append"), StandardCharsets.UTF_8,
Files.exists(path) ? StandardOpenOption.APPEND : StandardOpenOption.CREATE);
} catch (final IOException ioe) {
// Add your own exception handling...
}
Uwaga: Powyższe wykorzystuje Files.write
przeciążenie, które zapisuje wiersze tekstu do pliku (tj. Podobnie jak println
polecenie). Aby po prostu napisać tekst na końcu (tj. Podobny do print
polecenia), można zastosować alternatywne Files.write
przeciążenie, przekazując tablicę bajtów (np "mytext".getBytes(StandardCharsets.UTF_8)
.).
.CREATE
robi to za ciebie.
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łby FileWriter
obiekt otwarty.
Bardziej ogólny sposób robienia tego, który nie obchodzi, czy BufferedWriter()
można rzucić:
PrintWriter out = null;
BufferedWriter bw = null;
FileWriter fw = null;
try{
fw = new FileWriter("outfilename", true);
bw = new BufferedWriter(fw);
out = new PrintWriter(bw);
out.println("the text");
}
catch( IOException e ){
// File writing/opening failed at some stage.
}
finally{
try{
if( out != null ){
out.close(); // Will close bw and fw too
}
else if( bw != null ){
bw.close(); // Will close fw too
}
else if( fw != null ){
fw.close();
}
else{
// Oh boy did it fail hard! :3
}
}
catch( IOException e ){
// Closing the file writers failed for some obscure reason
}
}
Począwszy od wersji Java 7, zalecanym sposobem jest użycie opcji „spróbuj z zasobami” i pozwolenie JVM sobie z tym poradzić:
try( FileWriter fw = new FileWriter("outfilename", true);
BufferedWriter bw = new BufferedWriter(fw);
PrintWriter out = new PrintWriter(bw)){
out.println("the text");
}
catch( IOException e ){
// File writing/opening failed at some stage.
}
PrintWriter.close()
nie jest zadeklarowany jak throws 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ć go PrintWriter.checkError()
po próbie out.close()
. To powinno być naprawdę udokumentowane.
XX.close()
powinien mieć własną próbę złapania, prawda? Na przykład out.close()
może rzucić wyjątek, w którym to przypadku bw.close()
i fw.close()
nigdy nie zostanie wywołany, i fw
to ten, który jest najbardziej krytyczny do zamknięcia.
W Javie-7 można to również zrobić:
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
// ---------------------
Path filePath = Paths.get("someFile.txt");
if (!Files.exists(filePath)) {
Files.createFile(filePath);
}
Files.write(filePath, "Text to be added".getBytes(), StandardOpenOption.APPEND);
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:
String sampleText = "test" + System.getProperty("line.separator");
Files.write(Paths.get(filePath), sampleText.getBytes(StandardCharsets.UTF_8),
StandardOpenOption.CREATE, StandardOpenOption.APPEND);
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.
Można to zrobić w jednym wierszu kodu. Mam nadzieję że to pomoże :)
Files.write(Paths.get(fileName), msg.getBytes(), StandardOpenOption.APPEND);
Korzystanie z java.nio. Pliki wraz z plikiem java.nio.file. StandardOpenOption
PrintWriter out = null;
BufferedWriter bufWriter;
try{
bufWriter =
Files.newBufferedWriter(
Paths.get("log.txt"),
Charset.forName("UTF8"),
StandardOpenOption.WRITE,
StandardOpenOption.APPEND,
StandardOpenOption.CREATE);
out = new PrintWriter(bufWriter, true);
}catch(IOException e){
//Oh, no! Failed to create PrintWriter
}
//After successful creation of PrintWriter
out.println("Text to be appended");
//After done writing, remember to close!
out.close();
Powoduje to utworzenie BufferedWriter
plików, które akceptują StandardOpenOption
parametry i automatyczne opróżnianie PrintWriter
z wynikowej BufferedWriter
. PrintWriter
„s println()
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()
. I Charset.forName("charset name")
może być modyfikowany w celu dostosowania do pożądanego Charset
.
Dodam tylko mały szczegół:
new FileWriter("outfilename", true)
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
Próbka za pomocą Guava:
File to = new File("C:/test/test.csv");
for (int i = 0; i < 42; i++) {
CharSequence from = "some string" + i + "\n";
Files.append(from, to, Charsets.UTF_8);
}
Spróbuj z bufferFileWriter.append, działa ze mną.
FileWriter fileWriter;
try {
fileWriter = new FileWriter(file,true);
BufferedWriter bufferFileWriter = new BufferedWriter(fileWriter);
bufferFileWriter.append(obj.toJSONString());
bufferFileWriter.newLine();
bufferFileWriter.close();
} catch (IOException ex) {
Logger.getLogger(JsonTest.class.getName()).log(Level.SEVERE, null, ex);
}
String str;
String path = "C:/Users/...the path..../iin.txt"; // you can input also..i created this way :P
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
PrintWriter pw = new PrintWriter(new FileWriter(path, true));
try
{
while(true)
{
System.out.println("Enter the text : ");
str = br.readLine();
if(str.equalsIgnoreCase("exit"))
break;
else
pw.println(str);
}
}
catch (Exception e)
{
//oh noes!
}
finally
{
pw.close();
}
zrobi to, co zamierzasz ...
Lepiej używać try-with-resources, niż cała ta wersja wcześniejsza niż Java 7
static void appendStringToFile(Path file, String s) throws IOException {
try (BufferedWriter out = Files.newBufferedWriter(file, StandardCharsets.UTF_8, StandardOpenOption.APPEND)) {
out.append(s);
out.newLine();
}
}
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.
public static void main(String[] args) {
Path FILE_PATH = Paths.get("C:/temp", "temp.txt");
String text = "\n Welcome to Java 8";
//Writing to the file temp.txt
try (BufferedWriter writer = Files.newBufferedWriter(FILE_PATH, StandardCharsets.UTF_8, StandardOpenOption.APPEND)) {
writer.write(text);
} catch (IOException e) {
e.printStackTrace();
}
}
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:
//Reading from the file the first line which contains word "confidential"
try {
Stream<String> lines = Files.lines(FILE_PATH);
Optional<String> containsJava = lines.filter(l->l.contains("confidential")).findFirst();
if(containsJava.isPresent()){
System.out.println(containsJava.get());
}
} catch (IOException e) {
e.printStackTrace();
}
write(String string)
jeśli ktoś spodziewa się nowego wiersza po każdym zapisanym ciągu, newLine()
należy go
FileOutputStream fos = new FileOutputStream("File_Name", true);
fos.write(data);
true pozwala na dołączenie danych do istniejącego pliku. Jeśli napiszemy
FileOutputStream fos = new FileOutputStream("File_Name");
Zastąpi istniejący plik. Więc idź do pierwszego podejścia.
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
public class Writer {
public static void main(String args[]){
doWrite("output.txt","Content to be appended to file");
}
public static void doWrite(String filePath,String contentToBeAppended){
try(
FileWriter fw = new FileWriter(filePath, true);
BufferedWriter bw = new BufferedWriter(fw);
PrintWriter out = new PrintWriter(bw)
)
{
out.println(contentToBeAppended);
}
catch( IOException e ){
// File writing/opening failed at some stage.
}
}
}
FileOutputStream stream = new FileOutputStream(path, true);
try {
stream.write(
string.getBytes("UTF-8") // Choose your encoding.
);
} finally {
stream.close();
}
Następnie złap wyjątek IOException gdzieś powyżej.
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
//Adding a static modifier would make this accessible anywhere in your app
public Logger getLogger()
{
return java.util.logging.Logger.getLogger("MyLogFileName");
}
//call the method anywhere and append what you want to log
//Logger class will take care of putting timestamps for you
//plus the are ansychronously done so more of the
//processing power will go into your application
//from inside a function body in the same class ...{...
getLogger().log(Level.INFO,"the text you want to append");
...}...
/*********log file resides in server root log files********/
trzy wiersze kodu dwa naprawdę, ponieważ trzeci faktycznie dodaje tekst. : P
Biblioteka
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
Kod
public void append()
{
try
{
String path = "D:/sample.txt";
File file = new File(path);
FileWriter fileWriter = new FileWriter(file,true);
BufferedWriter bufferFileWriter = new BufferedWriter(fileWriter);
fileWriter.append("Sample text in the file to append");
bufferFileWriter.close();
System.out.println("User Registration Completed");
}catch(Exception ex)
{
System.out.println(ex);
}
}
Możesz także spróbować tego:
JFileChooser c= new JFileChooser();
c.showOpenDialog(c);
File write_file = c.getSelectedFile();
String Content = "Writing into file"; //what u would like to append to the file
try
{
RandomAccessFile raf = new RandomAccessFile(write_file, "rw");
long length = raf.length();
//System.out.println(length);
raf.setLength(length + 1); //+ (integer value) for spacing
raf.seek(raf.length());
raf.writeBytes(Content);
raf.close();
}
catch (Exception e) {
//any exception handling method of ur choice
}
Mogę zasugerować projekt Apache Commons . Ten projekt już zapewnia ramy do robienia tego, czego potrzebujesz (tj. Elastyczne filtrowanie kolekcji).
Następująca metoda pozwala dołączyć tekst do jakiegoś pliku:
private void appendToFile(String filePath, String text)
{
PrintWriter fileWriter = null;
try
{
fileWriter = new PrintWriter(new BufferedWriter(new FileWriter(
filePath, true)));
fileWriter.println(text);
} catch (IOException ioException)
{
ioException.printStackTrace();
} finally
{
if (fileWriter != null)
{
fileWriter.close();
}
}
}
Alternatywnie używając FileUtils
:
public static void appendToFile(String filePath, String text) throws IOException
{
File file = new File(filePath);
if(!file.exists())
{
file.createNewFile();
}
String fileContents = FileUtils.readFileToString(file);
if(file.length() != 0)
{
fileContents = fileContents.concat(System.lineSeparator());
}
fileContents = fileContents.concat(text);
FileUtils.writeStringToFile(file, fileContents);
}
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ł.
Ten kod spełni twoje potrzeby:
FileWriter fw=new FileWriter("C:\\file.json",true);
fw.write("ssssss");
fw.close();
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:
public static void addDatatoFile(String data1, String data2){
String fullPath = "/home/user/dir/file.csv";
File dir = new File(fullPath);
List<String> l = new LinkedList<String>();
try (BufferedReader br = new BufferedReader(new FileReader(dir))) {
String line;
int count = 0;
while ((line = br.readLine()) != null) {
if(count == 1){
//add data at the end of second line
line += data1;
}else if(count == 2){
//add other data at the end of third line
line += data2;
}
l.add(line);
count++;
}
br.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
createFileFromList(l, dir);
}
public static void createFileFromList(List<String> list, File f){
PrintWriter writer;
try {
writer = new PrintWriter(f, "UTF-8");
for (String d : list) {
writer.println(d.toString());
}
writer.close();
} catch (FileNotFoundException | UnsupportedEncodingException e) {
e.printStackTrace();
}
}
Moja odpowiedź:
JFileChooser chooser= new JFileChooser();
chooser.showOpenDialog(chooser);
File file = chooser.getSelectedFile();
String Content = "What you want to append to file";
try
{
RandomAccessFile random = new RandomAccessFile(file, "rw");
long length = random.length();
random.setLength(length + 1);
random.seek(random.length());
random.writeBytes(Content);
random.close();
}
catch (Exception exception) {
//exception handling
}
/**********************************************************************
* it will write content to a specified file
*
* @param keyString
* @throws IOException
*********************************************************************/
public static void writeToFile(String keyString,String textFilePAth) throws IOException {
// For output to file
File a = new File(textFilePAth);
if (!a.exists()) {
a.createNewFile();
}
FileWriter fw = new FileWriter(a.getAbsoluteFile(), true);
BufferedWriter bw = new BufferedWriter(fw);
bw.append(keyString);
bw.newLine();
bw.close();
}// end of writeToFile()
Możesz użyć następującego kodu, aby dodać zawartość do pliku:
String fileName="/home/shriram/Desktop/Images/"+"test.txt";
FileWriter fw=new FileWriter(fileName,true);
fw.write("here will be you content to insert or append in file");
fw.close();
FileWriter fw1=new FileWriter(fileName,true);
fw1.write("another content will be here to be append in the same file");
fw1.close();
1.7 Podejście:
void appendToFile(String filePath, String content) throws IOException{
Path path = Paths.get(filePath);
try (BufferedWriter writer =
Files.newBufferedWriter(path,
StandardOpenOption.APPEND)) {
writer.newLine();
writer.append(content);
}
/*
//Alternative:
try (BufferedWriter bWriter =
Files.newBufferedWriter(path,
StandardOpenOption.WRITE, StandardOpenOption.APPEND);
PrintWriter pWriter = new PrintWriter(bWriter)
) {
pWriter.println();//to have println() style instead of newLine();
pWriter.append(content);//Also, bWriter.append(content);
}*/
}