我正在從C應用程序中的bzip2
流中提取數據。由於數據塊出來解壓的,他們可以寫入stdout
:如何處理基於C的應用程序內部的數據流?
fwrite(buffer, 1, length, stdout);
這個偉大的工程。當它被髮送到stdout
時,我得到所有的數據。
而不是寫入stdout
,我想在單行塊內部處理這個語句的輸出:一個以換行符\n
終止的字符串。
我是否將解壓器流的輸出寫入另一個緩衝區,一次一個字符,直到我點擊一個換行符,然後調用per-line處理函數?這是否緩慢,是否有更明智的做法?謝謝你的建議。
編輯
感謝您的建議。我最終創建了一對緩衝區,在每次通過輸出緩衝區的數據時,在短行緩衝區的開始處存儲剩餘部分(輸出緩衝區末尾的「stub」)。
我一個接一個地循環輸出緩衝區,一次處理換行符的數據。無換行符的餘數被分配並分配,並被複制到下一個流的行緩衝區。看起來好像realloc
比重複malloc-free
陳述便宜。
這是我想出了代碼:
char bzBuf[BZBUFMAXLEN];
BZFILE *bzFp;
int bzError, bzNBuf;
char bzLineBuf[BZLINEBUFMAXLEN];
char *bzBufRemainder = NULL;
int bzBufPosition, bzLineBufPosition;
bzFp = BZ2_bzReadOpen(&bzError, *fp, 0, 0, NULL, 0); /* http://www.bzip.org/1.0.5/bzip2-manual-1.0.5.html#bzcompress-init */
if (bzError != BZ_OK) {
BZ2_bzReadClose(&bzError, bzFp);
fprintf(stderr, "\n\t[gchr2] - Error: Bzip2 data could not be retrieved\n\n");
return -1;
}
bzError = BZ_OK;
bzLineBufPosition = 0;
while (bzError == BZ_OK) {
bzNBuf = BZ2_bzRead(&bzError, bzFp, bzBuf, sizeof(bzBuf));
if (bzError == BZ_OK || bzError == BZ_STREAM_END) {
if (bzBufRemainder != NULL) {
/* fprintf(stderr, "copying bzBufRemainder to bzLineBuf...\n"); */
strncpy(bzLineBuf, bzBufRemainder, strlen(bzBufRemainder)); /* leave out \0 */
bzLineBufPosition = strlen(bzBufRemainder);
}
for (bzBufPosition = 0; bzBufPosition < bzNBuf; bzBufPosition++) {
bzLineBuf[bzLineBufPosition++] = bzBuf[bzBufPosition];
if (bzBuf[bzBufPosition] == '\n') {
bzLineBuf[bzLineBufPosition] = '\0'; /* terminate bzLineBuf */
/* process the line buffer, e.g. print it out or transform it, etc. */
fprintf(stdout, "%s", bzLineBuf);
bzLineBufPosition = 0; /* reset line buffer position */
}
else if (bzBufPosition == (bzNBuf - 1)) {
bzLineBuf[bzLineBufPosition] = '\0';
if (bzBufRemainder != NULL)
bzBufRemainder = (char *)realloc(bzBufRemainder, bzLineBufPosition);
else
bzBufRemainder = (char *)malloc(bzLineBufPosition);
strncpy(bzBufRemainder, bzLineBuf, bzLineBufPosition);
}
}
}
}
if (bzError != BZ_STREAM_END) {
BZ2_bzReadClose(&bzError, bzFp);
fprintf(stderr, "\n\t[gchr2] - Error: Bzip2 data could not be uncompressed\n\n");
return -1;
} else {
BZ2_bzReadGetUnused(&bzError, bzFp, 0, 0);
BZ2_bzReadClose(&bzError, bzFp);
}
free(bzBufRemainder);
bzBufRemainder = NULL;
我真的很感謝大家的幫助。這很好。
strtok可以節省您檢查緩衝區中每個字符的換行符。 – Tumas 2010-10-13 11:30:13
'strtok'就是我以前試過的,但它不適用於我,而且我失去了數據,因爲從bzip2解壓縮器中輸出的輸出緩衝區被分割成一行。最後我失去了那一點。也許我錯誤地使用了它。有沒有使用'strtok'來保留無換行符的「存根」,將那個存根粘貼到下一個輸出緩衝塊的開始處? – 2010-10-13 11:33:04
不,你說得對,strtok不太適合這裏。如果你使用strtok,那麼你會失去這一點,並且可能更容易檢查每個字符。正如Opera所描述的那樣,我不知道有什麼聰明的方式來保存這個不需要新行的「存根」,以備以後使用,除非手動完成。對不起,誤導你一下:) – Tumas 2010-10-13 11:56:39