gpt4 book ai didi

iphone - 使用 NSData block 对文件进行 Base64 编码

转载 作者:太空狗 更新时间:2023-10-30 03:33:42 27 4
gpt4 key购买 nike

更新 4
根据 Greg 的建议,我创建了一对图像/文本,显示从 37k 图像到 base64 编码的输出,使用 100k block 。由于文件只有 37k,可以肯定地说循环只迭代了一次,所以没有附加任何内容。另一对显示从相同的 37k 图像到 base64 编码的输出,使用 10k block 。由于文件大小为 37k,因此循环迭代了四次,并且肯定附加了数据。

对这两个文件进行比较表明,在 10kb block 文件上,从第 214 行开始到第 640 行结束有很大差异。

更新 3
这是我的代码现在所在的位置。清理了一下但仍然产生相同的效果:

// Read data in chunks from the original file[originalFile seekToEndOfFile];NSUInteger fileLength = [originalFile offsetInFile];[originalFile seekToFileOffset:0];NSUInteger chunkSize = 100 * 1024;NSUInteger offset = 0;while(offset < fileLength) {    NSData *chunk = [originalFile readDataOfLength:chunkSize];    offset += chunkSize;    // Convert the chunk to a base64 encoded string and back into NSData    NSString *base64EncodedChunkString = [chunk base64EncodedString];    NSData *base64EncodedChunk = [base64EncodedChunkString dataUsingEncoding:NSASCIIStringEncoding];    // Write the encoded chunk to our output file    [encodedFile writeData:base64EncodedChunk];    // Cleanup    base64EncodedChunkString = nil;    base64EncodedChunk = nil;    // Update progress bar    [self updateProgress:[NSNumber numberWithInt:offset] total:[NSNumber numberWithInt:fileLength]];}

更新 2
所以看起来大于 100 KB 的文件会被打乱,但小于 100 KB 的文件没问题。很明显,我的缓冲区/数学/等有问题,但我迷失了这一点。可能是时候结束了,但我很想在解决这个问题后上床 sleep 。

这是一个例子:

更新 1
在做了一些测试后,我发现相同的代码对于小图像可以正常工作,但不适用于大图像或任何大小的视频。绝对看起来像是缓冲区问题,对吧?


嘿,尝试通过循环对大文件进行 base64 编码,一次一小块。一切似乎都正常,但文件总是以损坏告终。我很好奇是否有人可以指出我在这里可能出错的地方:

    NSFileHandle *originalFile, *encodedFile;    self.localEncodedURL = [NSString stringWithFormat:@"%@-base64.xml", self.localURL];    // Open the original file for reading    originalFile = [NSFileHandle fileHandleForReadingAtPath:self.localURL];    if (originalFile == nil) {        [self performSelectorOnMainThread:@selector(updateStatus:) withObject:@"Encoding failed." waitUntilDone:NO];        return;    }    encodedFile = [NSFileHandle fileHandleForWritingAtPath:self.localEncodedURL];    if (encodedFile == nil) {        [self performSelectorOnMainThread:@selector(updateStatus:) withObject:@"Encoding failed." waitUntilDone:NO];        return;    }    // Read data in chunks from the original file    [originalFile seekToEndOfFile];    NSUInteger length = [originalFile offsetInFile];    [originalFile seekToFileOffset:0];    NSUInteger chunkSize = 100 * 1024;    NSUInteger offset = 0;    do {        NSUInteger thisChunkSize = length - offset > chunkSize ? chunkSize : length - offset;        NSData *chunk = [originalFile readDataOfLength:thisChunkSize];        offset += [chunk length];        NSString *base64EncodedChunkString = [chunk base64EncodedString];        NSData *base64EncodedChunk = [base64EncodedChunkString dataUsingEncoding:NSASCIIStringEncoding];        [encodedFile writeData:base64EncodedChunk];        base64EncodedChunkString = nil;        base64EncodedChunk = nil;    } while (offset < length);

最佳答案

我希望我能赞扬 GregInYEG,因为他关于填充的原始观点是根本问题。使用 base64,每个 block 都必须是 3 的倍数。所以这解决了问题:

chunkSize = 3600

一旦我有了它,腐败就消失了。但后来我遇到了内存泄漏问题,所以我添加了从这篇文章中获取的自动释放池方法: http://www.cocoadev.com/index.pl?ReadAFilePieceByPiece

最终代码:

// Read data in chunks from the original file
[originalFile seekToEndOfFile];
NSUInteger fileLength = [originalFile offsetInFile];
[originalFile seekToFileOffset:0];

// For base64, each chunk *MUST* be a multiple of 3
NSUInteger chunkSize = 24000;
NSUInteger offset = 0;
NSAutoreleasePool *chunkPool = [[NSAutoreleasePool alloc] init];

while(offset < fileLength) {
// Read the next chunk from the input file
[originalFile seekToFileOffset:offset];
NSData *chunk = [originalFile readDataOfLength:chunkSize];

// Update our offset
offset += chunkSize;

// Base64 encode the input chunk
NSData *serializedChunk = [NSPropertyListSerialization dataFromPropertyList:chunk format:NSPropertyListXMLFormat_v1_0 errorDescription:NULL];
NSString *serializedString = [[NSString alloc] initWithData:serializedChunk encoding:NSASCIIStringEncoding];
NSRange r = [serializedString rangeOfString:@"<data>"];
serializedString = [serializedString substringFromIndex:r.location+7];
r = [serializedString rangeOfString:@"</data>"];
serializedString = [serializedString substringToIndex:r.location-1];

// Write the base64 encoded chunk to our output file
NSData *base64EncodedChunk = [serializedString dataUsingEncoding:NSASCIIStringEncoding];
[encodedFile truncateFileAtOffset:[encodedFile seekToEndOfFile]];
[encodedFile writeData:base64EncodedChunk];

// Cleanup
base64EncodedChunk = nil;
serializedChunk = nil;
serializedString = nil;
chunk = nil;

// Update the progress bar
[self updateProgress:[NSNumber numberWithInt:offset] total:[NSNumber numberWithInt:fileLength]];

// Drain and recreate the pool
[chunkPool release];
chunkPool = [[NSAutoreleasePool alloc] init];
}
[chunkPool release];

关于iphone - 使用 NSData block 对文件进行 Base64 编码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3859437/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com