Следующий код работает, но примерно в два раза неэффективен по сравнению с тем, когда я использую (linux) трубу, которая дает распакованные данные для (модифицированной) программы. Мне нужен постоянный поток внутри программы, который я могу продолжать раскалывать на \n
. Есть ли способ сделать это, используя поток (string?) Или любой другой трюк?Как реализовать поток, который может быть разделен символом новой строки
int main(int argc, char *argv[]) {
static const int unzipBufferSize = 8192;
long long int counter = 0;
int i = 0, p = 0, n = 0;
int offset = 0;
char *end = NULL;
char *begin = NULL;
unsigned char unzipBuffer[unzipBufferSize];
unsigned int unzippedBytes;
char * inFileName = argv[1];
char buffer[200];
buffer[0] = '\0';
bool breaker = false;
char pch[4][200];
Read *aRead = new Read;
gzFile inFileZ;
inFileZ = gzopen(inFileName, "rb");
while (true) {
unzippedBytes = gzread(inFileZ, unzipBuffer, unzipBufferSize);
if (unzippedBytes > 0) {
unzipBuffer[unzippedBytes] = '\0'; //put a 0-char after the total buffer
begin = (char*) &unzipBuffer[0]; // point to the address of the first char
do {
end = strchr(begin,(int)'\n'); //find the end of line
if (end != NULL) *(end) = '\0'; // put 0-char to use it as a c-string
pch[p][0] = '\0'; \\ put a 0-char to be able to strcat
if (strlen(buffer) > 0) { // if buffer from previous iteration contains something
strcat(pch[p], buffer); // cat it to the p-th pch
buffer[0] = '\0'; \\ set buffer to null-string or ""
}
strcat(pch[p], begin); // put begin (or rest of line in case there was a buffer into p-th pch
if (end != NULL) { // see if it already points to something
begin = end+1; // if so, advance begin to old end+1
p++;
}
if(p>3) { // a 'read' contains 4 lines, so if p>3
strcat(aRead->bases,pch[1]); // we use line 2 and 4 as
strcat(aRead->scores,pch[3]); // bases and scores
//do things with the reads
aRead->bases[0] = '\0'; //put them back to 0-char
aRead->scores[0] = '\0';
p = 0; // start counting next 4 lines
}
}
while (end != NULL);
strcat(buffer,pch[p]); //move the left-over of unzipBuffer to buffer
}
else {
break; // when no unzippedBytes, exit the loop
}
}
Почему бы не использовать, например. [Библиотека Boost iostreams] (http://www.boost.org/doc/libs/1_58_0/libs/iostreams/doc/index.html), которые имеют классы для gzipped-файлов. Затем вы можете использовать обычную 'std :: getline' для чтения по строковой основе. –
Цель этой программы - быть как можно быстрее. Я ошибаюсь, полагая, что использование библиотеки C++, такой как Boost, будет не таким быстрым, как если бы мы сохранили это на C, используя c-строки? – Niels
Также мне очень интересно, как это можно сделать самым простым способом, без использования внешних библиотек. Одной из целей zlib должно быть прямое использование данных, которые извлекаются, не так ли? Без необходимости использования других библиотек ... – Niels