Попробуйте... поймать внутри, наконец, при выпуске ресурса?
Я хочу написать 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
выдает исключение?
Ответы
Ответ 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);
}