Читайте в Python сжатые данные в C, используя zlib - PullRequest
0 голосов
/ 09 апреля 2019

У меня есть код C, который записывает несколько файлов данных для симуляции физики. Эти файлы данных в основном представляют собой текстовые файлы, содержащие двухмерную карту значений в диапазоне от -1 до +1. Они могут быть довольно большими (около 100 Мбайт каждый), но, поскольку многие значения обычно одинаковы (длинные строки +1 или -1), я подумал, что сжатие их было бы хорошей идеей.

Соответствующая часть кода C, которая записывала файл, была такой:

FILE *fp1;
char file1[] = "output_file.dat";
fp1 = fopen(file1,"w");
for ( i = 0; i < Nx; i++ ) {
    for ( j = 0; j < Ny; j++ ) {
        fprintf(fp1, "%.5f ", creal(phi[i*Ny+j]));
    }
    fprintf(fp1, "\n");
}
fclose(fp1);

И соответствующая часть кода Python, которая была читает файл был:

import numpy as np
data = np.loadtxt("output_file.dat")

Теперь я пытаюсь добавить сжатие с помощью библиотеки zlib. Я изменил код C следующим образом:

# include <zlib.h>
gzFile fp1;
char file1[] = "output_file.dat";
fp1 = gzopen(file1,"w");
for ( i = 0; i < Nx; i++ ) {
    for ( j = 0; j < Ny; j++ ) {
        gzprintf(fp1, "%.5f ", creal(phi[i*Ny+j]));
    }
    gzprintf(fp1, "\n");
}
gzclose(fp1);

И код Python:

import numpy as np
import zlib
compressed_data = open("output_file.dat", 'rb').read() 
data = zlib.decompress(compressed_data)

Кажется, код C работает хорошо. Файлы данных записываются и имеют размер менее 2 Мб (что разумно, учитывая избыточность содержимого). К сожалению, скрипт Python выдает мне ошибку:

error: Error -3 while decompressing data: incorrect header check

Кто-нибудь может указать мне правильное направление, как отладить это? Спасибо!

1 Ответ

0 голосов
/ 10 апреля 2019

Хорошо, решение оказалось очень простым. В основном, если я пишу файлы данных, используя расширение .gz:

# include <zlib.h>
gzFile fp1;
char file1[] = "output_file.gz";
fp1 = gzopen(file1,"w");
for ( i = 0; i < Nx; i++ ) {
    for ( j = 0; j < Ny; j++ ) {
        gzprintf(fp1, "%.5f ", creal(phi[i*Ny+j]));
    }
    gzprintf(fp1, "\n");
}
gzclose(fp1);

Затем я могу использовать функцию loadtext для их чтения, и они будут автоматически распакованы с помощью numpy:

import numpy as np
data = np.loadtxt("output_file.gz")

В качестве альтернативы, я все еще мог бы использовать функцию zlib.decompress, но передав ей еще один аргумент (как объяснено в этом вопросе):

zlib.decompress(compressed_data, 15 + 32)
...