2

这就是我使用 NSStream 实现 FTP 文件上传的方式,它工作正常,没有问题,但我无法弄清楚如何恢复文件上传,以防连接丢失或用户在上传时不小心关闭了应用程序进行中。

@implementation QFTPOperation

-(id)uploadFile:(NSString *)filePath
{
    NSURL *localpath = [NSURL URLWithString:filePath];
    NSLog(@"file url: %@",[localpath path]);

    if([[NSFileManager defaultManager] fileExistsAtPath:[localpath path]]) {
        NSLog(@"files exists");
    }

    self.readStream = [NSInputStream inputStreamWithFileAtPath:[[NSURL URLWithString:filePath] path]];
    [self.readStream open];
    NSURL *uploadUrl = [NSURL URLWithString:@"ftp://domain.example.com/test.png"];


    uploadUrl = CFBridgingRelease(
                            CFURLCreateCopyAppendingPathComponent(NULL, (__bridge CFURLRef) uploadUrl, (__bridge CFStringRef) [filePath lastPathComponent], false)
                            );

    NSLog(@"upload url: %@",uploadUrl);
    self.writeStream = CFBridgingRelease(
                      CFWriteStreamCreateWithFTPURL(NULL, (__bridge CFURLRef) uploadUrl)
                      );

    [[self writeStream] setDelegate:self];
    [[self writeStream] scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
    [[self writeStream] setProperty:@"foo" forKey:(id)kCFStreamPropertyFTPUserName];
    [[self writeStream] setProperty:@"bar" forKey:(id)kCFStreamPropertyFTPPassword];

    [[self writeStream] open];




    while ([[self writeStream] hasSpaceAvailable])
    {
        NSLog(@"yes ready");
        NSInteger bufferOffset = 0;
        NSInteger bufferLimit = 0;
        UInt8 buffer[1024];

        if (bufferOffset == bufferLimit) {
            NSInteger   bytesRead;

            bytesRead = [self.readStream read:buffer maxLength:1024];

            if (bytesRead == -1) {
                NSLog(@"faild to readstream");
                [self closeStream];
            } else if (bytesRead == 0) {
                NSLog(@"read completed");
                [self closeStream];
            } else {
                NSLog(@"bytes read");
                bufferOffset = 0;
                bufferLimit  = bytesRead;
            }
        }



        if (bufferOffset != bufferLimit) {
            NSLog(@"yes waiting to write");
            NSInteger   bytesWritten;
            bytesWritten = [self.writeStream write:&buffer[1024] maxLength:bufferLimit - bufferOffset];
            if (bytesWritten == -1) {
                NSLog(@"failed to write");
                [self closeStream];
            } else {
                bufferOffset += bytesWritten;
            }
        }

    }


    return self;
}

- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode
{
    switch (eventCode) {
        case NSStreamEventOpenCompleted:
            NSLog(@"yes stream open");
            break;
        case NSStreamEventHasBytesAvailable:
            break;
        case NSStreamEventHasSpaceAvailable: {
                NSLog(@"yes space available");
            NSInteger bufferOffset = 0;
            NSInteger bufferLimit = 0;
            UInt8 buffer[1024];

            if (bufferOffset == bufferLimit) {
                NSInteger   bytesRead;

                bytesRead = [self.readStream read:buffer maxLength:1024];

                if (bytesRead == -1) {
                    NSLog(@"faild to readstream");
                    [self closeStream];
                } else if (bytesRead == 0) {
                    NSLog(@"read completed");
                    [self closeStream];
                } else {
                    NSLog(@"bytes read");
                    bufferOffset = 0;
                    bufferLimit  = bytesRead;
                }
            }



            if (bufferOffset != bufferLimit) {
                NSLog(@"yes waiting to write");
                NSInteger   bytesWritten;
                bytesWritten = [self.writeStream write:&buffer[1024] maxLength:bufferLimit - bufferOffset];
                if (bytesWritten == -1) {
                   NSLog(@"failed to write");
                    [self closeStream];
                } else {
                    bufferOffset += bytesWritten;
                }
            }

        }
            break;
        case NSStreamEventEndEncountered:
            NSLog(@"error occurred");
            [self closeStream];
            break;
        case NSStreamEventErrorOccurred:
            NSLog(@"error occurred");
            [self closeStream];
            break;
        case NSStreamEventNone:
            break;
        default:
            break;
    }
}

-(void)closeStream
{
    [[self writeStream] removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
    [[self writeStream] setDelegate:nil];
    [[self writeStream] close];
    self.writeStream = nil;

    [[self readStream] close];
    self.readStream = nil;
}

假设用户在中间退出应用程序时上传 200 MB,假设上传了 100 MB。我想从 100 MB 恢复上传,而不是重新开始。

任何帮助提前谢谢

4

0 回答 0