Утечка памяти при сравнении больших файлов (под ARC)

Я пытаюсь сравнить 2 файла. Когда файлы очень большие (я тестирую с 1,7 Г), процесс растет и растет, пока он не заглохнет. Очевидно, что ARC не освобождает пространство правильно (или библиотеки объектной-c не очищаются после себя).

В "Инструментах" я вижу, что "Malloc 4,0KB" имеет все более высокие байты Live, которые указывают непосредственно на NSFileHandle или NSData, поскольку я использую размер буфера 4096 байт.

Я уже пробовал много разных вещей, например, инициализацию файлов с каждым циклом и установку их на нуль в конце каждого цикла. Ничто не помогает.

Есть идеи? Помог бы NSAutoreleasePool?

Здесь основной код:

NSFileHandle *file1;
NSFileHandle *file2;

int bufferSize = 4096;

file1 = [NSFileHandle fileHandleForReadingAtPath: [self.input1 stringValue]];
file2 = [NSFileHandle fileHandleForReadingAtPath: [self.input2 stringValue]];

int long long size1 = [file1 ***************];
int long long size2 = [file2 ***************];
int long long pos1 = 0;
int long long pos2 = 0;

if(size1 != size2) {
 NSLog(@"Files have different sizes");
 return;
}

do {

 [file1 seekToFileOffset: pos1];
 [file2 seekToFileOffset: pos2];

 NSLog(@"Reading at: %lli",[file1 offsetInFile]);

 if(![[file1 readDataOfLength: bufferSize] isEqualToData: [file2 readDataOfLength: bufferSize]]) {
 break;
 }

 pos1 += bufferSize;
 pos2 += bufferSize;

} while(pos1 < size1);

if(pos1 < size1) {
 NSLog(@"Files do not match");
} else {
 NSLog(@"Files are an exact match");
}
1 ответ

Как это случилось со мной раньше, после публикации вопроса у меня появилась какая-то новая идея, как это сделать.

я использовал

NSData initWithContentsOfFile: options: NSDataReadingMappedAlways error:nil

для чтения файла вместо NSFile. Теперь это работает.

int bufferSize = 4096;

NSData *file1;
NSData *file2;
NSRange range1;
NSRange range2;
unsigned char buffer1[bufferSize];
unsigned char buffer2[bufferSize];

range1.length = bufferSize;
range2.length = bufferSize;
range1.location = 0;
range2.location = 0;

int long long size1 = [[[NSFileManager defaultManager] attributesOfItemAtPath: [self.input1 stringValue] error:nil] fileSize];
int long long size2 = [[[NSFileManager defaultManager] attributesOfItemAtPath: [self.input2 stringValue] error:nil] fileSize];


if(size1 != size2) {
 NSLog(@"Files have different sizes");
 return;
}

file1 = [[NSData alloc] initWithContentsOfFile:[self.input1 stringValue] options: NSDataReadingMappedAlways error: nil];
file2 = [[NSData alloc] initWithContentsOfFile:[self.input2 stringValue] options: NSDataReadingMappedAlways error: nil];

do {
 [file1 getBytes: buffer1 range: range1];
 [file2 getBytes: buffer2 range: range2];

 NSData *data1 = [[NSData alloc] initWithBytes: buffer1 length: bufferSize];
 NSData *data2 = [[NSData alloc] initWithBytes: buffer2 length: bufferSize];

 if (![data1 isEqualToData: data2]) {
 break;
 }

 NSLog(@"Reading: %i",(int)(((float)range1.location / (float)size1) * 10000) / 100);

 range1.location += bufferSize;
 range2.location += bufferSize;

} while(range1.location < size1);

if(range1.location < size1) {
 NSLog(@"Files do not match");
} else {
 NSLog(@"Files are an exact match");
}

licensed under cc by-sa 3.0 with attribution.