首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用读写流复制文件

使用读写流复制文件
EN

Code Review用户
提问于 2020-11-12 23:45:24
回答 3查看 86关注 0票数 2

我在我的程序中有一段代码,其中我指定10000作为缓冲区的大小。现在如何检查我正在复制的文件是否小于10000,例如5000,而不是如何释放剩余的5000?

谢谢。

代码语言:javascript
复制
private void copyFile(File in, File out) {
        var buffer = new byte[10000];
        try {
            FileInputStream dis = new FileInputStream(in);
            FileOutputStream dos = new FileOutputStream(out);
            int count;
            do {
                count = dis.read(buffer);
                if (count != -1)
                    dos.write(buffer, 0, count);
            } while (count != -1);
            dis.close();
            dos.close();
        } catch (IOException e) {
            program.print("Error copying file: " + e.toString() + "\n", null);
        }
    }

编辑:还有,我可以优化这个更多吗?

EN

回答 3

Code Review用户

回答已采纳

发布于 2020-11-13 04:55:11

流应该始终关闭。如果您的方法抛出异常,您将出现资源泄漏。要么关闭finally块中的流,要么使用try-with-resources确保它们被关闭。

可选的大括号不是。在以后修改代码时,跳过大括号通常会导致错误。

用于处理流的典型循环结构看起来更像

代码语言:javascript
复制
int charsRead;
while ((charsRead = dis.read(buffer) > 0) {
    // do stuff
}

对于一个缓冲区来说,10,000是相当大的。这可能不是最好的选择。

请不要吞下堆栈的痕迹。当这段代码需要稍后调试时,这是关键信息。

意见:var很讨厌。

如果应用所有这些更改,您的代码可能更类似于:

代码语言:javascript
复制
private void copyFile(File in, File out) {
    byte[] buffer = new byte[1024];
    try (FileInputStream dis = new FileInputStream(in);
            FileOutputStream dos = new FileOutputStream(out)) {
        int charsRead;
        while ((buffer = dis.read(buffer) > 0) {
                dos.write(buffer, 0, charsRead);
        }
    } catch (IOException e) {
        //I don't know how to use your logging library to display exception stack trace, so..
        e.printStackTrace(System.err);
    }
}

当然,这是假设您不能使用比较直观的名称Files.copy()。那就好多了。

代码语言:javascript
复制
private void copyFile(File in, File out) {
    try {
        Files.copy(in.toPath(), out.toPath());
    } catch (IOException e) {
        e.printStackTrace(System.err);
    }
}
票数 5
EN

Code Review用户

发布于 2020-11-13 14:45:03

关于异常处理的注释。

异常是指与方法的调用方通信该方法未完成其工作。

在您的情况下,工作是复制一个文件。如果在此过程中发生异常,则很可能out文件尚未成为in文件的有效副本。你必须通知你的来电者那次失败。相反,通知用户是错误的,原因有二:

  • 如果未收到异常,则调用方方法假设所有操作都已完成,以后可能会读取该文件副本,并得到一个错误或不完整的数据,很难调试。
  • 由于您的方法的工作与用户界面无关,所以与用户交谈是很奇怪的。一些顶级活动必须接收异常,并且应该知道如何通知用户。

因此,最好只声明可能发生的异常,并让调用堆栈上的某些实例决定如何处理该异常。您的方法应该将其失败报告给调用方,并让他处理:

代码语言:javascript
复制
private void copyFile(File in, File out) throws IOException {
    var buffer = new byte[10000];
    
    FileInputStream dis = new FileInputStream(in);
    FileOutputStream dos = new FileOutputStream(out);
    int count;
    do {
        count = dis.read(buffer);
        if (count != -1)
            dos.write(buffer, 0, count);
    } while (count != -1);
    dis.close();
    dos.close();
}
票数 2
EN

Code Review用户

发布于 2020-12-02 14:08:39

很少有事情需要研究

  1. 应该有一个最后的块,其中所有的流都应该被关闭,这将确保即使在循环异常的情况下也不会有任何打开的流。

https://www.javatpoint.com/finally-block-in-exception-handling

  1. 用于打印异常的函数需要更改为System.err或e.printstacktrace()。
票数 0
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/252025

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档