Использование памяти CHCSVWriter для записи больших файлов CSV

В то время как верхние ответы просты и эффективны, они не устанавливают MSB для случая, когда n=0 и m=31:

~(~0 << 31) << 0 = 0111 1111 1111 1111 1111 1111 1111 1111‬

((1 << 31)-1) << 0 = 0111 1111 1111 1111 1111 1111 1111 1111‬

Мое предложение для 32-битного слова без знака (которое является уродливым и имеет ветвь) выглядит следующим образом:

unsigned int create_mask(unsigned int n,unsigned int m) {
  // 0 <= start_bit, end_bit <= 31
  return (m - n == 31 ? 0xFFFFFFFF : ((1 << (m-n)+1)-1) << n);
}

на самом деле получает бит в диапазоне [m,n] (закрытый интервал), поэтому create_mask(0,0) вернет маску для первого бита (бит 0) и create_mask(4,6) возвращает маску для битов с 4 по 6, т.е. ... 00111 0000.

0
задан silentBob 20 March 2019 в 08:17
поделиться

1 ответ

Если вы не хотите использовать много памяти при создании большого файла CSV, не создавайте поток вывода на основе памяти. Создайте поток вывода в фактический файл. Тогда данные CSV будут записаны в файл, а не в память. Тогда файл может быть гигабайтным и использовать очень мало памяти.

Это дает дополнительное преимущество: нет необходимости обращаться к данным буфера, создавать из них строку (теперь удваивает использование памяти), а затем записывать строку в файл.

NSOutputStream *csvStream = [NSOutputStream outputStreamToFileAtPath:csvPath append:NO];
[csvStream open];
CHCSVWriter *writer = [[CHCSVWriter alloc] initWithOutputStream:csvStream encoding:NSUTF8StringEncoding delimiter:';'];

// write your CSV entries

[writer closeStream];

Вот и все. Никакого другого кода, необходимого для создания файла.

В дополнение к этим изменениям вам необходимо изменить место использования пула автоматического выпуска. Он должен быть внутри внешней петли for.

//> write the rows
for (NSMutableDictionary *row in [self sharedUploadManager].modifiedRows) {
    @autoreleasepool {
        NSArray *orderedKeys = [[row allKeys] sortedArrayUsingDescriptors:keySortDescriptors];

        for (NSString *key in orderedKeys ) {

            NSString *field = [row objectForKey:key];
            if ([field isKindOfClass:[NSNull class]]) {
                [writer writeField:nil];
            } else {
                [writer writeField:field];
            }
        }

        //> finish the line
        [writer finishLine];
    }
}

Это обеспечит очистку памяти автоматически освобожденных объектов после каждой строки.

0
ответ дан rmaddy 20 March 2019 в 08:17
поделиться