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

使用NSURLSession通过FTP加载文件失败问题求助

NSURLSession FTP下载失败:"the requested url is not found on this server" 解决方法

核心问题分析

你的代码里有几个关键错误,直接导致了服务器返回路径不存在的错误:

  1. FTP URL格式错误
    你写的URL中,IP地址后面多了一个多余的冒号(比如ftp://121.122.0.200:/usr/path/file.json),正确的FTP URL格式是ftp://user:pwd@host/path,不指定端口时host后不需要冒号。这个错误会让服务器解析出错误的文件路径。

  2. 方法1逻辑完全颠倒
    方法1用了NSURLSessionUploadTask和PUT请求,这是上传文件的逻辑,和你要实现的下载功能完全反向。

  3. 方法2凭证存储未初始化
    方法2里的cred_storage是未初始化的空对象,调用setCredential不会生效,必须使用系统共享的凭证存储实例。


修正后的下载实现(两种可选方式)

方式1:URL中直接携带凭证(简单直接)

// 修正URL:去掉IP后的冒号,正确拼接用户名密码
NSURL *ftpURL = [NSURL URLWithString:@"ftp://user:pwd@121.122.0.200/usr/path/file.json"];

// 配置会话
NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
sessionConfig.allowsCellularAccess = YES;

// 创建带代理的会话(需实现下载回调)
NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfig delegate:self delegateQueue:nil];

// 启动下载任务
NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithURL:ftpURL];
[downloadTask resume];

方式2:使用凭证存储管理(适合分离凭证的场景)

NSURL *ftpURL = [NSURL URLWithString:@"ftp://121.122.0.200/usr/path/file.json"];
NSString *username = @"xxxx";
NSString *password = @"xxxx";

// 初始化保护空间
NSURLProtectionSpace *protectionSpace = [[NSURLProtectionSpace alloc] initWithHost:ftpURL.host 
                                                                              port:[ftpURL.port integerValue] 
                                                                          protocol:ftpURL.scheme 
                                                                             realm:nil 
                                                         authenticationMethod:NSURLAuthenticationMethodDefault];

// 创建会话凭证
NSURLCredential *credential = [NSURLCredential credentialWithUser:username 
                                                          password:password 
                                                       persistence:NSURLCredentialPersistenceForSession];

// 使用系统共享的凭证存储
NSURLCredentialStorage *credStorage = [NSURLCredentialStorage sharedCredentialStorage];
[credStorage setCredential:credential forProtectionSpace:protectionSpace];

// 配置并启动会话
NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
sessionConfig.URLCredentialStorage = credStorage;
sessionConfig.allowsCellularAccess = YES;

NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfig delegate:self delegateQueue:nil];
NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithURL:ftpURL];
[downloadTask resume];

必备的代理回调实现

记得实现NSURLSessionDownloadDelegate的方法来处理下载结果:

// 下载完成后处理临时文件
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location {
    NSString *docsDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
    NSURL *destURL = [NSURL fileURLWithPath:[docsDir stringByAppendingPathComponent:@"file.json"]];
    
    NSError *error;
    [[NSFileManager defaultManager] moveItemAtURL:location toURL:destURL error:&error];
    if (error) {
        NSLog(@"文件保存失败:%@", error.localizedDescription);
    }
}

// 处理下载错误
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
    if (error) {
        NSLog(@"下载出错:%@", error.localizedDescription);
    }
}

补充说明

SCP基于SSH协议,和FTP是完全不同的协议,服务器同时支持两种协议不代表URL格式通用,必须严格遵循FTP的URL规范。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 16:15:32