我有獲取引數的函式:(char* filedata存盤整個檔案)和FILE *fp(打開的檔案)。
void read_file(char *filedata, FILE *fp){
char buffer[1000];
while(fgets(buffer, sizeof(buffer), fp))
{
char *new_str;
if((new_str = malloc(strlen(filedata) strlen(buffer) 1)) != NULL)
{
new_str[0] = '\0'; // ensures the memory is an empty string
strcat(new_str, filedata);
strcat(new_str, buffer);
}
else
{
printf("malloc failed!\n");
}
strcpy(filedata, new_str);
}
fclose(fp);
}
但這不是太快......有沒有更快的方法來讀取整個檔案?
uj5u.com熱心網友回復:
fread()需要注意的是,您可以使用函式一舉將整個檔案讀入適當大小的緩沖區。
以下代碼概述了如何打開檔案、確定其大小、分配該大小的緩沖區,然后將檔案的資料(全部)讀入該緩沖區。但請注意關于fseekandftell函式的注意事項(稍后討論):
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char* filename = "MyFile.txt"; // Or whatever
FILE* fp = fopen(filename, "rb"); // Open in binary mode
int seek = fseek(fp, 0, SEEK_END); // CAVEAT: Files in BINARY mode may not support SEEK_END ...
if (seek != 0) {
printf("Cannot fseek on binary file!\n");
fclose(fp);
return 1;
}
size_t filesize = (size_t)ftell(fp); // ... but this is not reliable if opened in TEXT mode!
char* filedata = calloc(filesize 1, 1); // Add 1 for the terminating "nul" character
rewind(fp);
fread(filedata, 1, filesize, fp); // Read whole file
// Clean up ...
fclose(fp);
free(filedata);
return 0;
}
注意事項:
請注意,在 BINARY 模式下打開的檔案(如我在呼叫中"rb"給出的模式引數)不需要支持對;的呼叫中的來源。如果您的平臺是這種情況,那么這個答案提供了一些替代方法來確定檔案的大小。從 cppreference:fopen()SEEK_ENDfseek()
… 二進制流不需要支持 SEEK_END,尤其是在輸出額外的空位元組時。
但是,另一方面,在 TEXT 模式下打開檔案(使用"rt")將使呼叫ftell實際上毫無意義,就輸入緩沖區所需的大小和指定的值而言fread;來自 cppreference:
如果流以文本模式打開,則此函式回傳的值未指定,僅作為 fseek() 的輸入才有意義。
uj5u.com熱心網友回復:
注釋您的函式(不提及泄漏等)并計算字符緩沖區上的操作:
void read_file(char *filedata, FILE *fp){
char buffer[1000];
while(fgets(buffer, sizeof(buffer), fp)) // <<-- NEW_SIZE
{
char *new_str;
if((new_str = malloc(strlen(filedata) // <<-- OLD_SIZE
strlen(buffer) // <<-- NEW_SIZE
1)) != NULL)
{
new_str[0] = '\0'; // ensures the memory is an empty string
strcat(new_str, filedata); // <<-- OLD_SIZE
strcat(new_str, buffer); // <<-- NEW_SIZE
}
else
{
printf("malloc failed!\n");
}
strcpy(filedata, new_str); // <<-- OLD_SIZE NEW_SIZE
}
fclose(fp);
}
fgets(). strlen(),strcat()并且strcpy()都需要遍歷字符緩沖區。只有fgets()實際需要,其余的復制可以避免。
添加通過緩沖區的次數:
每個回圈的操作總和:3 * OLD_SIZE 4 * NEW_SIZE 并且:請記住,OLD_SIZE 實際上是遞回的 SUM(NEW_SIZE),因此您的函式具有 QUADRATIC 行為wrt 回圈迭代的次數。(基本上是行數讀)
所以你最終得到:
Number of times a character is inspected
= 4 * N_LINE * LINE_SIZE
7 * (NLINE * (NLINE-1) ) * LINE_SIZE
;
[這就是“畫家施萊米爾”的故事]
uj5u.com熱心網友回復:
下面是我的功能,說明了我通常是如何做的。不確定它與所有其他可能的 C 實作相比有多快。但我想它們都非常相似,除非以一種或另一種方式編程不當,這可能會導致執行速度更慢、效率更低。
/* ==========================================================================
* Function: readfile ( FILE *ptr, int *nbytes )
* Purpose: read open file ptr into internal buffer
* --------------------------------------------------------------------------
* Arguments: ptr (I) FILE * to already open (via fopen)
* file, whose contents are to be read
* nbytes (O) int * returning #bytes in returned buffer
* --------------------------------------------------------------------------
* Returns: ( unsigned char * ) buffer with ptr's contents
* --------------------------------------------------------------------------
* Notes: o caller should free() returned output buffer ptr when finished
* ======================================================================= */
/* --- entry point --- */
unsigned char *readfile ( FILE *ptr, int *nbytes ) {
/* ---
* allocations and declarations
* ------------------------------- */
unsigned char *outbuff = NULL; /* malloc'ed and realloc'ed below */
int allocsz=0, reallocsz=500000, /*total #bytes allocated, #realloc */
blksz=9900, nread=0, /* #bytes to read, #actually read */
buffsz = 0; /* total #bytes in buffer */
/* ---
* collect all bytes from ptr
* ----------------------------- */
if ( ptr != NULL ) { /* return NULL error if no input */
while ( 1 ) { /* read all input from file */
if ( buffsz blksz 99 >= allocsz ) { /* first realloc more memory */
allocsz = reallocsz; /*add reallocsz to current allocation*/
if ( (outbuff=realloc(outbuff,allocsz)) == NULL ) /* reallocate */
goto end_of_job; } /* quit with NULL ptr if failed */
nread = fread(outbuff buffsz,1,blksz,ptr); /* read next block */
if ( nread < 1 ) break; /* all done, nothing left to read */
buffsz = nread; /* add #bytes from current block */
} /* --- end-of-while(1) --- */
fclose(ptr); /* close fopen()'ed file ptr */
} /* --- end-of-if(ptr!=NULL) --- */
end_of_job:
if ( nbytes != NULL ) *nbytes = buffsz; /* #bytes in outbuff */
return ( outbuff ); /* back to caller with output or NULL*/
} /* --- end-of-function readfile() --- */
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/418757.html
標籤:
