21

我想将 a 写入StringUnicode 文件。我的代码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;
}

更新

现在将其与 C# 进行比较:

    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();
        }
    }

也许是因为我来自 C# 和 .Net 世界。但这是将字符串写入文件的正确方法吗?对于这样简单的任务来说,代码太多了。在 C# 中,我会说只是这样,但在语句内部out.close();添加一个似乎有点奇怪。无论发生什么,我都添加了关闭文件(资源)的语句。避免使用过多的资源。这是Java中的正确方法吗?如果是这样,为什么会抛出异常?try..catchfinallyfinallyclose

4

8 回答 8

17

您是正确的,因为您需要在 finally 块中调用 close() 并且您还需要包装这是一个 try/catch

通常,您将在项目中编写实用程序方法或使用库中的实用程序方法,例如http://commons.apache.org/io/apidocs/org/apache/commons/io/IOUtils.html#closeQuietly(java.io .Closeable)以安静地关闭。即忽略来自 close() 的任何抛出异常。

另外一点,Java 7 添加了对资源尝试的支持,从而无需手动关闭资源 - http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

于 2013-01-04T11:33:01.987 回答
3

是的,在 java 的 finally() 中 Try catch 并没有什么奇怪的。close() 可能由于各种原因抛出 IoException,这就是为什么它必须被 try catch 块包围。您的这个问题有一个改进的解决方案,在最新的 java SE 7 中尝试使用资源

于 2013-01-04T11:22:28.327 回答
2

与 using 语句等效的 Java 是 Java 7 中添加的 try-with-resources 语句:

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

try-with-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;
    }
}
于 2013-01-04T15:46:05.977 回答
1

这应该可以解决问题。如果您想管理具有复杂行为的异常 - 然后创建StreamWriter

public static bool saveStringToFile(String fileName, String text) 
{
    try
    {
        File.WriteAllText(fileName, text, Encoding.UTF8);
    }
    catch (IOException exp)
    {
        return false;
    }
    return true;
}
于 2013-01-04T11:25:11.673 回答
0

那么,问题是什么?没有正确或错误的方法。甚至可以关闭抛出 IO Exception 吗?那你怎么办呢?我通常不喜欢任何形式的不重新抛出。

问题是——你只是在关闭时吞下一个 IO 异常——很好。你能忍受那种打击吗?如果不是你有问题,如果是 - 没有错。

我从来没有这样做过,但是 - 再次,这取决于您的业务案例。

于 2013-01-04T11:21:57.237 回答
0
arch = new File("path + name");
arch.createNewFile();
FileOutputStream fos = new FileOutputStream(arch);
fos.write("ur text");
fos.close();

我的方式。

于 2013-01-04T11:22:58.830 回答
0

避免这种情况的最佳方法是将 out.close() 放在 out.flush() 之后,如果关闭失败,则会自动处理该过程。或者使用这个更好(我正在使用):

File file = ...
   OutputStream out = null;
   try {
     out = new BufferedOutputStream(new FileOutputStream(file));
     ...
    finally {
     if (out != null) {
       out.close();
     }
   }
 }
于 2013-01-04T11:26:27.313 回答
0

如果你想要最少的代码,你可以使用FileUtils.writeStringToFile

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

而且我不会使用布尔值,因为忽略发生错误的事实或发生错误的原因(在异常消息中)很少是一个好主意。使用已检查的异常可确保调用者始终正确处理此类错误,并可以记录有意义的错误消息以说明原因。

使用特定的 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);
}
于 2013-01-04T11:40:01.373 回答