Как сохранить строку в текстовом файле с помощью Java?

699

В Java у меня есть текст из текстового поля в строковой переменной с именем «текст».

Как я могу сохранить содержимое переменной «text» в файл?

Джастин Уайт
источник

Ответы:

727

Если вы просто выводите текст, а не какие-либо двоичные данные, сработает следующее:

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

Затем запишите свою строку, как и в любой выходной поток:

out.println(text);

Вам понадобится обработка исключений, как всегда. Обязательно позвоните, out.close()когда закончите писать.

Если вы используете Java 7 или более позднюю версию, вы можете использовать « оператор try-with-resources », который автоматически закроет ваш файл, PrintStreamкогда вы закончите с ним (то есть выйдите из блока), примерно так:

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

Вам все равно нужно будет явно бросить, java.io.FileNotFoundExceptionкак и раньше.

Джереми Смит
источник
4
@Justin, вы также можете передать абсолютный путь (например, «/tmp/filename.txt») в конструктор FileOutputStream, чтобы сохранить файл в любом месте
Jonik
7
Кстати, это можно упростить, используя удобные конструкторы, которые PrintStream имеет с 1.5. Этого будет достаточно: PrintStream out = new PrintStream ("filename.txt");
Джоник
10
Нужно закрыть этот файл хоть в какой-то момент ...? codecodex.com/wiki/ASCII_file_save#Java
JStrahl
2
Вы хотите использовать try {} catch () {} finally {}, где в finally {} вы закрываете файл, если он не равен нулю.
Бенас
23
В java8 вы можете попробовать (PrintStream ps = new PrintStream ("filename")) {ps.println (out); } это поможет вам
Антон Чикин
245

Apache Commons IO содержит несколько отличных методов для этого, в частности FileUtils содержит следующий метод:

static void writeStringToFile(File file, String data) 

который позволяет записывать текст в файл одним вызовом метода:

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

Вы также можете рассмотреть возможность указания кодировки для файла.

Джон
источник
10
Просто небольшая поправка, второй фрагмент должен выглядеть следующим образом: FileUtils.writeStringToFile (new File ("test.txt"), "Hello File");
pm_labs
3
Для тех из нас, кто предпочитает гуаву, он тоже может это сделать .
Джоник
10
Теперь функция устарела, вы должны добавить кодировку по умолчанию ->FileUtils.writeStringToFile(new File("test.txt"), "Hello File", forName("UTF-8"));
Пол
97

Посмотрите на Java File API

быстрый пример:

try (PrintStream out = new PrintStream(new FileOutputStream("filename.txt"))) {
    out.print(text);
}
Йорн
источник
@ XP1 Я знаю, это большое улучшение. Я использовал Lombok для этого в Java 6: просто иди @Cleanup new FileOutputStream(...)и готово.
Йорн
6
Не забудьте вызвать out.flush (); затем out.close ();
Алекс Берт
@AlexByrth зачем ему?
Андрей Тобилко
1
Большие файлы записываются в фоновом режиме (другой поток) и требуют времени для записи. Вызов flush () гарантирует, что все было записано на следующей строке, синхронизируя операцию. Но это необязательно , но хорошая практика, если вы обрабатываете большие файлы, такие как журналы.
Алекс Берт
1
Обратите внимание, что out.close () уже очищает поток, что означает, что нет необходимости вызывать out.flush ().
hjk321
90

В Java 7 вы можете сделать это:

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

Больше информации здесь: http://www.drdobbs.com/jvm/java-se-7-new-file-io/231600403

Даниил Шевелев
источник
3
В случае, если кто-то потом задумался, кодировка будет стандартом платформы.
Haakon Løtveit
5
content.getBytes(StandardCharsets.UTF_8)может использоваться для явного определения кодировки.
Джон 29
1
Обратите внимание, что StandardOpenOption.CREATE не является значением по умолчанию, а StandardOpenOption.CREATE и StandardOpenOption.TRUNCATE_EXISTING является значением по умолчанию. Чтобы использовать значение по умолчанию, просто удалите третий параметр.
Тинус Тейт
Пожалуйста, смотрите комментарий Тинус Тейт! Как происходит редактирование этого примера? Интересно, сколько тысяч людей взяли этот пример «как есть» только для того, чтобы обнаружить, что они получают неожиданные результаты, когда перезаписывают файл более короткой строкой. Как указывает Tinus, TRUNCATE_EXISTING имеет решающее значение, если вы не полностью понимаете и не имеете реальной причины не желать обрезать существующий файл при перезаписи более короткой строкой.
JCH
1
В Java 11 вы можете просто поместить строку в качестве второго параметра! Ура!
Деннис
78

Просто сделал что-то похожее в моем проекте. Использование FileWriter упростит часть вашей работы. И здесь вы можете найти хороший учебник .

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
Удаляя все try / catch и упрощая его, я также могу сделать это в одну строку, просто выполнив: (new BufferedWriter (new FileWriter (filename))). Write (str);
Артем Баргер
6
Итак, покажи свое простое и приятное решение. Я был бы рад узнать, как сделать это лучше.
Артем Баргер
4
Проигнорируйте троллей ... они всегда критикуют, не предлагая их собственного решения. Спасибо, что спасли меня от написания собственного кода / загрузки дополнительной библиотеки и введения зависимости ...
nikib3ro
1
Кажется, что .close()не выдает (по крайней мере, в Java 7?), Является ли последний trycatch возможно избыточным?
Кос
16
Проглатывание подобных исключений усложнит вам жизнь, когда действительно произойдут исключения. По крайней мере, вы должны отбросить их:throw new RuntimeException(e);
Roger Keays
65

Используйте FileUtils.writeStringToFile()от Apache Commons IO . Не нужно изобретать это колесо.

skaffman
источник
20
Я не мог не согласиться больше. Эти библиотеки есть, поэтому мы не вносим тонких ошибок в такое простое решение.
Скаффман
3
Нет, очевидно нет. Я только не согласен с тем, что ваше решение, возможно, не первое, что я бросил бы на кого-то, кто является начинающим Java-программистом. Вы же не говорите, что никогда не писали ничего подобного?
duffymo
8
У меня есть, да, но это до того, как я нашел обыкновенные. С тех пор, как я нашел это, я никогда не писал такого рода вещи вручную, даже в одноклассном проекте. Если бы я знал об этом с первого дня, я бы использовал это с первого дня.
Скаффман
5
Точно, но вы опытный разработчик. В вашей биографии говорится, что вы - пользователь JBOSS / Spring, но, конечно, вы не смогли бы участвовать ни в одном из своих первых попыток "Hello, World". Я не согласен с правильным использованием библиотек. Я говорю о том, что люди, пытающиеся использовать язык впервые, должны постараться узнать его в самом низу, даже если это означает делать то, что они откажутся позже, когда будут иметь опыт и будут лучше знать.
duffymo
2
Я реализовал это без общего достояния и получил менее очевидное исключение. Затем я реализовал это с помощью общих ресурсов, и он сказал мне, что именно не так. Мораль истории: зачем жить в темные века, если не нужно?
SilentNot
22

Вы можете использовать модифицированный код ниже, чтобы написать свой файл из любого класса или функции, обрабатывающей текст. Интересно, почему миру нужен новый текстовый редактор ...

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
Это не закрывает файл в случае исключения.
Том Хотин - tackline
1
@JanusTroelsen: Если отклонено, приведите « Заявление об использовании ресурсов» .
trashgod
22

В Java 11java.nio.file.Files класс был продлен на два новых служебных методов , чтобы записать строку в файл. Первый метод (см. JavaDoc здесь ) использует кодировку UTF-8 по умолчанию:

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

И второй метод (см. JavaDoc здесь ) позволяет указать отдельную кодировку:

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

Оба метода имеют необязательный параметр Varargs для настройки параметров обработки файлов (см. JavaDoc здесь ). В следующем примере будет создан несуществующий файл или добавлена ​​строка к существующему:

Files.writeString(Path.of("my", "path"), "String to append", StandardOpenOption.CREATE, StandardOpenOption.APPEND);
завивать волосы щипцами
источник
13

Я предпочитаю полагаться на библиотеки, когда это возможно, для такого рода операций. Это снижает вероятность того, что я случайно пропущу важный шаг (например, ошибку, сделанную выше). Некоторые библиотеки предложены выше, но мой фаворит для такого рода вещей - Google Guava . У Guava есть класс Files, который отлично подходит для этой задачи:

// 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
Если вы используете гуаву, есть также Charsets.UTF-8.
Флориан
2
@florian: Это на Charsets.UTF_8самом деле
Тим Бют
Родительская папка должна существовать. Пример: destination.mkdirs ().
Алик Эльзин-килака
2
Files.write (CharSequence from, File to, Charset charset) устарел в guava 26.0.
Дональд Дак
Современная гуавы альтернатива устаревшей Files.write: Files.asCharSink(file, charset).write(text)
Вадима
12

Используйте Apache Commons IO api. Это просто

Использовать API как

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

Maven Dependency

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.4</version>
</dependency>
Анирбан Чакрабарти
источник
12

В случае, если вам нужно создать текстовый файл на основе одной строки:

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();
        }
    }
}
Pavel_H
источник
Files.write (path, byte []) будет использовать кодировку UTF-8. String.getBytes () использует кодировку платформы по умолчанию. Так что это потенциальная проблема. Используйте string.getBytes (StandardCharsets.UTF_8)!
rmuller
11

Используйте это, это очень читабельно:

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

Files.write(Paths.get(path), lines.getBytes(), StandardOpenOption.WRITE);
Ран Адлер
источник
Это также копия существующего ответа. : c
james.garriss
2
извините, но я не изобрел java8, я не единственный, кто использует эту строку. но это не копия прошлого от других ответов на тот же вопрос
Ран Адлер
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

Вы можете вставить этот метод в ваши классы. Если вы используете этот метод в классе с методом main, измените этот класс на статический, добавив ключевое слово static. В любом случае вам нужно будет импортировать java.io. *, чтобы он работал, иначе File, FileWriter и BufferedWriter не будут распознаны.

Шон Х. Уортингтон
источник
10

Вы могли бы сделать это:

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

Использование 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);
}
BullyWiiPlaza
источник
Слово мудрому - это создаст новый файл, если его там нет, но перезапишет символы существующего файла, если он там есть. Если новые данные меньше, это будет означать, что вы, вероятно, создаете поврежденный файл. Спроси меня, откуда я знаю!
Крис Рей
Ок, откуда ты знаешь?
ojblass
Просто используйте, Files.write(targetPath, bytes);чтобы перезаписать файл тогда. Это будет работать как ожидалось.
BullyWiiPlaza
8

Использование org.apache.commons.io.FileUtils:

FileUtils.writeStringToFile(new File("log.txt"), "my string", Charset.defaultCharset());
GoYun.Info
источник
6

Если вам нужно только вставить один блок текста в файл, это будет перезаписывать его каждый раз.

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
        }
    }
}

Этот пример позволяет пользователю выбрать файл с помощью средства выбора файлов.

bhathiya-Перер
источник
@Eric Leschinski: спасибо за то, что вы сделали мой ответ более профессиональным (я также предположил, что именно этого и хотел ОП, поскольку именно этого и хочет большинство людей, просто
сбросьте
2
После того, как первоначальный вопрос получен, а ОП удовлетворен и ушел в прошлое, подобные страницы служат лишь полезным артефактом для людей, которые попадают сюда из поиска Google. Я попал на эту страницу, чтобы создать мини-текстовый аппендер к файлу. Так что лучше говорить со всей аудиторией, а не с ОП после того, как ОП продолжится.
Эрик Лещинский
3

Лучше закрыть писатель / выходной поток в блоке finally, на случай, если что-то случится

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

источник
1
еще лучше: используйте попытку с ресурсами
Янус Троелсен
Да, @JanusTroelsen правильно, лучше использовать пробный-с-ресурсов заявления 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
Хотя этот фрагмент кода может быть решением, включение пояснения действительно помогает улучшить качество вашего сообщения. Помните, что вы отвечаете на вопрос читателей в будущем, и эти люди могут не знать причин, по которым вы предлагаете код.
Йохан
close () никогда не может быть вызван. Пожалуйста, улучшите свой ответ, добавив правильную обработку ошибок.
Борис Бродский
0

Я думаю, что лучше всего использовать 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));

Смотри Javadoc :

Записать строки текста в файл. Каждая строка представляет собой последовательность символов и записывается в файл последовательно, каждая строка завершается разделителем строк платформы, как определено системным свойством line.separator. Символы кодируются в байты с использованием указанной кодировки.

Параметр options указывает, как файл создается или открывается. Если параметры отсутствуют, этот метод работает так, как если бы присутствовали параметры CREATE, TRUNCATE_EXISTING и WRITE. Другими словами, он открывает файл для записи, создает файл, если он не существует, или изначально обрезает существующий обычный файл до размера 0. Метод гарантирует, что файл будет закрыт, когда все строки были записаны ( или ошибка ввода-вывода или другое исключение во время выполнения). Если возникает ошибка ввода-вывода, это может произойти после того, как файл был создан или усечен, или после того, как в файл были записаны некоторые байты.

Пожалуйста, обратите внимание. Я вижу, что люди уже ответили с помощью встроенного в Java Files.write, но что особенного в моем ответе, который, кажется, никто не упоминает, это перегруженная версия метода, который принимает Iterable CharSequence (т.е. String) вместо byte[]массива, поэтому text.getBytes()не требуется , который немного чище, я думаю.

стихарь-i986
источник
0

Если вы хотите сохранить символы возврата каретки из строки в файл, вот пример кода:

    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

Мой путь основан на потоке, потому что он работает на всех версиях Android и требует много ресурсов, таких как URL / URI, любые предложения приветствуются.

Что касается этого, потоки (InputStream и OutputStream) передают двоичные данные, когда разработчик собирается записать строку в поток, сначала должен преобразовать ее в байты или, другими словами, кодировать ее.

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
Пожалуйста, добавьте правильную обработку ошибок, закрывая все открытые ресурсы и распространяя исключения
Борис Бродский
Не могли бы вы поделиться случаями обработки кода, как вы рекомендовали, спасибо.
牟家宏
-1

Вы можете использовать ArrayList, чтобы поместить все содержимое TextArea в качестве примера, и отправить в качестве параметра, вызвав save, так как писатель только что записал строковые строки, а затем мы будем использовать строку «для» построчно, чтобы написать наш ArrayList в конце мы будем содержимое TextArea в текстовом файле. если что-то не имеет смысла, извините, Google переводчик и я, кто не говорит по-английски.

Посмотрите Блокнот Windows, он не всегда пересекает строки и показывает все в одной строке, используйте Wordpad нормально.


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);     
    }   
}
Пауло Брито
источник
Вы можете оставить кучу открытых ресурсов. Это плохая практика, пожалуйста, не делайте этого.
Борис Бродский