【问题标题】:Java: Can't delete local file after jsch.putJava:在 jsch.put 之后无法删除本地文件
【发布时间】:2014-05-30 16:18:27
【问题描述】:

在将文件移动到 ftp 站点后,我在删除文件时遇到了一些问题。在之前的过程中,我正在生成文件并将它们放在一个文件夹中。此过程应将每个文件上传到 ftp 站点,然后删除本地副本。由于我无法确定删除失败的原因,但我没有收到任何类型的错误消息或异常。最初我在 ftp.put() 之后立即调用了 file.delete() ,但我将它移到了当前位置,认为该文件可能被 jsch 锁定并将调用放在那里可以修复它。情况似乎并非如此。理想情况下,电话会回到那里,所以我不需要两个“for”循环。

如果您也碰巧知道为什么覆盖不起作用,那将是一个奖励。当我查看通过实际 FTP 程序上传的文件时,权限是 rw-rw-rw。服务器上的现有文件已通过此过程上传。

代码如下:

    JSch jsch = new JSch();
    Session session = null;
    try {
        File sourceDir = new File(certSourceFolder);
        if (!sourceDir.exists()) {
            sourceDir.mkdirs();
        }

        session = jsch.getSession(ftpUser, ftpServer, 22);
        session.setConfig("StrictHostKeyChecking", "no");
        session.setPassword(ftpPassword);
        session.connect();

        Channel channel = session.openChannel("sftp");
        channel.connect();
        ChannelSftp ftp = (ChannelSftp) channel;

        ftp.cd(certDestFolder);

        for (File file : sourceDir.listFiles()) {
            if (file.isFile()) {
                try {
                    ftp.put(new FileInputStream(file), file.getName(), ChannelSftp.OVERWRITE);
                } catch (SftpException ex) {
                    //The overwrite is not working. For now I'm just going to trap the error and move on. This really shouldn't happen ever since I delete the file once uploaded.
                    if (!ex.getMessage().equalsIgnoreCase("Permission denied"))
                        throw ex;
                }
            }
        }

        ftp.exit();
        session.disconnect();

        //TODO: this is not working. figure out why. If possible get rid of this and move the file.delete up to after ftp.put
        for (File file : sourceDir.listFiles()) {
            if (file.isFile()) {
                file.delete();
            }
        }
    } catch (Exception e) {
        DefaultLogger.logException("CertificateFileTransfer", e);
    }
}

【问题讨论】:

    标签: java file-io ftp jsch


    【解决方案1】:

    使用后必须关闭文件,否则会被当前使用的组件锁定。

    改变这一行:

     ftp.put(new FileInputStream(file)...
    

    finally 子句在流上调用close 以确保文件在任何情况下(好或异常)的释放:

    finally{
      fileInput.close();
    }
    

    回顾一下:

    FileInputStream fileInput = null;
    try {
        fileInput = new FileInputStream(file);
        ftp.put(fileInput, file.getName(), ChannelSftp.OVERWRITE);
    } catch (SftpException ex) {
        if (!ex.getMessage().equalsIgnoreCase("Permission denied"))
            throw ex;
    }
    finally{
     if(fileInput != null){
       fileInput.close();
     }
    }
    

    来自文档:

    close() 关闭此文件输入流并释放任何系统 与流相关的资源。

    【讨论】:

      猜你喜欢
      • 2016-08-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-27
      • 1970-01-01
      • 2022-01-22
      • 2021-02-23
      • 1970-01-01
      相关资源
      最近更新 更多