在 linux 中,我如何從檔案中讀取至少 32 個位元組(或 4K),但給它一個 32MB 的緩沖區并讓它盡可能多地填充?(即如果整個檔案或其中的一半都準備好了,不要只給我第一個塊)
我不想要 EAGAIN 值。我希望它阻塞,直到至少 X 量的資料準備好
uj5u.com熱心網友回復:
這是做什么read的:
如果沒有可用資料,它會等到資料可用。
如果/當有資料可用時,它會回傳指定數量的所有可用資料。
例如,假設您想閱讀至少 4 KiB,而您要求閱讀 64 KiB。如果有 8 KiB 可用,read將立即回傳該 8 KiB。(它不會等待另一個 56 KiB 到達。)
同樣,如果最初只有 2 KiB 可用,read將回傳。沒有辦法告訴系統等到 4 KiB 可用。read所以這意味著如果我們想獲得最低金額,我們需要打電話。
ssize_t read_min( int fd, void *buf, size_t max_to_read, size_t min_to_read ) {
if ( min_to_read > SSIZE_MAX )
min_to_read = SSIZE_MAX;
if ( max_to_read > SSIZE_MAX )
max_to_read = SSIZE_MAX;
size_t total_read = 0;
while ( total_read < min_to_read ) {
ssize_t bytes_read = read( fd, buf total_read, max_to_read );
if ( bytes_read < 0 )
return -1;
if ( bytes_read == 0 )
return total_read;
max_to_read -= bytes_read;
total_read = bytes_read;
}
return total_read;
}
uj5u.com熱心網友回復:
select()或者,您可以對檔案描述符使用阻塞呼叫。
- 我們假設檔案不斷被寫入,如日志檔案或 CDR 檔案。
- 當您沒有
timeout在select()呼叫中指定時,它會阻塞直到檔案描述符可用于讀/寫,在我們的例子中僅用于讀取。 - 使用
FD_SET我們設定我們的fd,select()等待直到它準備好閱讀。 - 回傳時
select,驗證是否fd確實準備好使用FD_ISSET宏進行讀取。 - 重復這些步驟,直到您讀取了足夠的資料以滿足您的要求。
sockets這是用于在標頭/型別值之后讀取預期有效負載/資料的常用方法。
// assumes buf_sz > read_min
ssize_t read_min (const int fd, void *buf, size_t buf_sz, size_t read_min) {
if (buf_sz > SSIZE_MAX) buf_sz = SSIZE_MAX;
if (read_min > buf_sz) read_min = buf_sz;
ssize_t total = 0;
ssize_t bytes_read = 0;
while (total < read_min) {
fd_set rfds;
FD_ZERO (&rfds);
FD_SET (fd, &rfds);
int status = select (fd 1, &rfds, NULL, NULL, NULL); // blocking call
if (-1 == status)
perror ("read_min-select()");
if (FD_ISSET (fd, &rfds)) {
bytes_read = read (fd, buf total, buf_sz - total);
if (bytes_read > 0)
total = bytes_read;
if (bytes_read < 0)
perror ("read_min-read()");
/* if (0 == bytes_read) // EOF, do you want to return here?
return total;
*/
}
}
return total;
}
uj5u.com熱心網友回復:
沒有標準功能可以滿足我的要求:
- 執行一個阻塞直到它傳輸至少n個位元組的讀取,其中n > 1,然而
- 如果它可以這樣做而不會阻塞超過獲取n位元組所需的內容,則最多讀取n位元組。
但是,您可以在 之上構建自己的read()。 read()非常適合,因為(使用阻塞 I/O,默認值)它會在n == 1 的情況下執行您想要的操作。因此,如果您只是read()在同一個緩沖區中執行 s 直到您總共傳輸了至少n個位元組,或者到達檔案末尾或者出現錯誤,那么總體結果就是你描述的那樣。像這樣的東西:
ssize_t read_min(int fd, void *buf, size_t buf_size, size_t min_to_read) {
ssize_t total_read = 0;
ssize_t nread;
do {
n_read = read(fd, buffer total_read, buf_size - total_read);
} while (nread > 0 && total_read < min_to_read);
return (nread < 0) ? -1 : total_read;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/465347.html
