繁体   English   中英

无法在 ubuntu 18.04 中使用 apache commons vfs for vsftpd 重命名文件

[英]Cannot rename file using apache commons vfs for vsftpd in ubuntu 18.04

I am trying to rename the file in vsftpd server using apache commons vfs, moveTo function is working fine in local system OS (Kubuntu 19.04) and VSFTPD server but when I try to rename the file in a test environment which has ubuntu 18.04 I am not能够重命名我遇到异常的文件。

使用此代码:

    public static boolean move(String hostName, String username, String password, String remoteSrcFilePath,
        String remoteDestFilePath, byte [] data) {

    FileObject remoteFile = null;
    FileObject remoteDestFile = null;
    boolean result = false;

    try (StandardFileSystemManager manager = new StandardFileSystemManager()){
        manager.init();

        // Create remote object
        remoteFile = manager.resolveFile(
                createConnectionString(hostName, username, password, remoteSrcFilePath), createDefaultOptions());
        remoteDestFile = manager.resolveFile(
                createConnectionString(hostName, username, password, remoteDestFilePath), createDefaultOptions());

        if (!remoteDestFile.exists() && remoteFile.exists()) {
            remoteFile.moveTo(remoteDestFile);
            if(null != data)
                writeData(remoteDestFile, data);
            result =  true;
        }else {
            throw new DataIntegrityViolationException("Destination path already exists");
        }
    } catch (IOException e) {
        logger.error("Error while renaming/moving file",e);
    }  finally {
        try {
            if(null != remoteDestFile)
                remoteDestFile.close();

            if(null != remoteFile)
                remoteFile.close();

        } catch (FileSystemException e) {
            logger.warn("error while closing fileobject "+e.getMessage());
        }
    }
    return result;
}

    public static FileSystemOptions createDefaultOptions() throws FileSystemException {
    // Create SFTP options
    FileSystemOptions opts = new FileSystemOptions();

    // SSH Key checking
    SftpFileSystemConfigBuilder.getInstance().setStrictHostKeyChecking(opts, "no");

    /*
     * Using the following line will cause VFS to choose File System's Root as VFS's
     * root. If I wanted to use User's home as VFS's root then set 2nd method
     * parameter to "true"
     */
    // Root directory set to user home
    SftpFileSystemConfigBuilder.getInstance().setUserDirIsRoot(opts, true);

    // Timeout is count by Milliseconds
    SftpFileSystemConfigBuilder.getInstance().setConnectTimeoutMillis(opts, 10000);

    return opts;
    }
}

我有这个例外

org.apache.commons.vfs2.FileSystemException: Could not determine if file "sftp://ftpuser:***@ip_address/home/ftpuser/ftp/1/Documents/test1/test2" is writeable

请注意,上面的代码在本地运行良好。

如果您遵循apache commons vfs for moveTo() 的源代码,您会发现:

if (canRenameTo(destFile)) {            //src and dest have the same FS
  if (!getParent().isWriteable()) {     // <-- it could throw the same exception here
    throw new FileSystemException("vfs.provider/rename-parent-read-only.error", getName(),
                    getParent().getName());
  }
} else {
  if (!isWriteable()) {    // <---- it throws inside here (IMO) rather than returning false 
    throw new FileSystemException("vfs.provider/rename-read-only.error", getName());
  }
}

...,您会发现moveTo()将抛出您看到的异常,如果目标文件不可写但以一种灾难性的方式,例如isWriteable(file)在其主体内抛出异常而不是返回false

我的第一个电话是验证sftpd 进程ftp 用户是否可以写入您希望将文件移动到的目录。

@diginoise我一直尝试使用apache commons vfs,但这不起作用,仅用于重命名我切换到Jsch 下面是本地和远程服务器的工作代码

private static ChannelSftp setupJsch(String hostName, String username, String password) throws JSchException  {
    JSch jsch = new JSch();
    JSch.setConfig("StrictHostKeyChecking", "no");
    jsch.setKnownHosts("/home/"+username+"/.ssh/known_hosts");
    Session jschSession = jsch.getSession(username, hostName);
    jschSession.setPassword(password);
    jschSession.connect();
    return (ChannelSftp) jschSession.openChannel("sftp");
}

public static boolean renameFile(String hostName, String username, String password, String remoteSrcFilePath,
        String remoteDestFilePath) {

    boolean result = false;

    ChannelSftp channelSftp = null;
    try {

        channelSftp = setupJsch(hostName,username,password);
        channelSftp.connect();
        channelSftp.rename(remoteSrcFilePath, remoteDestFilePath);
        result = true;
    }catch(JSchException | SftpException  e) {
        logger.error("Error while renaming file sftp ",e);
    }finally {
        sftpCleanUp(channelSftp);
    }

    return result;  
}

private static void sftpCleanUp(ChannelSftp channelSftp) {
    if(null != channelSftp) {
        channelSftp.disconnect();
        channelSftp.exit();
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM