Jak zapisać ciąg do pliku tekstowego za pomocą Java?


699

W Javie mam tekst z pola tekstowego w zmiennej String zwanej „tekstem”.

Jak mogę zapisać zawartość zmiennej „tekst” do pliku?

Odpowiedzi:


727

Jeśli po prostu wyprowadzasz tekst, a nie dane binarne, działają:

PrintWriter out = new PrintWriter("filename.txt");

Następnie napisz do niego swój ciąg znaków, tak jak w przypadku dowolnego strumienia wyjściowego:

out.println(text);

Jak zawsze będziesz potrzebować obsługi wyjątków. Pamiętaj, aby zadzwonić out.close()po zakończeniu pisania.

Jeśli używasz Java 7 lub nowszej wersji, możesz użyć „instrukcji try-with-resources ”, która automatycznie zamknie twoją PrintStreamwersję po zakończeniu (tj. Wyjściu z bloku) w następujący sposób:

try (PrintWriter out = new PrintWriter("filename.txt")) {
    out.println(text);
}

Nadal będziesz musiał wyraźnie rzucić, java.io.FileNotFoundExceptionjak poprzednio.


4
@Justin, możesz również przekazać ścieżkę bezwzględną (np. „/Tmp/filename.txt”) do konstruktora FileOutputStream, aby zapisać plik w dowolnym miejscu
Jonik

7
Przy okazji, można to uprościć za pomocą konstruktorów wygody, które PrintStream ma od 1.5. To wystarczy: PrintStream out = new PrintStream ("filename.txt");
Jonik

10
Chcesz w pewnym momencie zamknąć ten plik ...? codecodex.com/wiki/ASCII_file_save#Java
JStrahl

2
Chcesz użyć try {} catch () {} wreszcie {}, gdzie w końcu {} zamykasz plik, jeśli nie jest on pusty.
Benas,

23
W java8 możesz wypróbować (PrintStream ps = nowy PrintStream („nazwa pliku”)) {ps.println (out); } to zajmie się zamknięciem dla ciebie
Anton Chikin

245

Apache Commons IO zawiera kilka świetnych metod, w szczególności FileUtils zawiera następującą metodę:

static void writeStringToFile(File file, String data) 

który pozwala pisać tekst do pliku w jednym wywołaniu metody:

FileUtils.writeStringToFile(new File("test.txt"), "Hello File");

Możesz również rozważyć określenie kodowania pliku.


10
Drobna poprawka, drugi fragment powinien brzmieć: FileUtils.writeStringToFile (nowy plik („test.txt”), „Hello File”);
pm_labs

3
Dla tych z nas, którzy wolą Guava, może to zrobić .
Jonik

10
Funkcja jest teraz przestarzała, należy dodać domyślny FileUtils.writeStringToFile(new File("test.txt"), "Hello File", forName("UTF-8"));
zestaw

97

Spójrz na API Java File API

szybki przykład:

try (PrintStream out = new PrintStream(new FileOutputStream("filename.txt"))) {
    out.print(text);
}

@ XP1 Wiem, to świetna poprawa. Użyłem Lombok do tego w Javie 6: po prostu idź @Cleanup new FileOutputStream(...)i gotowe.
Jorn

6
Nie zapomnij wywołać out.flush (); następnie out.close ();
Alex Byrth,

@AlexByrth dlaczego powinien?
Andrew Tobilko,

1
Duże pliki są zapisywane w tle (inny wątek) i nagrywanie zajmuje trochę czasu. Wywołanie flush () zapewnia, że ​​wszystko zostało zapisane w następnym wierszu, synchronizując operację. Jest to jednak opcjonalne , ale dobra praktyka w przypadku obsługi dużych plików, takich jak dzienniki.
Alex Byrth,

1
Zauważ, że out.close () już opróżnia strumień, co oznacza, że ​​nie trzeba wywoływać metody out.flush ().
hjk321,

90

W Javie 7 możesz to zrobić:

String content = "Hello File!";
String path = "C:/a.txt";
Files.write( Paths.get(path), content.getBytes());

Więcej informacji tutaj: http://www.drdobbs.com/jvm/java-se-7-new-file-io/231600403


3
Na wypadek, gdyby ktoś się później zastanawiał, kodowanie byłoby standardem platformy.
Haakon Løtveit

5
content.getBytes(StandardCharsets.UTF_8)można użyć do jawnego zdefiniowania kodowania.
John29

1
Zauważ, że StandardOpenOption.CREATE nie jest domyślny StandardOpenOption.CREATE i StandardOpenOption.TRUNCATE_EXISTING jest domyślny. Aby użyć domyślnego, wystarczy usunąć trzeci parametr.
Tinus Tate,

Zobacz komentarz Tinusa Tate! Jak wygląda proces edycji tego przykładu? Zastanawiam się, ile tysięcy osób wzięło ten przykład za „tylko”, aby odkryć, że mają nieoczekiwane wyniki, gdy nadpisują plik krótszym łańcuchem. Jak wskazuje Tinus, TRUNCATE_EXISTING ma kluczowe znaczenie, chyba że w pełni rozumiesz i masz rzeczywisty powód, dla którego nie chcesz obcinać istniejącego pliku podczas nadpisywania krótszym łańcuchem.
jch

1
W java 11 możesz po prostu wpisać ciąg jako drugi parametr! Brawo!
Dennis Glot,

78

Właśnie zrobiłem coś podobnego w moim projekcie. Korzystanie z FileWriter uprości część zadania. I tutaj możesz znaleźć fajny samouczek .

BufferedWriter writer = null;
try
{
    writer = new BufferedWriter( new FileWriter( yourfilename));
    writer.write( yourstring);

}
catch ( IOException e)
{
}
finally
{
    try
    {
        if ( writer != null)
        writer.close( );
    }
    catch ( IOException e)
    {
    }
}

4
Usuwając wszystkie try / catch i upraszczając, mogę to zrobić w jednym wierszu, wykonując: (new BufferedWriter (new FileWriter (nazwa pliku))). Write (str);
Artem Barger

6
Pokaż więc swoje proste i ładne rozwiązanie. Z przyjemnością nauczę się, jak to robić lepiej.
Artem Barger

4
Zignoruj ​​trolle ... zawsze krytykują, nie oferując własnego rozwiązania. Dzięki za uratowanie mnie przed napisaniem własnego kodu / pobraniem dodatkowej biblioteki i wprowadzeniem zależności ...
nikib3ro 27.01.11

1
Wydaje się, że .close()nie rzuca (przynajmniej w Javie 7?), Czy ostatni trycatch może być zbędny?
Kos

16
Przełykanie takich wyjątków utrudni ci życie, gdy naprawdę się zdarzają. Przynajmniej powinieneś rzucić je:throw new RuntimeException(e);
Roger Keays

65

Użyj FileUtils.writeStringToFile()z Apache Commons IO . Nie ma potrzeby wymyślania tego konkretnego koła.


20
Nie mogłem się nie zgodzić. Te biblioteki istnieją, więc nie wprowadzamy subtelnych błędów w tak prostym rozwiązaniu.
skaffman

3
Nie, oczywiście że nie. Nie zgadzam się tylko z tym, że twoje rozwiązanie może nie być pierwszą rzeczą, którą rzuciłbym na kogoś, kto jest początkującym programistą Java. Nie sugerujesz, że nigdy czegoś takiego nie napisałeś, prawda?
duffymo

8
Tak, ale zanim znalazłem commons-io. Odkąd to odkryłem, nigdy nie pisałem tego rodzaju rzeczy ręcznie, nawet w jednoklasowym projekcie. Gdybym wiedział o tym od pierwszego dnia, użyłbym tego od pierwszego dnia.
skaffman

5
Dokładnie, ale jesteś doświadczonym programistą. Twoja biografia mówi, że jesteś użytkownikiem JBOSS / Spring, ale z pewnością nie byłbyś w stanie poradzić sobie z żadnym z nich przy pierwszym filmie „Witaj, świecie”. Nie zgadzam się z prawidłowym korzystaniem z bibliotek. Mówię, że ludzie, którzy próbują języka po raz pierwszy, powinni spróbować poznać go na samym dole, nawet jeśli oznacza to robienie rzeczy, które odłożą później, gdy będą doświadczeni i będą lepiej wiedzieć.
duffymo

2
Zaimplementowałem to bez elementów wspólnych i został zgłoszony mniej niż oczywisty wyjątek. Następnie zaimplementowałem to za pomocą commons i dokładnie powiedziałem, co jest nie tak. Morał tej historii: po co żyć w ciemnych czasach, jeśli nie musisz?
SilentNot

22

Możesz użyć poniższego kodu modyfikacji, aby zapisać plik z dowolnej klasy lub funkcji, która obsługuje tekst. Można się jednak zastanawiać, dlaczego świat potrzebuje nowego edytora tekstu ...

import java.io.*;

public class Main {

    public static void main(String[] args) {

        try {
            String str = "SomeMoreTextIsHere";
            File newTextFile = new File("C:/thetextfile.txt");

            FileWriter fw = new FileWriter(newTextFile);
            fw.write(str);
            fw.close();

        } catch (IOException iox) {
            //do stuff with exception
            iox.printStackTrace();
        }
    }
}

2
To nie zamyka pliku w przypadku wyjątku.
Tom Hawtin - tackline

1
@JanusTroelsen: Jeśli zostanie odrzucony, zacytuj instrukcję Try-with-resources .
trashgod

22

W Javie 11java.nio.file.Files klasa została rozszerzona o dwie nowe metody użytkowych napisać ciąg do pliku. Pierwsza metoda (patrz JavaDoc tutaj ) używa domyślnie zestawu znaków UTF-8 :

Files.writeString(Path.of("my", "path"), "My String");

Druga metoda (patrz JavaDoc tutaj ) pozwala określić indywidualny zestaw znaków:

Files.writeString(Path.of("my", "path"), "My String", StandardCharset.ISO_8859_1);

Obie metody mają opcjonalny parametr Varargs do ustawiania opcji obsługi plików (patrz JavaDoc tutaj ). Poniższy przykład utworzyłby nieistniejący plik lub dołączył łańcuch do istniejącego:

Files.writeString(Path.of("my", "path"), "String to append", StandardOpenOption.CREATE, StandardOpenOption.APPEND);

13

W miarę możliwości wolę polegać na bibliotekach. To sprawia, że ​​mniej prawdopodobne jest, że przypadkowo pomijam ważny krok (jak pomyłka wilcze strzały zrobione powyżej). Niektóre biblioteki są sugerowane powyżej, ale moim ulubionym do tego rodzaju rzeczy jest Google Guava . Guava ma klasę o nazwie Pliki, która ładnie działa do tego zadania:

// This is where the file goes.
File destination = new File("file.txt");
// This line isn't needed, but is really useful 
// if you're a beginner and don't know where your file is going to end up.
System.out.println(destination.getAbsolutePath());
try {
    Files.write(text, destination, Charset.forName("UTF-8"));
} catch (IOException e) {
    // Useful error handling here
}

2
Jeśli używasz Guava, jest też Charsets.UTF-8.
florian

2
@florian: Tak Charsets.UTF_8naprawdę
Tim Büthe

Folder nadrzędny musi istnieć. Przykład: destination.mkdirs ().
AlikElzin-kilaka

2
Files.write (CharSequence z, File to, Charset charset) jest przestarzałe w guava 26.0.
Kaczor Donald

Nowoczesna guawa alternatywa dla przestarzałych plików. Napisz: Files.asCharSink(file, charset).write(text)
Vadzim

12

Użyj Apache Commons IO api. To proste

Użyj API jako

 FileUtils.writeStringToFile(new File("FileNameToWrite.txt"), "stringToWrite");

Zależność Maven

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.4</version>
</dependency>

12

Jeśli potrzebujesz utworzyć plik tekstowy na podstawie jednego ciągu:

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;

public class StringWriteSample {
    public static void main(String[] args) {
        String text = "This is text to be saved in file";

        try {
            Files.write(Paths.get("my-file.txt"), text.getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Files.write (ścieżka, bajt []) użyje kodowania UTF-8. String.getBytes () używa domyślnego kodowania platformy. To jest potencjalny problem. Użyj string.getBytes (StandardCharsets.UTF_8)!
rmuller

11

Użyj tego, jest bardzo czytelny:

import java.nio.file.Files;
import java.nio.file.Paths;

Files.write(Paths.get(path), lines.getBytes(), StandardOpenOption.WRITE);

Jest to także kopia istniejącej odpowiedzi. : c
james.garriss

2
przepraszam, ale nie wymyśliłem java8, nie tylko ja używam tej linii. ale to nie jest kopia przeszłości z innych odpowiedzi na to samo pytanie
Ran Adler,

10
import java.io.*;

private void stringToFile( String text, String fileName )
 {
 try
 {
    File file = new File( fileName );

    // if file doesnt exists, then create it 
    if ( ! file.exists( ) )
    {
        file.createNewFile( );
    }

    FileWriter fw = new FileWriter( file.getAbsoluteFile( ) );
    BufferedWriter bw = new BufferedWriter( fw );
    bw.write( text );
    bw.close( );
    //System.out.println("Done writing to " + fileName); //For testing 
 }
 catch( IOException e )
 {
 System.out.println("Error: " + e);
 e.printStackTrace( );
 }
} //End method stringToFile

Możesz wstawić tę metodę do swoich klas. Jeśli używasz tej metody w klasie z metodą główną, zmień tę klasę na statyczną, dodając słowo klucza statycznego. Tak czy inaczej, musisz zaimportować plik java.io. *, aby działał, w przeciwnym razie File, FileWriter i BufferedWriter nie zostaną rozpoznane.


10

Możesz to zrobić:

import java.io.*;
import java.util.*;

class WriteText
{
    public static void main(String[] args)
    {   
        try {
            String text = "Your sample content to save in a text file.";
            BufferedWriter out = new BufferedWriter(new FileWriter("sample.txt"));
            out.write(text);
            out.close();
        }
        catch (IOException e)
        {
            System.out.println("Exception ");       
        }

        return ;
    }
};

10

Używanie Java 7:

public static void writeToFile(String text, String targetFilePath) throws IOException
{
    Path targetPath = Paths.get(targetFilePath);
    byte[] bytes = text.getBytes(StandardCharsets.UTF_8);
    Files.write(targetPath, bytes, StandardOpenOption.CREATE);
}

Słowo dla mądrych - stworzy nowy plik, jeśli go nie ma, ale zastąpi znaki istniejącego pliku, jeśli tak jest. Jeśli nowe dane są mniejsze, oznacza to, że prawdopodobnie utworzyłeś uszkodzony plik. Zapytaj mnie, skąd to wiem!
Chris Rae,

Ok, skąd wiesz?
ojblass

Files.write(targetPath, bytes);Następnie użyj, aby zastąpić plik. Będzie działać zgodnie z oczekiwaniami.
BullyWiiPlaza

8

Korzystanie z org.apache.commons.io.FileUtils:

FileUtils.writeStringToFile(new File("log.txt"), "my string", Charset.defaultCharset());

6

Jeśli zależy Ci tylko na wypchnięciu jednego bloku tekstu do pliku, spowoduje to zastąpienie go za każdym razem.

JFileChooser chooser = new JFileChooser();
int returnVal = chooser.showSaveDialog(this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
    FileOutputStream stream = null;
    PrintStream out = null;
    try {
        File file = chooser.getSelectedFile();
        stream = new FileOutputStream(file); 
        String text = "Your String goes here";
        out = new PrintStream(stream);
        out.print(text);                  //This will overwrite existing contents

    } catch (Exception ex) {
        //do something
    } finally {
        try {
            if(stream!=null) stream.close();
            if(out!=null) out.close();
        } catch (Exception ex) {
            //do something
        }
    }
}

Ten przykład pozwala użytkownikowi wybrać plik za pomocą selektora plików.


@Eric Leschinski: dziękuję za uczynienie mojej odpowiedzi bardziej profesjonalną (założyłem również, że właśnie tego chciał OP, ponieważ tego właśnie chce większość ludzi, po prostu
zrzuć

2
Po udzieleniu odpowiedzi na pierwotne pytanie, gdy PO jest usatysfakcjonowany i dawno minęły, strony takie jak ten służą tylko jako użyteczny artefakt dla osób, które trafią tutaj z wyszukiwarki Google. Wylądowałem na tej stronie, aby utworzyć mini-tekstowy dodatek do pliku. Dlatego dobrze jest porozmawiać z całą publicznością, a nie z OP po przejściu PO.
Eric Leschinski,

3

Lepiej jest zamknąć moduł zapisujący / wyjściowy w ostatnim bloku, na wypadek, gdyby coś się wydarzyło

finally{
   if(writer != null){
     try{
        writer.flush();
        writer.close();
     }
     catch(IOException ioe){
         ioe.printStackTrace();
     }
   }
}

1
jeszcze lepiej: użyj try-with-resources
Janus Troelsen

Tak, @JanusTroelsen ma rację, lepsze wykorzystanie Oświadczenie try-with-resources docs.oracle.com/javase/tutorial/essential/exceptions/…

2
private static void generateFile(String stringToWrite, String outputFile) {
try {       
    FileWriter writer = new FileWriter(outputFile);
    writer.append(stringToWrite);
    writer.flush();
    writer.close();
    log.debug("New File is generated ==>"+outputFile);
} catch (Exception exp) {
    log.error("Exception in generateFile ", exp);
}

}


1
Ten fragment kodu może być rozwiązaniem, ale wyjaśnienie naprawdę pomaga poprawić jakość posta. Pamiętaj, że w przyszłości odpowiadasz na pytanie czytelników, a ci ludzie mogą nie znać przyczyn Twojej sugestii kodu.
Johan

close () może nigdy nie zostać wywołany. Popraw swoją odpowiedź, dodając odpowiednią obsługę przypadków błędów.
Boris Brodski

0

Myślę, że najlepszym sposobem jest użycie Files.write(Path path, Iterable<? extends CharSequence> lines, OpenOption... options):

String text = "content";
Path path = Paths.get("path", "to", "file");
Files.write(path, Arrays.asList(text));

Zobacz javadoc :

Napisz wiersze tekstu do pliku. Każda linia jest sekwencją char i jest zapisywana do pliku w sekwencji, a każda linia kończy się separatorem linii platformy, zgodnie z definicją właściwości systemowej line.separator. Znaki są kodowane w bajtach przy użyciu określonego zestawu znaków.

Parametr options określa sposób tworzenia lub otwierania pliku. Jeśli nie ma żadnych opcji, ta metoda działa tak, jakby były dostępne opcje CREATE, TRUNCATE_EXISTING i WRITE. Innymi słowy, otwiera plik do zapisu, tworzenia pliku, jeśli nie istnieje, lub początkowego obcięcia istniejącego zwykłego pliku do rozmiaru 0. Metoda zapewnia zamknięcie pliku po zapisaniu wszystkich wierszy ( lub zgłaszany jest błąd we / wy lub inny wyjątek czasu wykonywania). Jeśli wystąpi błąd we / wy, może to zrobić po utworzeniu lub obcięciu pliku lub po zapisaniu do niego niektórych bajtów.

Proszę zanotować. Widzę, że ludzie już odpowiedzieli wbudowaną Javą Files.write, ale w mojej odpowiedzi szczególna rzecz, o której chyba nikt nie wspomina, to przeciążona wersja metody, która pobiera Iterable z CharSequence (tj. String) zamiast byte[]tablicy, dlatego text.getBytes()nie jest wymagana , co wydaje mi się nieco czystsze.


0

Jeśli chcesz zachować znaki powrotu karetki z łańcucha do pliku, oto przykład kodu:

    jLabel1 = new JLabel("Enter SQL Statements or SQL Commands:");
    orderButton = new JButton("Execute");
    textArea = new JTextArea();
    ...


    // String captured from JTextArea()
    orderButton.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent ae) {
            // When Execute button is pressed
            String tempQuery = textArea.getText();
            tempQuery = tempQuery.replaceAll("\n", "\r\n");
            try (PrintStream out = new PrintStream(new FileOutputStream("C:/Temp/tempQuery.sql"))) {
                out.print(tempQuery);
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println(tempQuery);
        }

    });

-1

Mój sposób jest oparty na strumieniu ze względu na działanie na wszystkich wersjach Androida i potrzeby pobierania zasobów takich jak URL / URI, wszelkie sugestie są mile widziane.

Jeśli chodzi o strumienie, dane wejściowe (InputStream i OutputStream) przesyłają dane binarne, gdy programista zapisuje ciąg do strumienia, najpierw musi go przekonwertować na bajty lub innymi słowy, zakodować.

public boolean writeStringToFile(File file, String string, Charset charset) {
    if (file == null) return false;
    if (string == null) return false;
    return writeBytesToFile(file, string.getBytes((charset == null) ? DEFAULT_CHARSET:charset));
}

public boolean writeBytesToFile(File file, byte[] data) {
    if (file == null) return false;
    if (data == null) return false;
    FileOutputStream fos;
    BufferedOutputStream bos;
    try {
        fos = new FileOutputStream(file);
        bos = new BufferedOutputStream(fos);
        bos.write(data, 0, data.length);
        bos.flush();
        bos.close();
        fos.close();
    } catch (IOException e) {
        e.printStackTrace();
        Logger.e("!!! IOException");
        return false;
    }
    return true;
}

1
Dodaj poprawną obsługę przypadków błędów zamykających wszystkie otwarte zasoby i propagujących wyjątki
Boris Brodski

Czy mógłbyś dzielić się przypadkami obsługi kodu zgodnie z zaleceniami, dziękuję.
牟家宏

-1

Możesz użyć ArrayList, aby umieścić całą zawartość TextArea dla przykładu, i wysłać jako parametr, wywołując save, ponieważ pisarz właśnie napisał linie ciągów, a następnie używamy „for” wiersz po wierszu, aby zapisać naszą ArrayList na końcu będziemy zawartość TextArea w pliku txt. jeśli coś nie ma sensu, przykro mi to tłumacz Google i ja, którzy nie mówię po angielsku.

Obejrzyj Notatnik Windows, nie zawsze przeskakuje on przez linie i pokazuje wszystko w jednym wierszu, użyj WordPada ok.


private void SaveActionPerformed(java.awt.event.ActionEvent evt) {

    String NameFile = Name.getText();
    ArrayList< String > Text = new ArrayList< String >();

    Text.add(TextArea.getText());

    SaveFile(NameFile, Text);
}

public void SaveFile(String name, ArrayList< String> message) {

    path = "C:\\Users\\Paulo Brito\\Desktop\\" + name + ".txt";

    File file1 = new File(path);

    try {

        if (!file1.exists()) {

            file1.createNewFile();
        }


        File[] files = file1.listFiles();


        FileWriter fw = new FileWriter(file1, true);

        BufferedWriter bw = new BufferedWriter(fw);

        for (int i = 0; i < message.size(); i++) {

            bw.write(message.get(i));
            bw.newLine();
        }

        bw.close();
        fw.close();

        FileReader fr = new FileReader(file1);

        BufferedReader br = new BufferedReader(fr);

        fw = new FileWriter(file1, true);

        bw = new BufferedWriter(fw);

        while (br.ready()) {

            String line = br.readLine();

            System.out.println(line);

            bw.write(line);
            bw.newLine();

        }
        br.close();
        fr.close();

    } catch (IOException ex) {
        ex.printStackTrace();
        JOptionPane.showMessageDialog(null, "Error in" + ex);     
    }   
}

Możesz pozostawić otwarte zasoby. To zła praktyka, proszę, nie rób tego.
Boris Brodski
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.