Подтвердить что ты не робот

Попробуйте... поймать внутри, наконец, при выпуске ресурса?

Я хочу написать String в файл Unicode. Мой код в Java:

public static boolean saveStringToFile(String fileName, String text) {
    BufferedWriter out = null;
    boolean result = true;
    try {
        File f = new File(fileName);
        out = new BufferedWriter(new OutputStreamWriter(
                new FileOutputStream(f), "UTF-8"));
        out.write(text);
        out.flush();
    } catch (Exception ex) {
        result = false;
    } finally {
        if (out != null)
            try {
                out.close();
            } catch (IOException e) {
                // nothing to do! couldn't close
            }
    }

    return result;
}

Update

Теперь сравните его с С#:

    private static bool SaveStringToFile(string fileName, string text)
    {
        using (StreamWriter writer = new StreamWriter(fileName))
        {
            writer.Write(text);
        }
    }
Форма

или даже try..catch будет:

    private static bool SaveStringToFile(string fileName, string text)
    {
        StreamWriter writer = new StreamWriter(fileName);
        try
        {
            writer.Write(text);
        }catch (Exception ex)
        {
            return false;
        }
        finally
        {
            if (writer != null)
                writer.Dispose();
        }
    }

Возможно, это потому, что я из мира С# и .Net. Но это правильный способ написать String в файл? Это слишком много кода для такой простой задачи. В С# я бы сказал просто out.close();, и это было так, но кажется немного странным добавить try..catch внутри оператора finally. Я добавил оператор finally, чтобы закрыть файл (ресурс) независимо от того, что произойдет. Во избежание использования слишком большого ресурса. Правильно ли это на Java? Если да, почему close выдает исключение?

4b9b3361

Ответ 1

Вы правы в том, что вам нужно вызвать close() в блоке finally, и вам также необходимо обернуть это try/catch

Как правило, вы пишете полезный метод в проекте или используете метод утилиты из библиотеки, например http://commons.apache.org/io/apidocs/org/apache/commons/io/IOUtils.html#closeQuietly(java.io.Closeable), чтобы закрыть Quietly.i.e. игнорировать любое исключение throw из объекта close().

Еще одна заметка: Java 7 добавила поддержку для попыток с ресурсами, которая устраняет необходимость вручную закрыть resouce - http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

Ответ 2

Да, нет ничего странного в том, что Try catch in finally() в java. close() может вызывать исключение IoException по разным причинам, поэтому он должен быть заключен в блоки try catch. Существует усовершенствованное решение этой проблемы, в последней версии java SE 7 Попробуйте с ресурсами

Ответ 3

Java-эквивалент оператора using - это оператор try-with-resources, добавленный в Java 7:

public static void saveStringToFile(String fileName, String text) throws IOException {
    try (Writer w = new OutputStreamWriter(new FileOutputStream(fileName), "UTF-8")) {
        w.write(text);
    }
}

С помощью try-in-resources будет автоматически закрываться поток (который сжимает его), и бросать любые исключения, возникающие при этом.

BufferedWriter не требуется, если вы все равно производите один вызов (его цель состоит в объединении нескольких записей в базовый поток для уменьшения количества системных вызовов, что повышает производительность).

Если вы настаиваете на обработке ошибок, возвращая false, вы можете добавить предложение catch:

public static boolean saveStringToFile(String fileName, String text) {
    try (Writer w = new OutputStreamWriter(new FileOutputStream(fileName), "UTF-8")) {
        w.write(text);
        return true;
    } catch (IOException e) {
        return false;
    }
}

Ответ 4

Это должно сделать трюк. Если вы хотите управлять исключением со сложным поведением - создайте StreamWriter

public static bool saveStringToFile(String fileName, String text) 
{
    try
    {
        File.WriteAllText(fileName, text, Encoding.UTF8);
    }
    catch (IOException exp)
    {
        return false;
    }
    return true;
}

Ответ 5

Итак, в чем вопрос? Нет правильного или неправильного пути. Может закрыть даже выбросить исключение IO? Что вы делаете тогда? Мне вообще нравится не реинтронирование любого рода.

Проблема в том, что вы просто проглатываете исключение IO при закрытии - хорошо. Можете ли вы жить с этим дутьем? Если нет, у вас есть проблема, если да - ничего плохого.

Я никогда этого не делал, но, опять же, это зависит от вашего бизнес-случая.

Ответ 6

arch = new File("path + name");
arch.createNewFile();
FileOutputStream fos = new FileOutputStream(arch);
fos.write("ur text");
fos.close();

мой путь.

Ответ 7

Лучший способ избежать этого - поместить ваш out.close() после out.flush(), и процесс автоматически обрабатывается, если сбой завершается. Или используйте это лучше (что я использую):

File file = ...
   OutputStream out = null;
   try {
     out = new BufferedOutputStream(new FileOutputStream(file));
     ...
    finally {
     if (out != null) {
       out.close();
     }
   }
 }

Ответ 8

Если вам нужен минимальный код, вы можете использовать FileUtils.writeStringToFile

FileUtils.writeStringToFile(new File(fileName), text);

и я бы не использовал boolean, так как редко можно было игнорировать либо тот факт, что произошла ошибка, либо причина, по которой она возникла в сообщении об исключении. Использование проверенного Exception гарантирует, что вызывающий абонент всегда будет правильно обрабатывать такую ​​ошибку и может регистрировать осмысленные сообщения об ошибках относительно того, почему.

Чтобы сохранить файл с помощью специального CharSet

try {
    FileUtils.writeStringToFile(new File(fileName), text, "UTF-8");
} catch(IOException ioe) {
    Logger.getLogger(getClass()).log(Level.WARNING, "Failed to write to " + fileName, ioe);
}