liuyong / ziparchive

Automatically exported from code.google.com/p/ziparchive
0 stars 0 forks source link

No idea on changing creation time of extracted files. #1

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
I still didn't find the way to change creation time of file on iPhone,
because the key 'NSCreationDate' is not valid for iPhone, but ok for
desktop OSX. If anyone knows how to modify the creation datetime, please
let me know. thanks.

Original issue reported on code.google.com by acs...@gmail.com on 6 Feb 2009 at 1:17

GoogleCodeExporter commented 9 years ago
Were you looking for NSFileCreationDate ? its there, in NSFileManager.h (on 
iphone SDK 3.0 at least). 

BTW: Trying to unzip, I got a bad modification date (in 2010) from your NSDate* 
orgDate = [[NSDate alloc]  
initWithTimeInterval:(NSTimeInterval)fileInfo.dosDate   sinceDate:[self 
Date1980] ]

Are you sure that fileInfo.dosDate is actually the number of seconds since 
1980? Googling "MSDOS Date 
format in pkzip" it seems to be packed date fields (seconds, minutes, hours, 
day, etc). 

Thanks for posting this.

Original comment by gracions...@gmail.com on 13 Jul 2009 at 9:44

GoogleCodeExporter commented 9 years ago
I don't think it is number of seconds since 1980.  I had this same problem and 
worked around it with the 
following mod to upzipFileTo:overWrite:

-(BOOL) unzipFileTo:(NSString*)path overWrite:(BOOL)overWrite
{
    BOOL success = YES;
    int ret = unzGoToFirstFile( _unzFile );
    unsigned char       buffer[4096] = {0};
    NSFileManager* fman = [NSFileManager defaultManager];
    if( ret!=UNZ_OK )
    {
        [self outputErrorMessage:@"Failed"];
    }

    do  {
        ret = unzOpenCurrentFile( _unzFile );
        if( ret!=UNZ_OK )
        {
            [self outputErrorMessage:@"Error occurs"];
            success = NO;
            break;
        }
        // reading data and write to file
        int read ;
        unz_file_info   fileInfo ={0};
        ret = unzGetCurrentFileInfo(_unzFile, &fileInfo, NULL, 0, NULL, 0, NULL, 0);
        if( ret!=UNZ_OK )
        {
            [self outputErrorMessage:@"Error occurs while getting file info"];
            success = NO;
            unzCloseCurrentFile( _unzFile );
            break;
        }
        char* filename = (char*) malloc( fileInfo.size_filename +1 );
        unzGetCurrentFileInfo(_unzFile, &fileInfo, filename, fileInfo.size_filename + 1, NULL, 0, NULL, 0);
        filename[fileInfo.size_filename] = '\0';

        // check if it contains directory
        NSString * strPath = [NSString  stringWithCString:filename];
        BOOL isDirectory = NO;
        if( filename[fileInfo.size_filename-1]=='/' || filename[fileInfo.size_filename-1]=='\\')
            isDirectory = YES;
        free( filename );
        if( [strPath rangeOfCharacterFromSet:[NSCharacterSet 
characterSetWithCharactersInString:@"/\\"]].location!=NSNotFound )
        {// contains a path
            strPath = [strPath stringByReplacingOccurrencesOfString:@"\\" withString:@"/"];
        }
        NSString* fullPath = [path stringByAppendingPathComponent:strPath];

        if( isDirectory )
            [fman createDirectoryAtPath:fullPath withIntermediateDirectories:YES attributes:nil error:nil];
        else
            [fman createDirectoryAtPath:[fullPath stringByDeletingLastPathComponent] 
withIntermediateDirectories:YES attributes:nil error:nil];
        if( [fman fileExistsAtPath:fullPath] && !isDirectory && !overWrite )
        {
            if( ![self overWrite:fullPath] )
            {
                unzCloseCurrentFile( _unzFile );
                ret = unzGoToNextFile( _unzFile );
                continue;
            }
        }
        FILE* fp = fopen( (const char*)[fullPath UTF8String], "wb");
        while( fp )
        {
            read=unzReadCurrentFile(_unzFile, buffer, 4096);
            if( read > 0 )
            {
                fwrite(buffer, read, 1, fp );
            }
            else if( read<0 )
            {
                [self outputErrorMessage:@"Failed to reading zip file"];
                break;
            }
            else 
                break;              
        }
        if( fp )
        {
            fclose( fp );
            // set the orignal datetime property
            if( fileInfo.dosDate!=0 )
            {

                //NSNumber *secondsSince1980 = [NSNumber numberWithUnsignedLong:fileInfo.dosDate];
                //NSDate* orgDate = [[NSDate alloc] 
                //                 initWithTimeInterval:[secondsSince1980 doubleValue]
                //                 sinceDate:[self Date1980] ];

                NSDateComponents *dc = [[NSDateComponents alloc] init];

                dc.second = fileInfo.tmu_date.tm_sec;
                dc.minute = fileInfo.tmu_date.tm_min;
                dc.hour = fileInfo.tmu_date.tm_hour;
                dc.day = fileInfo.tmu_date.tm_mday;
                dc.month = fileInfo.tmu_date.tm_mon+1;
                dc.year = fileInfo.tmu_date.tm_year;

                NSCalendar *gregorian = [[NSCalendar alloc] 
initWithCalendarIdentifier:NSGregorianCalendar];

                NSDate *orgDate = [gregorian dateFromComponents:dc];
                [dc release];
                [gregorian release];

                NSDictionary* attr = [NSDictionary dictionaryWithObject:orgDate 
forKey:NSFileModificationDate]; //[[NSFileManager defaultManager] 
fileAttributesAtPath:fullPath 
traverseLink:YES];
                if( attr )
                {
                //  [attr  setValue:orgDate forKey:NSFileCreationDate];
                    if( ![[NSFileManager defaultManager] setAttributes:attr ofItemAtPath:fullPath error:nil] )
                    {
                        // cann't set attributes 
                        NSLog(@"Failed to set attributes");
                    }

                }
                //[orgDate release];
                //orgDate = nil;
            }

        }
        unzCloseCurrentFile( _unzFile );
        ret = unzGoToNextFile( _unzFile );
    }while( ret==UNZ_OK && UNZ_OK!=UNZ_END_OF_LIST_OF_FILE );
    return success;
}

Original comment by brad.ea...@gmail.com on 22 Jul 2009 at 9:57

GoogleCodeExporter commented 9 years ago
thanks brad.eaton for your solution.

after doing some deep research, I found some applications will not use 
"dosDate" field as the creation date, 
instead they use tmz_date section. Now I changed to use tmz_date as well during 
compression process. 

Original comment by acs...@gmail.com on 21 Oct 2009 at 3:38

GoogleCodeExporter commented 9 years ago
Thanks for your work.

Original comment by tso...@gmail.com on 4 Dec 2009 at 5:54