C语言实现二进制文件读写

我一直觉得二进制文件读写是个很容易的事,所以一直没在意,最近在写一个http客户端,实现文件下载的时候,发现总有问题,后来才发现是忘记写文件用二进制方式,惭愧的很啊。
然后,就在网上搜索了一下,发现通过C语言实现二进制文件读写的资料居然出奇的少,这让我很愤怒,因为虽然这东西很简单,但是对于初学者,往往会需要花很长的时间去弄,一旦明白,又发现花的时间很不值得

#include <string>

#include <fstream>

#include <iostream>
using  namespace  std;
  
typedef  struct
{
    int  x;
    int  y;
}point_t;
  
int  main(int  argc, char* argv[])
{
    /* 二进制文件的写入 */
    ofstream ofs("test.dat", ios::binary);
    /* 写入字符串 */
    string a = "You are welcome!"
    int  n = a.size();
    ofs.write((char*)&n, sizeof(int));
    ofs.write(a.c_str(), sizeof(char) * n);
    /* 写入结构体 */
    point_t b = {80, 51};
    ofs.write((char*)&b, sizeof(point_t));
    ofs.close();    
  
    /* 二进制文件读取 */
    ifstream ifs("test.dat", std::ios::binary);
    /* 读取字符串 */
    int  m;
    ifs.read((char*)&m, sizeof(int));
    char* c = new  char[m + 1];
    ifs.read(c, sizeof(char) * m);
    c[m] = '\0';
    /* 读取结构体 */
    point_t d;
    ifs.read((char*)&d, sizeof(point_t));
    ifs.close();
  
    /* 显示读取数据 */
    cout << c << endl;
    cout << '('  << d.x << ','  << d.y << ')'  << endl;
  
    return  0;
}




后面是关于fopen,fread,fwrite三个函数的详细说明。

fopen(打开文件)
相关函数
open,fclose
表头文件
#include<stdio.h>
定义函数
FILE * fopen(const char * path,const char * mode);
函数说明
参数path字符串包含欲打开的文件路径及文件名,参数mode字符串则代表着流形态。
mode 有下列几种形态字符串 :
r 打开只读文件,该文件必须存在。

r+  打开可读写的文件,该文件必须存在。
打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失。若文件不存在
则建立该文件。
w+  打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件
不存在则建立该文件。
以附加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,
写入的数据会被加到文件尾,即文件原先的内容会被保留。
a+  以附加方式打开可读写的文件。若文件不存在,则会建立该文件,如果文件存在,
写入的数据会被加到文件尾后,即文件原先的内容会被保留。
上述的形态字符串都可以再加一个b字符,如rb、w+b或ab+等组合,加入b 字符
用来告诉函数库打开的文件为二进制文件,而非纯文字文件。不过在POSIX系统,
包含Linux都会忽略该字符。由fopen()所建立的新文件会具有S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH(0666)权限,
此文件权限也会参考umask值。
返回值
文件顺利打开后,指向该流的文件指针就会被返回。若果文件打开失败则返回NULL,
并把错误代码存在errno 中。
附加说明
一般而言,开文件后会作一些文件读取或写入的动作,若开文件失败,接下来的读写
动作也无法顺利进行,所以在fopen()后请作错误判断及处理。
范例
#include<stdio.h>
main()
{
FILE * fp;
fp=fopen("noexist","a+");
if(fp= =NULL) return;
fclose(fp);
}

 

fread(从文件流读取数据)
相关函数
fopen,fwrite,fseek,fscanf
表头文件
#include<stdio.h>
定义函数
size_t fread(void * ptr,size_t size,size_t nmemb,FILE * stream);
函数说明
fread()用来从文件流中读取数据。参数stream为已打开的文件指针,参数ptr 指向
欲存放读取进来的数据空间,读取的字符数以参数size*nmemb来决定。Fread()会
返回实际读取到的nmemb数目,如果此值比参数nmemb 来得小,则代表可能读到
了文件尾或有错误发生,这时必须用feof()或ferror()来决定发生什么情况。
返回值
返回实际读取到的nmemb数目。
附加说明

 

 
范例
#include<stdio.h>
#define nmemb 3
struct test
{
char name[20];
int size;
}s[nmemb];
main()
{
FILE * stream;
int i;
stream = fopen("/tmp/fwrite","r");
fread(s,sizeof(struct test),nmemb,stream);
fclose(stream);
for(i=0;i<nmemb;i++)
printf("name[%d]=%-20s:size[%d]=%d\n",i,s[i].name,i,s[i].size);
}
执行
name[0]=Linux! size[0]=6
name[1]=FreeBSD! size[1]=8
name[2]=Windows2000 size[2]=11

 

fwrite(将数据写至文件流)
相关函数
fopen,fread,fseek,fscanf
表头文件
#include<stdio.h>
定义函数
size_t fwrite(const void * ptr,size_t size,size_t nmemb,FILE * stream);
函数说明
fwrite()用来将数据写入文件流中。参数stream为已打开的文件指针,参数ptr 指向
欲写入的数据地址,总共写入的字符数以参数size*nmemb来决定。Fwrite()会返回
实际写入的nmemb数目。
返回值
返回实际写入的nmemb数目。
范例
#include<stdio.h>
#define set_s (x,y) {strcoy(s[x].name,y);s[x].size=strlen(y);}
#define nmemb 3
struct test
{
char name[20];
int size;
}s[nmemb];
main()
{
FILE * stream;
set_s(0,"Linux!");
set_s(1,"FreeBSD!");
set_s(2,"Windows2000.");
stream=fopen("/tmp/fwrite","w");
fwrite(s,sizeof(struct test),nmemb,stream);
fclose(stream);
}
执行
参考fread()。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值