C語言 檔案大小,分配空間,讀入檔案,寫入檔案,實現複製的功能
阿新 • • 發佈:2018-11-02
首先通過兩種方法得到檔案的大小,位元組為單位,根據這個大小使用malloc分配固定的空間buffer,二進位制流讀入檔案,把二進位制流寫入buffer中,buffer輸出寫入到新的檔案。
原始檔1.txt,輸出檔案1.txt.txt
環境為Ubuntu 16.04,gcc
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
//get file size
int file_size(char *filename)
{
struct stat statbuf;
stat(filename, &statbuf);
int size = statbuf.st_size;
printf("the size of file %s is : %d byte\n", filename, size);
return size;
}
long file_size2(FILE *file)
{
/* 獲取檔案大小 */
fseek (file, 0, SEEK_END);
long lSize;
lSize = ftell (file);
rewind (file) ;//point back to the begin
printf("the size of file is : %ld byte\n", lSize);
return lSize;
}
//inputName: 1.txt -> outputName:1.txt.txt
void initOutname(char *filename)
{
int nameLen = strlen(filename), suffixLen = 0;
char *first = strrchr(filename, '.');
if (first == NULL) return ;
strcat(filename, first);
}
int main(int argc, char *argv[])
{
char *buffer = NULL;
char filename[100];
if(argc == 1){
strcpy(filename, "1.txt");
}else if(argc == 2){
strcpy(filename, argv[1]);
}else {
printf("parameter ERROR!\n");
return -1;
}
int len = file_size(filename);
FILE *file = fopen(filename, "rb");
if (!file)
{
printf("%s: can not open %s\n", __func__, filename);
return -1;
}
long llen = file_size2(file);
//len bytes
buffer = malloc(llen);
// printf("%ld\n", sizeof(char));
if(NULL != buffer)
{
printf("success\n");
}
else
{
printf("the file is too large to load!\n");
return -1;
}
/* 將檔案拷貝到buffer中 */
size_t result = fread (buffer, 1, llen, file);
if (result != llen)
{
printf("fread ERROR\n");
return -1;
}
printf("%ld\n", result);
printf("%s\n", buffer);
initOutname(filename);
FILE *fileOut = fopen(filename, "w+");
if (!fileOut)
{
printf("%s: can not open %s\n", __func__, filename);
return -1;
}
result = fwrite(buffer, 1, llen, fileOut);
if (result != llen)
{
printf("%s: can not write %s\n", __func__, filename);
return -1;
}
fclose (fileOut);
fclose (file);
free(buffer);
return 0;
}
在測試大檔案(5G)大小時候,第一種方法測出只有1G,第二種方法比較準確,原因還未知,讀者知道的麻煩告訴下~
[email protected]:/workfile$ ./test /media/sf_share/16.04.vdi
the size of file /media/sf_share/16.04.vdi is : 1075838976 byte
the size of file is : 5370806272 byte
success
第一種方法是一次性申請讀入檔案大小的記憶體空間buffer,一次性寫入buffer,再輸出到檔案中,但檔案特別大時候,malloc時候就失敗了,解決方法是申請固定size大小的buffer,得到檔案的大小len,每次寫入size位元組的內容,更新len為len-size,剛開始判斷len<size,如果是的話則寫入len大小。最終退出迴圈時,len減為0
更新後的程式碼使用第二種檔案大小得到方法,程式碼如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXSIZE 32768
#include <sys/stat.h>
//inputName: 1.txt -> outputName:1.txt.txt
void initOutname(char *filename)
{
int nameLen = strlen(filename), suffixLen = 0;
char *first = strrchr(filename, '.');
if (first == NULL) return ;
strcat(filename, first);
}
long file_size2(FILE *file)
{
/* 獲取檔案大小 */
fseek (file, 0, SEEK_END);
long lSize;
lSize = ftell (file);
rewind (file);//point back to the begin
printf("the size of file is : %ld byte\n", lSize);
return lSize;
}
int main(int argc, char *argv[])
{
char *buffer = NULL;
char filename[100];
if(argc == 1)
{
strcpy(filename, "1.txt");
}
else if(argc == 2)
{
strcpy(filename, argv[1]);
}
else
{
printf("parameter ERROR!\n");
return -1;
}
FILE *file = fopen(filename, "rb");
if (!file)
{
printf("%s: can not open %s\n", __func__, filename);
return -1;
}
initOutname(filename);
FILE *fileOut = fopen(filename, "w");
fclose (fileOut);
fileOut = fopen(filename, "a+");
if (!fileOut)
{
printf("%s: can not open %s\n", __func__, filename);
return -1;
}
buffer = malloc(MAXSIZE);
if(NULL != buffer)
{
printf("success\n");
}
else
{
printf("%s the file is too large to load!\n", __func__);
return -1;
}
/* 將檔案拷貝到buffer中 */
int bytes_read = 0;
int onceSize = MAXSIZE;
int len = file_size2(file);
for(; len > 0; len -= onceSize)
{
if(len < MAXSIZE) onceSize = len;
fread (buffer, 1, onceSize, file);
fwrite(buffer, 1, onceSize, fileOut);
}
fclose (fileOut);
fclose (file);
free(buffer);
return 0;
}
其中開啟輸出檔案方式先使用w目的是新建並清空之前的檔案內容,再用二進位制追加a+的方式開啟。
判斷生成的檔案和原始檔的sha224的值:
[email protected]:/workfile/SHA$ ./sha sha224 ../1.txt
File('../1.txt'): a069a467f410fae0559382f1e45ec9a850e1e26472eac466588291c7
[email protected]:/workfile/SHA$ ./sha sha224 ../1.txt.txt
File('../1.txt.txt'): a069a467f410fae0559382f1e45ec9a850e1e26472eac466588291c7
其中讀入再寫入有一種簡單的寫法,思想和圖片一樣。讀入了byte_read位元組,那麼就寫入byte_read位元組到檔案中。
// int onceSize = MAXSIZE;
// int len = file_size2(file);
// for(; len > 0; len -= onceSize)
// {
// if(len < MAXSIZE) onceSize = len;
// fread (buffer, 1, onceSize, file);
// fwrite(buffer, 1, onceSize, fileOut);
// }
while(bytes_read=fread (buffer, 1, MAXSIZE, file))
fwrite(buffer, 1, bytes_read, fileOut);