3

ファイルをアップロードしようとしていますが、いくつかの問題があります。ローカル パスからの入力ストリームがあります。

self.stmIn = [NSInputStream inputStreamWithFileAtPath:localPath];

変数 localPath の URL は次のとおりです。

/Users/JBG/Library/Application Support/iPhone Simulator/6.0/Applications/734F4DC6-8683-42BB-AB0D-A5553BC22C55/Documents/100046-003.jpg

問題なくストリームを開くことができます。私がそれを読もうとすると問題が発生します:

bytesRead = [self.stmIn read:self.buffer maxLength:kSendBufferSize];

結果は -1 です。問題がわかりません。何か案が?

感謝と敬意

EDIT:コードはAppleのSimpleFTPSampleに基づいています(取得されています)が、UIViewControllerの横にあるNSObjectクラスとして実装しました

編集: streamError メソッドを使用してこの情報を取得しました: エラー Domain=NSPOSIXErrorDomain Code=14 "The operation coudn't be completed. Bad address"

編集:コードを追加します:

- (uint8_t *)buffer {
    return self->buffer;
}

- (BOOL)isSending {
    return (self.stmOut != nil);
}

- (void)startSend {
    BOOL success;
    NSURL *url;

    [[NetworkManager sharedInstance] didStartNetworkOperation];

    assert([[NSFileManager defaultManager] fileExistsAtPath:localPath]);

    assert(self.stmOut == nil);      // don't tap send twice in a row!
    assert(self.stmIn == nil);         // ditto

    url = [[NetworkManager sharedInstance] smartURLForString:ftpPath];
    success = (url != nil);

    if (success) {
        url = CFBridgingRelease(CFURLCreateCopyAppendingPathComponent(NULL, (CFURLRef) url, (CFStringRef) [localPath lastPathComponent], false));
        success = (url != nil);
    }

    if ( ! success) {
        NSLog(@"Invalid URL");
    } else {

        self.stmIn = [NSInputStream inputStreamWithFileAtPath:localPath];
        assert(self.stmIn != nil);

        [self.stmIn open];

        self.stmOut = CFBridgingRelease(CFWriteStreamCreateWithFTPURL(NULL, (CFURLRef) url));
        assert(self.stmOut != nil);

        success = [self.stmOut setProperty:ftpUser forKey:(id)kCFStreamPropertyFTPUserName];
        assert(success);
        success = [self.stmOut setProperty:ftpPwd forKey:(id)kCFStreamPropertyFTPPassword];
        assert(success);

        self.stmOut.delegate = self;
        [self.stmOut scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
        [self.stmOut open];
    }
}

- (void)stopSendWithStatus:(NSString *)statusString {
    if (self.stmOut != nil) {
        [self.stmOut removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
        self.stmOut.delegate = nil;
        [self.stmOut close];
        self.stmOut = nil;
    }
    if (self.stmIn != nil) {
        [self.stmIn close];
        self.stmIn = nil;
    }
    if (statusString == nil) {
        statusString = @"Archivo subido";
    }
    [[NetworkManager sharedInstance] didStopNetworkOperation];
}

- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode {
    assert(aStream == self.stmOut);

    switch (eventCode) {
        case NSStreamEventOpenCompleted: {
            NSLog(@"Opened connection");
        } break;
        case NSStreamEventHasBytesAvailable: {
            assert(NO); 
        } break;
        case NSStreamEventHasSpaceAvailable: {
            NSLog(@"Sending");
            if (self.bufferOffset == self.bufferLimit) {
                NSInteger   bytesRead;

                bytesRead = [self.stmIn read:self.buffer maxLength:kSendBufferSize];

                if (bytesRead == -1) {
                    [self stopSendWithStatus:@"File read error"];
                } else if (bytesRead == 0) {
                    [self stopSendWithStatus:nil];
                } else {
                    self.bufferOffset = 0;
                    self.bufferLimit  = bytesRead;
                }
            }

            if (self.bufferOffset != self.bufferLimit) {
                NSInteger   bytesWritten;
                bytesWritten = [self.stmOut write:&self.buffer[self.bufferOffset] maxLength:self.bufferLimit - self.bufferOffset];
                assert(bytesWritten != 0);
                if (bytesWritten == -1) {
                    [self stopSendWithStatus:@"Network write error"];
                } else {
                    self.bufferOffset += bytesWritten;
                }
            }
        } break;
        case NSStreamEventErrorOccurred: {
            [self stopSendWithStatus:@"Stream open error"];
        } break;
        case NSStreamEventEndEncountered: {
        // ignore
        } break;
        default: {
            assert(NO);
        } break;
    }
}
4

2 に答える 2

1

このコードを試してください..それがあなたに役立つことを願っています..

- (void)sendDidStart
{
    // self.statusLabel.text = @"Sending";
    [[NetworkManager sharedInstance] didStartNetworkOperation];

}

- (void)updateStatus:(NSString *)statusString
{
    assert(statusString != nil);
    //self.statusLabel.text = statusString;
}

- (void)sendDidStopWithStatus:(NSString *)statusString
{
    if (statusString == nil) {
        statusString = @"Put succeeded";
    }
    [[NetworkManager sharedInstance] didStopNetworkOperation];
}

#pragma mark * Core transfer code

// This is the code that actually does the networking.

// Because buffer is declared as an array, you have to use a custom getter.  
// A synthesised getter doesn't compile.

- (uint8_t *)buffer
{
    return self->_buffer;
}

- (BOOL)isSending
{
    return (self.networkStream != nil);
}

- (void)startSend:(NSString *)filePath
{
    BOOL                    success;
    NSURL *                 url;
    NSLog(@"localfilepath..:%@",localFilePath);
    assert(localFilePath != nil);
    assert([[NSFileManager defaultManager] fileExistsAtPath:localFilePath]);
    assert( [localFilePath.pathExtension isEqual:@"png"] || [localFilePath.pathExtension isEqual:@"jpg"] );

    assert(self.networkStream == nil);      // don't tap send twice in a row!
    assert(self.fileStream == nil);         // ditto

    // First get and check the URL.

    url = [[NetworkManager sharedInstance] smartURLForString:@"ftp://yourFTPLink/"];
    success = (url != nil);

    if (success) {
        // Add the last part of the file name to the end of the URL to form the final 
        // URL that we're going to put to.

        // url = CFBridgingRelease(
        // CFURLCreateCopyAppendingPathComponent(NULL, (__bridge CFURLRef) url, (__bridge CFStringRef) @"minkle.png" , false)
        // );
        url = CFBridgingRelease(
                                CFURLCreateCopyAppendingPathComponent(NULL, ( CFURLRef) url, ( CFStringRef) imageString , false)
                                );

        success = (url != nil);
    }

    // If the URL is bogus, let the user know.  Otherwise kick off the connection.

    if ( ! success) {
        // self.statusLabel.text = @"Invalid URL";
    }    
    else 
    {

        // Open a stream for the file we're going to send.  We do not open this stream; 
        // NSURLConnection will do it for us.

        self.fileStream = [NSInputStream inputStreamWithFileAtPath:localFilePath];
        assert(self.fileStream != nil);

        [self.fileStream open];

        // Open a CFFTPStream for the URL.

        self.networkStream = CFBridgingRelease(
                                               CFWriteStreamCreateWithFTPURL(NULL, ( CFURLRef) url)
                                               );
        assert(self.networkStream != nil);

        // if ([self.usernameText.text length] != 0) {
        success = [self.networkStream setProperty:@"yourUserName" forKey:(id)kCFStreamPropertyFTPUserName];
        assert(success);
        success = [self.networkStream setProperty:@"yourPassword" forKey:(id)kCFStreamPropertyFTPPassword];
        assert(success);
        //}

        self.networkStream.delegate = self;
        [self.networkStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
        [self.networkStream open];

        // Tell the UI we're sending.

        [self sendDidStart];
    }
}

- (void)stopSendWithStatus:(NSString *)statusString
{
    if (self.networkStream != nil) {
        [self.networkStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
        self.networkStream.delegate = nil;
        [self.networkStream close];
        self.networkStream = nil;
    }
    if (self.fileStream != nil) {
        [self.fileStream close];
        self.fileStream = nil;
    }
    [self sendDidStopWithStatus:statusString];
}

- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode
// An NSStream delegate callback that's called when events happen on our 
// network stream.
{
#pragma unused(aStream)
    assert(aStream == self.networkStream);

    switch (eventCode) {
        case NSStreamEventOpenCompleted: {
            [self updateStatus:@"Opened connection"];
        } break;
        case NSStreamEventHasBytesAvailable: {
            assert(NO);     // should never happen for the output stream
        } break;
        case NSStreamEventHasSpaceAvailable: {
            [self updateStatus:@"Sending"];

            // If we don't have any data buffered, go read the next chunk of data.

            if (self.bufferOffset == self.bufferLimit) {
                NSInteger   bytesRead;

                bytesRead = [self.fileStream read:self.buffer maxLength:jSendBufferSize];

                if (bytesRead == -1) {
                    [self stopSendWithStatus:@"File read error"];
                } else if (bytesRead == 0) {
                    [self stopSendWithStatus:nil];
                } else {
                    self.bufferOffset = 0;
                    self.bufferLimit  = bytesRead;
                }
            }

            // If we're not out of data completely, send the next chunk.

            if (self.bufferOffset != self.bufferLimit) {
                NSInteger   bytesWritten;
                bytesWritten = [self.networkStream write:&self.buffer[self.bufferOffset] maxLength:self.bufferLimit - self.bufferOffset];
                assert(bytesWritten != 0);
                if (bytesWritten == -1) {
                    [self stopSendWithStatus:@"Network write error"];
                } else {
                    self.bufferOffset += bytesWritten;
                }
            }
        } break;
        case NSStreamEventErrorOccurred: {
            [self stopSendWithStatus:@"Stream open error"];
        } break;
        case NSStreamEventEndEncountered: {
            // ignore
        } break;
        default: {
            assert(NO);
        } break;
    }
}
于 2013-02-15T11:01:05.327 に答える
0

この文字列を回しましたか:

/Users/JBG/Library/Application Support/iPhone Simulator/6.0/Applications/734F4DC6-8683-42BB-AB0D-A5553BC22C55/Documents/100046-003.jpg

ファイルの URL に?

fileURLWithPath:[NSURL](https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSURL_Class/Reference/Reference.html] ドキュメントのようなものを使用して文字列を変換する必要があります適切な URL へのパス。

于 2013-02-18T15:56:07.443 に答える