詳細(xì):
成都創(chuàng)新互聯(lián)公司是一家集網(wǎng)站建設(shè),文縣企業(yè)網(wǎng)站建設(shè),文縣品牌網(wǎng)站建設(shè),網(wǎng)站定制,文縣網(wǎng)站建設(shè)報(bào)價(jià),網(wǎng)絡(luò)營(yíng)銷,網(wǎng)絡(luò)優(yōu)化,文縣網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強(qiáng)企業(yè)競(jìng)爭(zhēng)力??沙浞譂M足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時(shí)我們時(shí)刻保持專業(yè)、時(shí)尚、前沿,時(shí)刻以成就客戶成長(zhǎng)自我,堅(jiān)持不斷學(xué)習(xí)、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實(shí)用型網(wǎng)站。
我一直覺得二進(jìn)制文件讀寫是個(gè)很容易的事,所以一直沒在意,最近在寫一個(gè)http客戶端,實(shí)現(xiàn)文件下載的時(shí)候,發(fā)現(xiàn)總有問題,后來才發(fā)現(xiàn)是忘記寫文件用二進(jìn)制方式,慚愧的很啊。然后,就在網(wǎng)上搜索了一下,發(fā)現(xiàn)通過C語言實(shí)現(xiàn)二進(jìn)制文件讀寫的資料居然出奇的少,這讓我很憤怒,因?yàn)殡m然這東西很簡(jiǎn)單,但是對(duì)于初學(xué)者,往往會(huì)需要花很長(zhǎng)的時(shí)間去弄,一旦明白,又發(fā)現(xiàn)花的時(shí)間很不值得,罷了,這里通過一個(gè)文件拷貝的例子來講講二進(jìn)制文件的讀寫吧。先介紹函數(shù),我們一共要用到三個(gè)函數(shù),fopen,fread,fwrite。二進(jìn)制讀寫的順序是用fopen以二進(jìn)制方式打開讀寫文件,然后使用fread和fwrite兩個(gè)函數(shù)將數(shù)據(jù)寫入二進(jìn)制文件中。下面我們看看一個(gè)拷貝程序的源碼:
Copy.c:#include stdio.h
#include stdlib.h
#define MAXLEN 1024
int main(int argc, char *argv[])
{
if( argc 3 )
{
printf("usage: %s %s\n", argv[0], "infile outfile");
exit(1);
}
FILE * outfile, *infile;
outfile = fopen(argv[2], "wb" );
infile = fopen(argv[1], "rb");
unsigned char buf[MAXLEN];
if( outfile == NULL || infile == NULL )
{
printf("%s, %s",argv[1],"not exit\n");
exit(1);
}
int rc;
while( (rc = fread(buf,sizeof(unsigned char), MAXLEN,infile)) != 0 )
{
fwrite( buf, sizeof( unsigned char ), rc, outfile );
}
fclose(infile);
fclose(outfile);
system("PAUSE");
return 0;
}
main()
{
FILE * stream;
int i;
stream = fopen("/tmp/fwrite","r");
fread(s,sizeof(struct test),nmemb,stream);
fclose(stream);
for(i=0;inmemb;i++)
printf("name[%d]=%-20s:size[%d]=%d/n",i,s[i].name,i,s[i].size);
}
供參考
你怎么輸出的?
二進(jìn)制如果以文本輸出,自然會(huì)有很多亂碼。
你可以用"%x"格式輸出看看
char
a;
a=fgetc(fp1);
printf("%c",
a);/*這樣肯定有亂碼*/
printf("%x",
a);/*這樣就是16進(jìn)制*/
用 fopen 打開文件時(shí) 設(shè) "rb" --用二進(jìn)制方法打開,用于讀
用 fread 讀取數(shù)據(jù),函數(shù)原型是:
size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );
各參數(shù)意義,請(qǐng)查編譯器幫助文件,這里就不開課了。
300×300 的數(shù)組需要的內(nèi)存量較大,可動(dòng)態(tài)分配,或用 全局量。
下面是程序例子。先建了一個(gè)2進(jìn)制文件,里面存了300*300個(gè)float型數(shù)據(jù)。然后讀這個(gè)文件里的內(nèi)容。
#includestdio.h
float a[300][300];
int main()
{
FILE *fin, *fout;
int i,j;
for (j=0;j300;j++) for (i=0;i300;i++) a[j][i]=j*100+i;
fout=fopen("a.txt","wb");
for (j=0;j300;j++)
fwrite(a[j][0],sizeof(float),300,fout);
fclose(fout);
for (j=0;j300;j++) for (i=0;i300;i++) a[j][i]=0; //數(shù)組清零
fin=fopen("a.txt","rb"); //打開輸入文件
for (j=0;j300;j++)
fread(a[j][0],sizeof(float),300,fin); //讀文件
fclose(fin); //關(guān)閉文件
// 下面輸出文件的左上角100個(gè)數(shù)據(jù),和右下角100個(gè)數(shù)據(jù)供檢查參考。
for (j=0;j10;j++) {
for (i=0;i10;i++)printf("%3.0f ",a[j][i]); printf("\n");}
printf("\n");
for (j=290;j300;j++){
for (i=290;i300;i++)printf("%g ",a[j][i]); printf("\n");}
return 0;
}
C語言中二進(jìn)制文件的讀取要用fread和fwrite來實(shí)現(xiàn)。
fwrite()與fprintf()是不同的。
fwrite將寫入的數(shù)據(jù)作為文件的磁盤內(nèi)容保存。fprintf將寫入的數(shù)據(jù)的每個(gè)字符所對(duì)應(yīng)的ASCII碼作為文件的磁盤內(nèi)容保存。fprintf做了一個(gè)轉(zhuǎn)換的工作。
當(dāng)打開文件時(shí),記事本會(huì)自動(dòng)把文件的磁盤內(nèi)容作為ASCII碼轉(zhuǎn)換成對(duì)應(yīng)的字符,然后再顯示出來,即顯示的是文本內(nèi)容而不是磁盤內(nèi)容。
例如,用fwrite向文件寫入“65”時(shí),文件的磁盤內(nèi)容就是保存的65(磁盤上以二進(jìn)制表示)。當(dāng)用記事本打開文件時(shí),記事本會(huì)讀到65,并把65看作一個(gè)ASCII碼,再把對(duì)應(yīng)的字符“A”顯示出來。因此屏幕上看到的文本內(nèi)容是“A”。
而用fprintf向文件寫入“65”時(shí),文件的磁盤內(nèi)容保存的是“6”和“5”這兩個(gè)字符對(duì)應(yīng)的ASCII碼,分別是54和53。因此文件的磁盤內(nèi)容是54和53。當(dāng)用記事本打開文件時(shí),記事本讀到54,就顯示出對(duì)應(yīng)的“6”。再讀到53,就顯示出對(duì)應(yīng)的“5”。
使用read()函數(shù)以下為百度百科的介紹
函數(shù)名:read
功 能:從文件中讀
函數(shù)原型 :int read(int handle, void *buf, int nbyte);
表頭文件:#include unistd.h
函數(shù)說明:read()會(huì)把參數(shù)handle所指的文件傳送nbyte個(gè)字節(jié)到buf指針?biāo)傅膬?nèi)存中。若參數(shù)nbyte為0,則read()不會(huì)有作用并返回0。返回值為實(shí)際讀取到的字節(jié)數(shù),如果返回0,表示已到達(dá)文件尾或無可讀取的數(shù)據(jù)。
程序例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include stdio.h
#include io.h
#include alloc.h
#include fcntl.h
#include process.h
#include sys\stat.h
int main(void)
{
void *buf;
int handle, bytes;
buf = malloc(10);
/*
Looks for a file in the current directory named TEST.$$$ and attempts
to read 10 bytes from it. To use this example you should create the
file TEST.$$$
*/
if ((handle =
open("TEST.$$$", O_RDONLY | O_BINARY, S_IWRITE | S_IREAD)) == -1)
{
printf("Error Opening File\n");
exit(1);
}
if ((bytes = read(handle, buf, 10)) == -1) {
printf("Read Failed.\n");
exit(1);
}
else {
printf("Read: %d bytes read.\n", bytes);
}
return 0;
}
2Linux C
編輯
定義函數(shù)
ssize_t read(int fd, void *buf, size_t count);
返回值
成功返回讀取的字節(jié)數(shù),出錯(cuò)返回-1并設(shè)置errno,如果在調(diào)read之前已到達(dá)文件末尾,則這次read返回0。
參數(shù)
參數(shù)count是請(qǐng)求讀取的字節(jié)數(shù),讀上來的數(shù)據(jù)保存在緩沖區(qū)buf中,同時(shí)文件的當(dāng)前讀寫位置向后移。注意這個(gè)讀寫位置和使用C標(biāo)準(zhǔn)I/O庫時(shí)的讀寫位置有可能不同,這個(gè)讀寫位置是記在內(nèi)核中的,而使用C標(biāo)準(zhǔn)I/O庫時(shí)的讀寫位置是用戶空間I/O緩沖區(qū)中的位置。比如用fgetc讀一個(gè)字節(jié),fgetc有可能從內(nèi)核中預(yù)讀1024個(gè)字節(jié)到I/O緩沖區(qū)中,再返回第一個(gè)字節(jié),這時(shí)該文件在內(nèi)核中記錄的讀寫位置是1024,而在FILE結(jié)構(gòu)體中記錄的讀寫位置是1。注意返回值類型是ssize_t,表示有符號(hào)的size_t,這樣既可以返回正的字節(jié)數(shù)、0(表示到達(dá)文件末尾)也可以返回負(fù)值-1(表示出錯(cuò))。
read函數(shù)返回時(shí),返回值說明了buf中前多少個(gè)字節(jié)是剛讀上來的。有些情況下,實(shí)際讀到的字節(jié)數(shù)(返回值)會(huì)小于請(qǐng)求讀的字節(jié)數(shù)count,例如:讀常規(guī)文件時(shí),在讀到count個(gè)字節(jié)之前已到達(dá)文件末尾。例如,距文件末尾還有30個(gè)字節(jié)而請(qǐng)求讀100個(gè)字節(jié),則read返回30,下次read將返回0。