Sunday, May 12, 2013

NSInputStream inputStreamWithURL example ios


inputStreamWithURL:

Creates and returns an initialized NSInputStream object that reads data from the file at a given URL.
+ (id)inputStreamWithURL:(NSURL *)url
Parameters
url
The URL to the file.
Return Value
An initialized NSInputStream object that reads data from the URL at url. If the file specified by url doesn’t exist or is unreadable, returns nil.
( NSInputStream inputStreamWithURL example )
NSInputStream *inputStream = [NSInputStream inputStreamWithURL: myURL];
NSOutputStream *outputStream = [NSOutputStream outputStreamToMemory];
( NSInputStream inputStreamWithURL example )
#import <mach/mach_time.h>

@interface NSURL(CopyWithProgress)<NSObject>
- (void) copyFileURLToURL:(NSURL*)destURL withProgressBlock:(void(^)(double, double, double))block;
@end

@implementation NSURL(CopyWithProgress)

- (void) copyFileURLToURL:(NSURL*)destURL
        withProgressBlock:(void(^)(double, double, double))block
{
    ///
    // NOTE: error handling has been left out in favor of simplicity
    //       real production code should obviously handle errors.
    NSUInteger fileSize = [[NSFileManager defaultManager] attributesOfItemAtPath:self.path error:nil].fileSize;

    NSInputStream  *fileInput  = [NSInputStream inputStreamWithURL:self];
    NSOutputStream *copyOutput = [NSOutputStream outputStreamWithURL:destURL append:NO];

    static size_t bufferSize = 4096;
    uint8_t *buffer = malloc(bufferSize);
    size_t   bytesToWrite;
    size_t   bytesWritten;
    size_t   copySize = 0;
    size_t   counter  = 0;

    [fileInput open];
    [copyOutput open];

    uint64_t time0 = mach_absolute_time();

    while (fileInput.hasBytesAvailable) {
        do {
            bytesToWrite = [fileInput read:buffer maxLength:bufferSize];
            bytesWritten = [copyOutput write:buffer maxLength:bytesToWrite];
            bytesToWrite -= bytesWritten;
            copySize     += bytesWritten;
            if (bytesToWrite > 0)
                memmove(buffer, buffer + bytesWritten, bytesToWrite);
        }
        while (bytesToWrite > 0);

        if (block != nil && ++counter % 10 == 0) {
            double percent  = (double)copySize / fileSize;
            uint64_t time1  = mach_absolute_time();
            double elapsed  = (double)(time1 - time0)/NSEC_PER_SEC;
            double estTimeLeft = ((1 - percent) / percent) * elapsed;
            block(copySize, percent, estTimeLeft);
        }
    }

    if (block != nil)
        block(copySize, 1, 0);
}

@end
( NSInputStream inputStreamWithURL example )
- (void)encryptWithSemaphore:(NSURL *)url {
  dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);

  __block int total = 0;
  int blockSize = 32 * 1024;

  NSString *encryptedFile = [[url lastPathComponent] stringByDeletingPathExtension];
  NSURL *docsURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
  self.tempURL = [[docsURL URLByAppendingPathComponent:encryptedFile isDirectory:NO] URLByAppendingPathExtension:@"crypt"];

  NSInputStream *inputStream = [NSInputStream inputStreamWithURL:url];
  __block NSOutputStream *outputStream = [NSOutputStream outputStreamWithURL:self.tempURL append:NO];
  __block NSError *encryptionError = nil;

  [inputStream open];
  [outputStream open];

  RNEncryptor *encryptor = [[RNEncryptor alloc] initWithSettings:kRNCryptorAES256Settings
                                                        password:self.password
                                                         handler:^(RNCryptor *cryptor, NSData *data) {
                                                           @autoreleasepool {
                                                             [outputStream write:data.bytes maxLength:data.length];
                                                             dispatch_semaphore_signal(semaphore);

                                                             data = nil;
                                                             if (cryptor.isFinished) {
                                                               [outputStream close];
                                                               encryptionError = cryptor.error;
                                                               // call my delegate that I'm finished with decrypting
                                                             }
                                                           }
                                                         }];
  while (inputStream.hasBytesAvailable) {
    @autoreleasepool {
      uint8_t buf[blockSize];
      NSUInteger bytesRead = [inputStream read:buf maxLength:blockSize];
      if (bytesRead > 0) {
        NSData *data = [NSData dataWithBytes:buf length:bytesRead];

        total = total + bytesRead;
        [encryptor addData:data];

        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
      }
    }
  }

  [inputStream close];
  [encryptor finish];  
}