You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Renci.sshnet开发C# SFTP下载接口:如何判断文件是否正在上传

解决SFTP上传中文件无法下载的判断问题

嘿,这个场景我之前做项目时碰到过,给你几个靠谱的解决方案,都是基于Renci.SshNet能实现的:

方案1:检查文件大小是否稳定

上传中的文件大小肯定是持续增长的,我们可以间隔一段时间两次获取文件大小,如果连续两次大小一致,基本就能确定上传完成了。这是最通用的方法,不依赖服务器的特殊配置。

示例代码:

private bool IsFileUploadComplete(SftpClient sftpClient, string remoteFile, int checkIntervalMs = 2000, int maxChecks = 3)
{
    long lastSize = -1;
    int stableCount = 0;

    for (int i = 0; i < maxChecks; i++)
    {
        var fileAttr = sftpClient.GetAttributes(remoteFile);
        long currentSize = fileAttr.Size;

        if (currentSize == lastSize)
        {
            stableCount++;
            if (stableCount >= 2)
            {
                return true;
            }
        }
        else
        {
            stableCount = 0;
            lastSize = currentSize;
        }

        System.Threading.Thread.Sleep(checkIntervalMs);
    }

    return false;
}

调用的时候,先判断这个方法返回true,再执行下载操作就行。

方案2:利用临时文件命名规则

很多客户端上传文件时,会先传一个带临时后缀的文件(比如file.txt.tmp、file.txt.part),上传完成后再重命名为正式文件名。这种情况下,你只需要只下载正式命名的文件,忽略带临时后缀的文件就行。

如果是你自己控制上传端,那可以约定好临时后缀;如果是第三方客户端,你可以先观察一下他们的上传规律,再针对性处理。

方案3:检查文件的修改时间

和大小判断逻辑类似,上传中的文件修改时间会频繁变动。我们可以间隔获取文件的LastWriteTime,如果连续两次一致,说明文件没有被写入,上传完成。

示例代码片段:

var firstAttr = sftpClient.GetAttributes(remoteFile);
System.Threading.Thread.Sleep(2000);
var secondAttr = sftpClient.GetAttributes(remoteFile);

if (firstAttr.LastWriteTime == secondAttr.LastWriteTime)
{
    // 文件已稳定,可以下载
}

备选方案:捕获下载异常兜底

如果上面的方法都不适用,那可以在下载时捕获Renci的SftpException,根据异常信息判断是否是文件被占用的情况,然后提示用户重试。不过这个方法依赖服务器返回的异常信息,不同服务器可能不一样,属于兜底方案。

示例代码:

try
{
    using (var localFile = File.Create(localFilePath))
    {
        sftpClient.DownloadFile(remoteFilePath, localFile);
    }
}
catch (SftpException ex)
{
    // 这里的异常信息需要根据你的服务器返回调整
    if (ex.Message.IndexOf("locked", StringComparison.OrdinalIgnoreCase) >= 0 || 
        ex.Message.IndexOf("in use", StringComparison.OrdinalIgnoreCase) >= 0)
    {
        Console.WriteLine("文件正在上传中,请稍后再试!");
    }
    else
    {
        // 其他异常正常抛出
        throw;
    }
}

注意事项

  • 方案1和3的间隔时间不要设太短,避免因为网络延迟误判;
  • 如果服务器支持文件锁定或者能执行shell命令(比如Linux的lsof),也可以尝试远程执行命令判断文件是否被占用,但这种方法局限性大,需要服务器开放shell权限,不推荐作为首选。

内容的提问来源于stack exchange,提问作者Mohit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:51:33