网络文件下载(提供多种下载方式)

2024-03-05 14:10

本文主要是介绍网络文件下载(提供多种下载方式),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

(1)使用 NSURLConnection 直接方式

(2)使用 NSURLConnection 代理方式

(3)使用 NSURLSession 直接方式

(4)使用 NSURLSession 代理方式

(5)使用 AFNetworking 方式

 

附加功能:

(1)使用 AFNetworking 中的 AFNetworkReachabilityManager 来检查网络情况:

  • AFNetworkReachabilityStatusReachableViaWiFi:Wi-Fi 网络下

  • AFNetworkReachabilityStatusReachableViaWWAN:2G/3G/4G 蜂窝移动网络下

  • AFNetworkReachabilityStatusNotReachable:未连接网络

 

(2)使用 AFNetworking 中的 AFNetworkActivityIndicatorManager 来启动网络活动指示器:

1 #import "AFNetworkActivityIndicatorManager.h"
2 
3 //启动网络活动指示器;会根据网络交互情况,实时显示或隐藏网络活动指示器;他通过「通知与消息机制」来实现 [UIApplication sharedApplication].networkActivityIndicatorVisible 的控制
4 [AFNetworkActivityIndicatorManager sharedManager].enabled = YES;

 

效果如下:

 

 

 

ViewController.h

1 #import <UIKit/UIKit.h>
2 
3 @interface ViewController : UITableViewController
4 @property (copy, nonatomic) NSArray *arrSampleName;
5 
6 - (instancetype)initWithSampleNameArray:(NSArray *)arrSampleName;
7 
8 @end 

ViewController.m

 1 #import "ViewController.h"2 #import "NSURLConnectionViewController.h"3 #import "NSURLConnectionDelegateViewController.h"4 #import "NSURLSessionViewController.h"5 #import "NSURLSessionDelegateViewController.h"6 #import "AFNetworkingViewController.h"7 8 @interface ViewController ()9 - (void)layoutUI;
10 @end
11 
12 @implementation ViewController
13 - (void)viewDidLoad {
14     [super viewDidLoad];
15     
16     [self layoutUI];
17 }
18 
19 - (void)didReceiveMemoryWarning {
20     [super didReceiveMemoryWarning];
21     // Dispose of any resources that can be recreated.
22 }
23 
24 - (instancetype)initWithSampleNameArray:(NSArray *)arrSampleName {
25     if (self = [super initWithStyle:UITableViewStyleGrouped]) {
26         self.navigationItem.title = @"多种方式实现文件下载功能";
27         self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"返回" style:UIBarButtonItemStylePlain target:nil action:nil];
28         
29         _arrSampleName = arrSampleName;
30     }
31     return self;
32 }
33 
34 - (void)layoutUI {
35 }
36 
37 #pragma mark - UITableViewController相关方法重写
38 - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
39     return 0.1;
40 }
41 
42 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
43     return 1;
44 }
45 
46 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
47     return [_arrSampleName count];
48 }
49 
50 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
51     static NSString *cellIdentifier = @"cell";
52     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
53     if (!cell) {
54         cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
55     }
56     cell.textLabel.text = _arrSampleName[indexPath.row];
57     return cell;
58 }
59 
60 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
61     switch (indexPath.row) {
62         case 0: {
63             NSURLConnectionViewController *connectionVC = [NSURLConnectionViewController new];
64             [self.navigationController pushViewController:connectionVC animated:YES];
65             break;
66         }
67         case 1: {
68             NSURLConnectionDelegateViewController *connectionDelegateVC = [NSURLConnectionDelegateViewController new];
69             [self.navigationController pushViewController:connectionDelegateVC animated:YES];
70             break;
71         }
72         case 2: {
73             NSURLSessionViewController *sessionVC = [NSURLSessionViewController new];
74             [self.navigationController pushViewController:sessionVC animated:YES];
75             break;
76         }
77         case 3: {
78             NSURLSessionDelegateViewController *sessionDelegateVC = [NSURLSessionDelegateViewController new];
79             [self.navigationController pushViewController:sessionDelegateVC animated:YES];
80             break;
81         }
82         case 4: {
83             AFNetworkingViewController *networkingVC = [AFNetworkingViewController new];
84             [self.navigationController pushViewController:networkingVC animated:YES];
85             break;
86         }
87         default:
88             break;
89     }
90 }
91 
92 @end 

PrefixHeader.pch

1 #define kFileURLStr @"http://files.cnblogs.com/files/huangjianwu/metro_demo使用Highcharts实现图表展示.zip"
2 
3 #define kTitleOfNSURLConnection @"使用 NSURLConnection 直接方式"
4 #define kTitleOfNSURLConnectionDelegate @"使用 NSURLConnection 代理方式"
5 #define kTitleOfNSURLSession @"使用 NSURLSession 直接方式"
6 #define kTitleOfNSURLSessionDelegate @"使用 NSURLSession 代理方式"
7 #define kTitleOfAFNetworking @"使用 AFNetworking 方式"
8 
9 #define kApplication [UIApplication sharedApplication] 

UIButton+BeautifulButton.h

 1 #import <UIKit/UIKit.h>2 3 @interface UIButton (BeautifulButton)4 /**5  *  根据按钮文字颜色,返回对应文字颜色的圆角按钮6  *7  *  @param tintColor 按钮文字颜色;nil 的话就为深灰色8  */9 - (void)beautifulButton:(UIColor *)tintColor;
10 
11 @end 

UIButton+BeautifulButton.m

 1 #import "UIButton+BeautifulButton.h"2 3 @implementation UIButton (BeautifulButton)4 5 - (void)beautifulButton:(UIColor *)tintColor {6     self.tintColor = tintColor ?: [UIColor darkGrayColor];7     self.layer.masksToBounds = YES;8     self.layer.cornerRadius = 10.0;9     self.layer.borderColor = [UIColor grayColor].CGColor;
10     self.layer.borderWidth = 1.0;
11 }
12 
13 @end 

NSURLConnectionViewController.h

1 #import <UIKit/UIKit.h>
2 
3 @interface NSURLConnectionViewController : UIViewController
4 @property (strong, nonatomic) IBOutlet UILabel *lblFileName;
5 @property (strong, nonatomic) IBOutlet UILabel *lblMessage;
6 @property (strong, nonatomic) IBOutlet UIButton *btnDownloadFile;
7 
8 @end 

NSURLConnectionViewController.m

 1 #import "NSURLConnectionViewController.h"2 #import "UIButton+BeautifulButton.h"3 4 @interface NSURLConnectionViewController ()5 - (void)layoutUI;6 - (void)saveDataToDisk:(NSData *)data;7 @end8 9 @implementation NSURLConnectionViewController
10 
11 - (void)viewDidLoad {
12     [super viewDidLoad];
13     
14     [self layoutUI];
15 }
16 
17 - (void)didReceiveMemoryWarning {
18     [super didReceiveMemoryWarning];
19     // Dispose of any resources that can be recreated.
20 }
21 
22 - (void)layoutUI {
23     self.navigationItem.title = kTitleOfNSURLConnection;
24     self.view.backgroundColor = [UIColor colorWithWhite:0.95 alpha:1.000];
25     
26     [_btnDownloadFile beautifulButton:nil];
27 }
28 
29 - (void)saveDataToDisk:(NSData *)data {
30     //数据接收完保存文件;注意苹果官方要求:下载数据只能保存在缓存目录(/Library/Caches)
31     NSString *savePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
32     savePath = [savePath stringByAppendingPathComponent:_lblFileName.text];
33     [data writeToFile:savePath atomically:YES]; //writeToFile: 方法:如果 savePath 文件存在,他会执行覆盖
34 }
35 
36 - (IBAction)downloadFile:(id)sender {
37     _lblMessage.text = @"下载中...";
38     
39     NSString *fileURLStr = kFileURLStr;
40     //编码操作;对应的解码操作是用 stringByRemovingPercentEncoding 方法
41     fileURLStr = [fileURLStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
42     NSURL *fileURL = [NSURL URLWithString:fileURLStr];
43     
44     //创建请求
45     NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:fileURL];
46     
47     //创建连接;Apple 提供的处理一般请求的两种方法,他们不需要进行一系列的 NSURLConnectionDataDelegate 委托协议方法操作,简洁直观
48     //方法一:发送一个同步请求;不建议使用,因为当前线程是主线程的话,会造成线程阻塞,一般比较少用
49 //    NSURLResponse *response;
50 //    NSError *connectionError;
51 //    NSData *data = [NSURLConnection sendSynchronousRequest:request
52 //                                         returningResponse:&response
53 //                                                     error:&connectionError];
54 //    if (!connectionError) {
55 //        [self saveDataToDisk:data];
56 //        NSLog(@"保存成功");
57 //        
58 //        _lblMessage.text = @"下载完成";
59 //    } else {
60 //        NSLog(@"下载失败,错误信息:%@", connectionError.localizedDescription);
61 //        
62 //        _lblMessage.text = @"下载失败";
63 //    }
64     
65     //方法二:发送一个异步请求
66     [NSURLConnection sendAsynchronousRequest:request
67                                        queue:[NSOperationQueue mainQueue]
68                            completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
69                                if (!connectionError) {
70                                    [self saveDataToDisk:data];
71                                    NSLog(@"保存成功");
72                                    
73                                    _lblMessage.text = @"下载完成";
74                                    
75                                } else {
76                                    NSLog(@"下载失败,错误信息:%@", connectionError.localizedDescription);
77                                    
78                                    _lblMessage.text = @"下载失败";
79                                }
80                            }];
81 }
82 
83 @end 

NSURLConnectionViewController.xib

  View Code 

NSURLConnectionDelegateViewController.h

 1 #import <UIKit/UIKit.h>2 3 @interface NSURLConnectionDelegateViewController : UIViewController4 @property (strong, nonatomic) NSMutableData *mDataReceive;5 @property (assign, nonatomic) NSUInteger totalDataLength;6 7 @property (strong, nonatomic) IBOutlet UILabel *lblFileName;8 @property (strong, nonatomic) IBOutlet UIProgressView *progVDownloadFile;9 @property (strong, nonatomic) IBOutlet UILabel *lblMessage;
10 @property (strong, nonatomic) IBOutlet UIButton *btnDownloadFile;
11 
12 @end 

NSURLConnectionDelegateViewController.m

  1 #import "NSURLConnectionDelegateViewController.h"2 #import "UIButton+BeautifulButton.h"3 4 @interface NSURLConnectionDelegateViewController ()5 - (void)layoutUI;6 - (BOOL)isExistCacheInMemory:(NSURLRequest *)request;7 - (void)updateProgress;8 @end9 10 @implementation NSURLConnectionDelegateViewController11 12 - (void)viewDidLoad {13     [super viewDidLoad];14     15     [self layoutUI];16 }17 18 - (void)didReceiveMemoryWarning {19     [super didReceiveMemoryWarning];20     // Dispose of any resources that can be recreated.21 }22 23 - (void)layoutUI {24     self.navigationItem.title = kTitleOfNSURLConnectionDelegate;25     self.view.backgroundColor = [UIColor colorWithWhite:0.95 alpha:1.000];26     27     [_btnDownloadFile beautifulButton:nil];28 }29 30 - (BOOL)isExistCacheInMemory:(NSURLRequest *)request {31     BOOL isExistCache = NO;32     NSURLCache *cache = [NSURLCache sharedURLCache];33     [cache setMemoryCapacity:1024 * 1024]; //1M34     35     NSCachedURLResponse *response = [cache cachedResponseForRequest:request];36     if (response != nil) {37         NSLog(@"内存中存在对应请求的响应缓存");38         isExistCache = YES;39     }40     return isExistCache;41 }42 43 - (void)updateProgress {44     NSUInteger receiveDataLength = _mDataReceive.length;45     if (receiveDataLength == _totalDataLength) {46         _lblMessage.text = @"下载完成";47         kApplication.networkActivityIndicatorVisible = NO;48     } else {49         _lblMessage.text = @"下载中...";50         kApplication.networkActivityIndicatorVisible = YES;51         _progVDownloadFile.progress = (float)receiveDataLength / _totalDataLength;52     }53 }54 55 - (IBAction)downloadFile:(id)sender {56     /*57      此例子更多的是希望大家了解代理方法接收响应数据的过程,实际开发中也不可能使用这种方法进行文件下载。这种下载有个致命的问题:无法进行大文件下载。因为代理方法在接收数据时虽然表面看起来是每次读取一部分响应数据,事实上它只有一次请求并且也只接收了一次服务器响应,只是当响应数据较大时系统会重复调用数据接收方法,每次将已读取的数据拿出一部分交给数据接收方法而已。在这个过程中其实早已经将响应数据全部拿到,只是分批交给开发者而已。这样一来对于几个G的文件如果进行下载,那么不用说是真机下载了,就算是模拟器恐怕也是不现实的。58      实际开发文件下载的时候不管是通过代理方法还是静态方法执行请求和响应,我们都会分批请求数据,而不是一次性请求数据。假设一个文件有1G,那么只要每次请求1M的数据,请求1024次也就下载完了。那么如何让服务器每次只返回1M的数据呢?59      在网络开发中可以在请求的头文件中设置一个Range信息,它代表请求数据的大小。通过这个字段配合服务器端可以精确的控制每次服务器响应的数据范围。例如指定bytes=0-1023,然后在服务器端解析Range信息,返回该文件的0到1023之间的数据的数据即可(共1024Byte)。这样,只要在每次发送请求控制这个头文件信息就可以做到分批请求。60      当然,为了让整个数据保持完整,每次请求的数据都需要逐步追加直到整个文件请求完成。但是如何知道整个文件的大小?其实在此例子通过头文件信息获取整个文件大小,他请求整个数据,这样做对分段下载就没有任何意义了。所幸在WEB开发中我们还有另一种请求方法“HEAD”,通过这种请求服务器只会响应头信息,其他数据不会返回给客户端,这样一来整个数据的大小也就可以得到了。61      */62     63     64     NSString *fileURLStr = kFileURLStr;65     //编码操作;对应的解码操作是用 stringByRemovingPercentEncoding 方法66     fileURLStr = [fileURLStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];67     NSURL *fileURL = [NSURL URLWithString:fileURLStr];68     69     /*创建请求70      cachePolicy:缓存策略71      1、NSURLRequestUseProtocolCachePolicy 协议缓存,根据 response 中的 Cache-Control 字段判断缓存是否有效,如果缓存有效则使用缓存数据否则重新从服务器请求72      2、NSURLRequestReloadIgnoringLocalCacheData 不使用缓存,直接请求新数据73      3、NSURLRequestReloadIgnoringCacheData 等同于 NSURLRequestReloadIgnoringLocalCacheData74      4、NSURLRequestReturnCacheDataElseLoad 直接使用缓存数据不管是否有效,没有缓存则重新请求75      5、NSURLRequestReturnCacheDataDontLoad 直接使用缓存数据不管是否有效,没有缓存数据则失败76      77      timeoutInterval:超时时间设置(默认60s)78      */79     NSURLRequest *request = [[NSURLRequest alloc] initWithURL:fileURL80                                                   cachePolicy:NSURLRequestUseProtocolCachePolicy81                                               timeoutInterval:60.0];82     if ([self isExistCacheInMemory:request]) {83         request = [[NSURLRequest alloc] initWithURL:fileURL84                                         cachePolicy:NSURLRequestReturnCacheDataDontLoad85                                     timeoutInterval:60.0];86     }87     88     //创建连接,异步操作89     NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request90                                                                   delegate:self];91     [connection start]; //启动连接92 }93 94 #pragma mark - NSURLConnectionDataDelegate95 - (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)response {96     NSLog(@"即将发送请求");97     98     return request;99 }
100 
101 - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
102     NSLog(@"已经接收到响应");
103     
104     _mDataReceive = [NSMutableData new];
105     _progVDownloadFile.progress = 0.0;
106     
107     //通过响应头中的 Content-Length 获取到整个响应的总长度
108     /*
109      {
110      "Accept-Ranges" = bytes;
111      "Cache-Control" = "max-age=7776000";
112      "Content-Length" = 592441;
113      "Content-Type" = "application/x-zip-compressed";
114      Date = "Wed, 02 Sep 2015 13:17:01 GMT";
115      Etag = "\"d8f617371f9cd01:0\"";
116      "Last-Modified" = "Mon, 01 Jun 2015 03:58:27 GMT";
117      Server = "Microsoft-IIS/7.5";
118      "X-Powered-By" = "ASP.NET";
119      }
120      */
121     NSDictionary *dicHeaderField = [(NSHTTPURLResponse *)response allHeaderFields];
122     _totalDataLength = [[dicHeaderField objectForKey:@"Content-Length"] integerValue];
123 }
124 
125 - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
126     NSLog(@"已经接收到响应数据,数据长度为%lu字节...", (unsigned long)[data length]);
127     
128     [_mDataReceive appendData:data]; //连续接收数据
129     [self updateProgress]; //连续更新进度条
130 }
131 
132 - (void)connectionDidFinishLoading:(NSURLConnection *)connection {
133     NSLog(@"已经接收完所有响应数据");
134     
135     NSString *savePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
136     savePath = [savePath stringByAppendingPathComponent:_lblFileName.text];
137     [_mDataReceive writeToFile:savePath atomically:YES];
138 }
139 
140 - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
141     //如果连接超时或者连接地址错误可能就会报错
142     NSLog(@"连接错误,错误信息:%@", error.localizedDescription);
143     
144     _lblMessage.text = @"连接错误";
145 }
146 
147 @end

NSURLConnectionDelegateViewController.xib

  View Code

NSURLSessionViewController.h

1 #import <UIKit/UIKit.h>
2 
3 @interface NSURLSessionViewController : UIViewController
4 @property (strong, nonatomic) IBOutlet UILabel *lblFileName;
5 @property (strong, nonatomic) IBOutlet UILabel *lblMessage;
6 @property (strong, nonatomic) IBOutlet UIButton *btnDownloadFile;
7 
8 @end 

NSURLSessionViewController.m

  1 #import "NSURLSessionViewController.h"2 #import "UIButton+BeautifulButton.h"3 4 @interface NSURLSessionViewController ()5 - (void)layoutUI;6 @end7 8 @implementation NSURLSessionViewController9 10 - (void)viewDidLoad {11     [super viewDidLoad];12     13     [self layoutUI];14 }15 16 - (void)didReceiveMemoryWarning {17     [super didReceiveMemoryWarning];18     // Dispose of any resources that can be recreated.19 }20 21 - (void)layoutUI {22     self.navigationItem.title = kTitleOfNSURLSession;23     self.view.backgroundColor = [UIColor colorWithWhite:0.95 alpha:1.000];24     25     [_btnDownloadFile beautifulButton:nil];26 }27 28 - (IBAction)downloadFile:(id)sender {29     _lblMessage.text = @"下载中...";30     31     NSString *fileURLStr = kFileURLStr;32     //编码操作;对应的解码操作是用 stringByRemovingPercentEncoding 方法33     fileURLStr = [fileURLStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];34     NSURL *fileURL = [NSURL URLWithString:fileURLStr];35     36     //创建请求37     NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:fileURL];38     39     //创建会话(这里使用了一个全局会话)40     NSURLSession *session = [NSURLSession sharedSession];41     42     //创建下载任务,并且启动他;在非主线程中执行43     NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithRequest:request completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {44         __block void (^updateUI)(); //声明用于主线程更新 UI 的代码块45         46         if (!error) {47             NSLog(@"下载后的临时保存路径:%@", location);48             49             NSString *savePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];50             savePath = [savePath stringByAppendingPathComponent:_lblFileName.text];51             NSURL *saveURL = [NSURL fileURLWithPath:savePath];52             NSError *saveError;53             NSFileManager *fileManager = [NSFileManager defaultManager];54             //判断是否存在旧的目标文件,如果存在就先移除;避免无法复制问题55             if ([fileManager fileExistsAtPath:savePath]) {56                 [fileManager removeItemAtPath:savePath error:&saveError];57                 if (saveError) {58                     NSLog(@"移除旧的目标文件失败,错误信息:%@", saveError.localizedDescription);59                     60                     updateUI = ^ {61                         _lblMessage.text = @"下载失败";62                     };63                 }64             }65             if (!saveError) {66                 //把源文件复制到目标文件,当目标文件存在时,会抛出一个错误到 error 参数指向的对象实例67                 //方法一(path 不能有 file:// 前缀)68                 //                [fileManager copyItemAtPath:[location path]69                 //                                     toPath:savePath70                 //                                      error:&saveError];71                 72                 //方法二73                 [fileManager copyItemAtURL:location74                                      toURL:saveURL75                                      error:&saveError];76                 77                 if (!saveError) {78                     NSLog(@"保存成功");79                     80                     updateUI = ^ {81                         _lblMessage.text = @"下载完成";82                     };83                 } else {84                     NSLog(@"保存失败,错误信息:%@", saveError.localizedDescription);85                     86                     updateUI = ^ {87                         _lblMessage.text = @"下载失败";88                     };89                 }90             }91             92         } else {93             NSLog(@"下载失败,错误信息:%@", error.localizedDescription);94             95             updateUI = ^ {96                 _lblMessage.text = @"下载失败";97             };98         }99         
100         dispatch_async(dispatch_get_main_queue(), updateUI); //使用主队列异步方式(主线程)执行更新 UI 的代码块
101     }];
102     [downloadTask resume]; //恢复线程,启动任务
103 }
104 
105 @end 

NSURLSessionViewController.xib

  View Code 

NSURLSessionDelegateViewController.h

 1 #import <UIKit/UIKit.h>2 3 @interface NSURLSessionDelegateViewController : UIViewController <NSURLSessionDownloadDelegate>4 @property (strong, nonatomic) NSURLSessionDownloadTask *downloadTask;5 6 @property (strong, nonatomic) IBOutlet UILabel *lblFileName;7 @property (strong, nonatomic) IBOutlet UIProgressView *progVDownloadFile;8 @property (strong, nonatomic) IBOutlet UILabel *lblMessage;9 @property (strong, nonatomic) IBOutlet UIButton *btnDownloadFile;
10 @property (strong, nonatomic) IBOutlet UIButton *btnCancel;
11 @property (strong, nonatomic) IBOutlet UIButton *btnSuspend;
12 @property (strong, nonatomic) IBOutlet UIButton *btnResume;
13 
14 @end 

NSURLSessionDelegateViewController.m

  1 #import "NSURLSessionDelegateViewController.h"2 #import "UIButton+BeautifulButton.h"3 4 @interface NSURLSessionDelegateViewController ()5 - (void)layoutUI;6 - (NSURLSession *)defaultSession;7 - (NSURLSession *)backgroundSession;8 - (void)updateProgress:(int64_t)receiveDataLength totalDataLength:(int64_t)totalDataLength;9 @end10 11 @implementation NSURLSessionDelegateViewController12 13 - (void)viewDidLoad {14     [super viewDidLoad];15     16     [self layoutUI];17 }18 19 - (void)didReceiveMemoryWarning {20     [super didReceiveMemoryWarning];21     // Dispose of any resources that can be recreated.22 }23 24 - (void)layoutUI {25     self.navigationItem.title = kTitleOfNSURLSessionDelegate;26     self.view.backgroundColor = [UIColor colorWithWhite:0.95 alpha:1.000];27     28     [_btnDownloadFile beautifulButton:nil];29     [_btnCancel beautifulButton:[UIColor redColor]];30     [_btnSuspend beautifulButton:[UIColor purpleColor]];31     [_btnResume beautifulButton:[UIColor orangeColor]];32 }33 34 - (NSURLSession *)defaultSession {35     /*36      NSURLSession 支持进程三种会话:37      1、defaultSessionConfiguration:进程内会话(默认会话),用硬盘来缓存数据。38      2、ephemeralSessionConfiguration:临时的进程内会话(内存),不会将 cookie、缓存储存到本地,只会放到内存中,当应用程序退出后数据也会消失。39      3、backgroundSessionConfiguration:后台会话,相比默认会话,该会话会在后台开启一个线程进行网络数据处理。40      */41 42     //创建会话配置「进程内会话」43     NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];44     sessionConfiguration.timeoutIntervalForRequest = 60.0; //请求超时时间;默认为60秒45     sessionConfiguration.allowsCellularAccess = YES; //是否允许蜂窝网络访问(2G/3G/4G)46     sessionConfiguration.HTTPMaximumConnectionsPerHost = 4; //限制每次最多连接数;在 iOS 中默认值为447     48     //创建会话49     NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration50                                                           delegate:self51                                                      delegateQueue:nil];52     return session;53 }54 55 - (NSURLSession *)backgroundSession {56     static NSURLSession *session;57     static dispatch_once_t onceToken;58     dispatch_once(&onceToken, ^{ //应用程序生命周期内,只执行一次;保证只有一个「后台会话」59         //创建会话配置「后台会话」60         NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"KMDownloadFile.NSURLSessionDelegateViewController"];61         sessionConfiguration.timeoutIntervalForRequest = 60.0; //请求超时时间;默认为60秒62         sessionConfiguration.allowsCellularAccess = YES; //是否允许蜂窝网络访问(2G/3G/4G)63         sessionConfiguration.HTTPMaximumConnectionsPerHost = 4; //限制每次最多连接数;在 iOS 中默认值为464         sessionConfiguration.discretionary = YES; //是否自动选择最佳网络访问,仅对「后台会话」有效65         66         //创建会话67         session = [NSURLSession sessionWithConfiguration:sessionConfiguration68                                                 delegate:self69                                            delegateQueue:nil];70     });71     return session;72 }73 74 - (void)updateProgress:(int64_t)receiveDataLength totalDataLength:(int64_t)totalDataLength; {75     dispatch_async(dispatch_get_main_queue(), ^{ //使用主队列异步方式(主线程)执行更新 UI 操作76         if (receiveDataLength == totalDataLength) {77             _lblMessage.text = @"下载完成";78             kApplication.networkActivityIndicatorVisible = NO;79         } else {80             _lblMessage.text = @"下载中...";81             kApplication.networkActivityIndicatorVisible = YES;82             _progVDownloadFile.progress = (float)receiveDataLength / totalDataLength;83         }84     });85 }86 87 - (IBAction)downloadFile:(id)sender {88     NSString *fileURLStr = kFileURLStr;89     //编码操作;对应的解码操作是用 stringByRemovingPercentEncoding 方法90     fileURLStr = [fileURLStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];91     NSURL *fileURL = [NSURL URLWithString:fileURLStr];92     93     //创建请求94     NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:fileURL];95     96     //创建会话「进程内会话」;如要用「后台会话」就使用自定义的[self backgroundSession] 方法97     NSURLSession *session = [self defaultSession];98     99     //创建下载任务,并且启动他;在非主线程中执行
100     _downloadTask = [session downloadTaskWithRequest:request];
101     [_downloadTask resume];
102     
103     /*
104      会话任务状态
105      typedef NS_ENUM(NSInteger, NSURLSessionTaskState) {
106      NSURLSessionTaskStateRunning = 0, //正在执行
107      NSURLSessionTaskStateSuspended = 1, //已挂起
108      NSURLSessionTaskStateCanceling = 2, //正在取消
109      NSURLSessionTaskStateCompleted = 3, //已完成
110      } NS_ENUM_AVAILABLE(NSURLSESSION_AVAILABLE, 7_0);
111      */
112 }
113 
114 - (IBAction)cancel:(id)sender {
115     [_downloadTask cancel];
116 }
117 
118 - (IBAction)suspend:(id)sender {
119     [_downloadTask suspend];
120     kApplication.networkActivityIndicatorVisible = NO;
121 }
122 
123 - (IBAction)resume:(id)sender {
124     [_downloadTask resume];
125 }
126 
127 #pragma mark - NSURLSessionDownloadDelegate
128 - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite {
129     NSLog(@"已经接收到响应数据,数据长度为%lld字节...", totalBytesWritten);
130     
131     [self updateProgress:totalBytesWritten totalDataLength:totalBytesExpectedToWrite];
132 }
133 
134 - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location {
135     //下载文件会临时保存,正常流程下系统最终会自动清除此临时文件;保存路径目录根据会话类型而有所不同:
136     //「进程内会话(默认会话)」和「临时的进程内会话(内存)」,路径目录为:/tmp,可以通过 NSTemporaryDirectory() 方法获取
137     //「后台会话」,路径目录为:/Library/Caches/com.apple.nsurlsessiond/Downloads/com.kenmu.KMDownloadFile
138     NSLog(@"已经接收完所有响应数据,下载后的临时保存路径:%@", location);
139     
140     __block void (^updateUI)(); //声明用于主线程更新 UI 的代码块
141     
142     NSString *savePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
143     savePath = [savePath stringByAppendingPathComponent:_lblFileName.text];
144     NSURL *saveURL = [NSURL fileURLWithPath:savePath];
145     NSError *saveError;
146     NSFileManager *fileManager = [NSFileManager defaultManager];
147     //判断是否存在旧的目标文件,如果存在就先移除;避免无法复制问题
148     if ([fileManager fileExistsAtPath:savePath]) {
149         [fileManager removeItemAtPath:savePath error:&saveError];
150         if (saveError) {
151             NSLog(@"移除旧的目标文件失败,错误信息:%@", saveError.localizedDescription);
152             
153             updateUI = ^ {
154                 _lblMessage.text = @"下载失败";
155             };
156         }
157     }
158     if (!saveError) {
159         //把源文件复制到目标文件,当目标文件存在时,会抛出一个错误到 error 参数指向的对象实例
160         //方法一(path 不能有 file:// 前缀)
161         //                [fileManager copyItemAtPath:[location path]
162         //                                     toPath:savePath
163         //                                      error:&saveError];
164         
165         //方法二
166         [fileManager copyItemAtURL:location
167                              toURL:saveURL
168                              error:&saveError];
169         
170         if (!saveError) {
171             NSLog(@"保存成功");
172             
173             updateUI = ^ {
174                 _lblMessage.text = @"下载完成";
175             };
176         } else {
177             NSLog(@"保存失败,错误信息:%@", saveError.localizedDescription);
178             
179             updateUI = ^ {
180                 _lblMessage.text = @"下载失败";
181             };
182         }
183     }
184     
185     dispatch_async(dispatch_get_main_queue(), updateUI); //使用主队列异步方式(主线程)执行更新 UI 的代码块
186 }
187 
188 - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
189     NSLog(@"无论下载成功还是失败,最终都会执行一次");
190     
191     if (error) {
192         NSString *desc = error.localizedDescription;
193         NSLog(@"下载失败,错误信息:%@", desc);
194         
195         dispatch_async(dispatch_get_main_queue(), ^{ //使用主队列异步方式(主线程)执行更新 UI 操作
196             _lblMessage.text = [desc isEqualToString:@"cancelled"] ? @"下载已取消" : @"下载失败";
197             kApplication.networkActivityIndicatorVisible = NO;
198             _progVDownloadFile.progress = 0.0;
199         });
200     }
201 }
202 
203 @end

NSURLSessionDelegateViewController.xib

  View Code 

AFNetworkingViewController.h

 1 #import <UIKit/UIKit.h>2 #import "MBProgressHUD.h"3 4 @interface AFNetworkingViewController : UIViewController5 @property (strong, nonatomic) MBProgressHUD *hud;6 7 @property (strong, nonatomic) IBOutlet UILabel *lblFileName;8 @property (strong, nonatomic) IBOutlet UILabel *lblMessage;9 @property (strong, nonatomic) IBOutlet UIButton *btnDownloadFileByConnection;
10 @property (strong, nonatomic) IBOutlet UIButton *btnDownloadFileBySession;
11 
12 @end 

AFNetworkingViewController.m

  1 #import "AFNetworkingViewController.h"2 #import "AFNetworking.h"3 #import "AFNetworkActivityIndicatorManager.h"4 #import "UIButton+BeautifulButton.h"5 6 @interface AFNetworkingViewController ()7 - (void)showAlert:(NSString *)msg;8 - (void)checkNetwork;9 - (void)layoutUI;10 - (NSMutableURLRequest *)downloadRequest;11 - (NSURL *)saveURL:(NSURLResponse *)response deleteExistFile:(BOOL)deleteExistFile;12 - (void)updateProgress:(int64_t)receiveDataLength totalDataLength:(int64_t)totalDataLength;13 @end14 15 @implementation AFNetworkingViewController16 17 - (void)viewDidLoad {18     [super viewDidLoad];19     20     [self layoutUI];21 }22 23 - (void)didReceiveMemoryWarning {24     [super didReceiveMemoryWarning];25     // Dispose of any resources that can be recreated.26 }27 28 - (void)showAlert:(NSString *)msg {29     UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"网络情况"30                                                     message:msg31                                                    delegate:self32                                           cancelButtonTitle:nil33                                           otherButtonTitles:@"确定", nil];34     [alert show];35 }36 37 - (void)checkNetwork {38     NSURL *baseURL = [NSURL URLWithString:@"http://www.baidu.com/"];39     AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:baseURL];40     41     NSOperationQueue *operationQueue = manager.operationQueue;42     [manager.reachabilityManager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {43         switch (status) {44             case AFNetworkReachabilityStatusReachableViaWiFi:45                 [self showAlert:@"Wi-Fi 网络下"];46                 [operationQueue setSuspended:NO];47                 break;48             case AFNetworkReachabilityStatusReachableViaWWAN:49                 [self showAlert:@"2G/3G/4G 蜂窝移动网络下"];50                 [operationQueue setSuspended:YES];51                 break;52             case AFNetworkReachabilityStatusNotReachable:53             default:54                 [self showAlert:@"未连接网络"];55                 [operationQueue setSuspended:YES];56                 break;57         }58     }];59     60     [manager.reachabilityManager startMonitoring];61 }62 63 - (void)layoutUI {64     self.navigationItem.title = kTitleOfAFNetworking;65     self.view.backgroundColor = [UIColor colorWithWhite:0.95 alpha:1.000];66     67     //条件表达式中,「?:」可以表示在条件不成立的情况,才使用后者赋值,否则使用用于条件判断的前者赋值68     //以下语句等同于:UIButton *btn = _btnDownloadFileByConnection ? _btnDownloadFileByConnection : [UIButton new];69     //在 .NET 中,相当于使用「??」;在 JavaScript 中,相当于使用「||」来实现这种类似的判断70     UIButton *btn = _btnDownloadFileByConnection ?: [UIButton new];71     [btn beautifulButton:nil];72     [_btnDownloadFileBySession beautifulButton:[UIColor orangeColor]];73     74     //进度效果75     _hud = [[MBProgressHUD alloc] initWithView:self.view];76     _hud.mode = MBProgressHUDModeDeterminate;77     _hud.labelText = @"下载中...";78     [_hud hide:YES];79     [self.view addSubview:_hud];80     81     //检查网络情况82     [self checkNetwork];83     84     //启动网络活动指示器;会根据网络交互情况,实时显示或隐藏网络活动指示器;他通过「通知与消息机制」来实现 [UIApplication sharedApplication].networkActivityIndicatorVisible 的控制85     [AFNetworkActivityIndicatorManager sharedManager].enabled = YES;86 }87 88 - (NSMutableURLRequest *)downloadRequest {89     NSString *fileURLStr = kFileURLStr;90     //编码操作;对应的解码操作是用 stringByRemovingPercentEncoding 方法91     fileURLStr = [fileURLStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];92     NSURL *fileURL = [NSURL URLWithString:fileURLStr];93     94     //创建请求95     NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:fileURL];96     return request;97 }98 99 - (NSURL *)saveURL:(NSURLResponse *)response deleteExistFile:(BOOL)deleteExistFile {
100     NSString *fileName = response ? [response suggestedFilename] : _lblFileName.text;
101     
102     //方法一
103 //    NSString *savePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
104 //    savePath = [savePath stringByAppendingPathComponent:fileName];
105 //    NSURL *saveURL = [NSURL fileURLWithPath:savePath];
106     
107     //方法二
108     NSURL *saveURL = [[NSFileManager defaultManager] URLForDirectory:NSCachesDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
109     saveURL = [saveURL URLByAppendingPathComponent:fileName];
110     NSString *savePath = [saveURL path];
111     
112     if (deleteExistFile) {
113         NSError *saveError;
114         NSFileManager *fileManager = [NSFileManager defaultManager];
115         //判断是否存在旧的目标文件,如果存在就先移除;避免无法复制问题
116         if ([fileManager fileExistsAtPath:savePath]) {
117             [fileManager removeItemAtPath:savePath error:&saveError];
118             if (saveError) {
119                 NSLog(@"移除旧的目标文件失败,错误信息:%@", saveError.localizedDescription);
120             }
121         }
122     }
123     
124     return saveURL;
125 }
126 
127 - (void)updateProgress:(int64_t)receiveDataLength totalDataLength:(int64_t)totalDataLength; {
128     dispatch_async(dispatch_get_main_queue(), ^{ //使用主队列异步方式(主线程)执行更新 UI 操作
129         _hud.progress = (float)receiveDataLength / totalDataLength;
130         
131         if (receiveDataLength == totalDataLength) {
132             _lblMessage.text =  receiveDataLength < 0 ? @"下载失败" : @"下载完成";
133             //kApplication.networkActivityIndicatorVisible = NO;
134             [_hud hide:YES];
135         } else {
136             _lblMessage.text = @"下载中...";
137             //kApplication.networkActivityIndicatorVisible = YES;
138             [_hud show:YES];
139         }
140     });
141 }
142 
143 - (IBAction)downloadFileByConnection:(id)sender {
144     //创建请求
145     NSMutableURLRequest *request = [self downloadRequest];
146     
147     //创建请求操作
148     AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
149     NSString *savePath = [[self saveURL:nil deleteExistFile:NO] path];
150     
151     [operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {
152         NSLog(@"已经接收到响应数据,数据长度为%lld字节...", totalBytesRead);
153         
154         [self updateProgress:totalBytesRead totalDataLength:totalBytesExpectedToRead];
155     }];
156     
157     [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
158         NSLog(@"已经接收完所有响应数据");
159         
160         NSData *data = (NSData *)responseObject;
161         [data writeToFile:savePath atomically:YES]; //responseObject 的对象类型是 NSData
162         
163         [self updateProgress:100 totalDataLength:100];
164     } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
165         NSLog(@"下载失败,错误信息:%@", error.localizedDescription);
166         
167         [self updateProgress:-1 totalDataLength:-1];
168     }];
169     
170     //启动请求操作
171     [operation start];
172 }
173 
174 - (IBAction)downloadFileBySession:(id)sender {
175     //创建请求
176     NSMutableURLRequest *request = [self downloadRequest];
177     
178     //创建会话配置「进程内会话」
179     NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
180     sessionConfiguration.timeoutIntervalForRequest = 60.0; //请求超时时间;默认为60秒
181     sessionConfiguration.allowsCellularAccess = YES; //是否允许蜂窝网络访问(2G/3G/4G)
182     sessionConfiguration.HTTPMaximumConnectionsPerHost = 4; //限制每次最多连接数;在 iOS 中默认值为4
183     
184     //创建会话管理器
185     AFURLSessionManager *sessionManager = [[AFURLSessionManager alloc] initWithSessionConfiguration:sessionConfiguration];
186     
187     //创建会话下载任务,并且启动他;在非主线程中执行
188     NSURLSessionDownloadTask *task = [sessionManager
189                                       downloadTaskWithRequest:request
190                                       progress:nil
191                                       destination:^ NSURL*(NSURL *targetPath, NSURLResponse *response) {
192                                           //当 sessionManager 调用 setDownloadTaskDidFinishDownloadingBlock: 方法,并且方法代码块返回值不为 nil 时(优先级高),下面的两句代码是不执行的(优先级低)
193                                           NSLog(@"下载后的临时保存路径:%@", targetPath);
194                                           return [self saveURL:response deleteExistFile:YES];
195                                       } completionHandler:^ (NSURLResponse *response, NSURL *filePath, NSError *error) {
196                                           if (!error) {
197                                               NSLog(@"下载后的保存路径:%@", filePath); //为上面代码块返回的路径
198                                               
199                                               [self updateProgress:100 totalDataLength:100];
200                                           } else {
201                                               NSLog(@"下载失败,错误信息:%@", error.localizedDescription);
202                                               
203                                               [self updateProgress:-1 totalDataLength:-1];
204                                           }
205                                           
206                                           [_hud hide:YES];
207                                       }];
208     
209     //类似 NSURLSessionDownloadDelegate 的方法操作
210     //- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite;
211     [sessionManager setDownloadTaskDidWriteDataBlock:^ (NSURLSession *session, NSURLSessionDownloadTask *downloadTask, int64_t bytesWritten, int64_t totalBytesWritten, int64_t totalBytesExpectedToWrite) {
212         NSLog(@"已经接收到响应数据,数据长度为%lld字节...", totalBytesWritten);
213         
214         [self updateProgress:totalBytesWritten totalDataLength:totalBytesExpectedToWrite];
215     }];
216     
217     //- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location;
218     [sessionManager setDownloadTaskDidFinishDownloadingBlock:^ NSURL*(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, NSURL *location) {
219         NSLog(@"已经接收完所有响应数据,下载后的临时保存路径:%@", location);
220         return [self saveURL:nil deleteExistFile:YES];
221     }];
222     
223     [task resume];
224 }
225 
226 @end

AFNetworkingViewController.xib

  View Cod 

AppDelegate.h

1 #import <UIKit/UIKit.h>
2 
3 @interface AppDelegate : UIResponder <UIApplicationDelegate>
4 
5 @property (strong, nonatomic) UIWindow *window;
6 @property (strong, nonatomic) UINavigationController *navigationController;
7 
8 @end 

AppDelegate.m

 1 #import "AppDelegate.h"2 #import "ViewController.h"3 4 @interface AppDelegate ()5 6 @end7 8 @implementation AppDelegate9 
10 
11 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
12     _window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
13     ViewController *viewController = [[ViewController alloc]
14                                       initWithSampleNameArray:@[ kTitleOfNSURLConnection,
15                                                                  kTitleOfNSURLConnectionDelegate,
16                                                                  kTitleOfNSURLSession,
17                                                                  kTitleOfNSURLSessionDelegate,
18                                                                  kTitleOfAFNetworking]];
19     _navigationController = [[UINavigationController alloc] initWithRootViewController:viewController];
20     _window.rootViewController = _navigationController;
21     //[_window addSubview:_navigationController.view]; //当_window.rootViewController关联时,这一句可有可无
22     [_window makeKeyAndVisible];
23     return YES;
24 }
25 
26 - (void)applicationWillResignActive:(UIApplication *)application {
27 }
28 
29 - (void)applicationDidEnterBackground:(UIApplication *)application {
30 }
31 
32 - (void)applicationWillEnterForeground:(UIApplication *)application {
33 }
34 
35 - (void)applicationDidBecomeActive:(UIApplication *)application {
36 }
37 
38 - (void)applicationWillTerminate:(UIApplication *)application {
39 }
40 
41 @end

转载于:https://www.cnblogs.com/fshmjl/p/4852268.html

这篇关于网络文件下载(提供多种下载方式)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/776768

相关文章

常用的jdk下载地址

jdk下载地址 安装方式可以看之前的博客: mac安装jdk oracle 版本:https://www.oracle.com/java/technologies/downloads/ Eclipse Temurin版本:https://adoptium.net/zh-CN/temurin/releases/ 阿里版本: github:https://github.com/

Linux 网络编程 --- 应用层

一、自定义协议和序列化反序列化 代码: 序列化反序列化实现网络版本计算器 二、HTTP协议 1、谈两个简单的预备知识 https://www.baidu.com/ --- 域名 --- 域名解析 --- IP地址 http的端口号为80端口,https的端口号为443 url为统一资源定位符。CSDNhttps://mp.csdn.net/mp_blog/creation/editor

ASIO网络调试助手之一:简介

多年前,写过几篇《Boost.Asio C++网络编程》的学习文章,一直没机会实践。最近项目中用到了Asio,于是抽空写了个网络调试助手。 开发环境: Win10 Qt5.12.6 + Asio(standalone) + spdlog 支持协议: UDP + TCP Client + TCP Server 独立的Asio(http://www.think-async.com)只包含了头文件,不依

poj 3181 网络流,建图。

题意: 农夫约翰为他的牛准备了F种食物和D种饮料。 每头牛都有各自喜欢的食物和饮料,而每种食物和饮料都只能分配给一头牛。 问最多能有多少头牛可以同时得到喜欢的食物和饮料。 解析: 由于要同时得到喜欢的食物和饮料,所以网络流建图的时候要把牛拆点了。 如下建图: s -> 食物 -> 牛1 -> 牛2 -> 饮料 -> t 所以分配一下点: s  =  0, 牛1= 1~

poj 3068 有流量限制的最小费用网络流

题意: m条有向边连接了n个仓库,每条边都有一定费用。 将两种危险品从0运到n-1,除了起点和终点外,危险品不能放在一起,也不能走相同的路径。 求最小的费用是多少。 解析: 抽象出一个源点s一个汇点t,源点与0相连,费用为0,容量为2。 汇点与n - 1相连,费用为0,容量为2。 每条边之间也相连,费用为每条边的费用,容量为1。 建图完毕之后,求一条流量为2的最小费用流就行了

poj 2112 网络流+二分

题意: k台挤奶机,c头牛,每台挤奶机可以挤m头牛。 现在给出每只牛到挤奶机的距离矩阵,求最小化牛的最大路程。 解析: 最大值最小化,最小值最大化,用二分来做。 先求出两点之间的最短距离。 然后二分匹配牛到挤奶机的最大路程,匹配中的判断是在这个最大路程下,是否牛的数量达到c只。 如何求牛的数量呢,用网络流来做。 从源点到牛引一条容量为1的边,然后挤奶机到汇点引一条容量为m的边

2. 下载rknn-toolkit2项目

官网链接: https://github.com/airockchip/rknn-toolkit2 安装好git:[[1. Git的安装]] 下载项目: git clone https://github.com/airockchip/rknn-toolkit2.git 或者直接去github下载压缩文件,解压即可。

配置InfiniBand (IB) 和 RDMA over Converged Ethernet (RoCE) 网络

配置InfiniBand (IB) 和 RDMA over Converged Ethernet (RoCE) 网络 服务器端配置 在服务器端,你需要确保安装了必要的驱动程序和软件包,并且正确配置了网络接口。 安装 OFED 首先,安装 Open Fabrics Enterprise Distribution (OFED),它包含了 InfiniBand 所需的驱动程序和库。 sudo

【机器学习】高斯网络的基本概念和应用领域

引言 高斯网络(Gaussian Network)通常指的是一个概率图模型,其中所有的随机变量(或节点)都遵循高斯分布 文章目录 引言一、高斯网络(Gaussian Network)1.1 高斯过程(Gaussian Process)1.2 高斯混合模型(Gaussian Mixture Model)1.3 应用1.4 总结 二、高斯网络的应用2.1 机器学习2.2 统计学2.3

网络学习-eNSP配置NAT

NAT实现内网和外网互通 #给路由器接口设置IP地址模拟实验环境<Huawei>system-viewEnter system view, return user view with Ctrl+Z.[Huawei]undo info-center enableInfo: Information center is disabled.[Huawei]interface gigabit