在 iOS 中对接收到的网络数据(NSData)进行文件读写
2015-08-26 14:59
483 查看
在 c 语言中,文件操作都是由库函数来实现的,主要是分为读和写两种操作:
这个结构体是系统自己定义的,定义在stdio.h头文件中,取名为FILE。也就是说FILE是系统名称,不可改变的,不是自定义。
所以只要程序用到一个文件,系统就为此文件开辟一个如上的结构体变量。需要几个文件,系统就开辟几个这样的结构体。
这些结构体变量不用变量名来标识,而是通过指向结构体类型的指针变量去访问,这就是文件指针。
比如:FILE *fp1,*fp2,*fp3; 当引用文件时,就可以把这个文件的结构体首地址赋给某个文件指针(*fp1),通过*fp1就可以调用结构体以找到相关的信息。
一般来说,有多少个文件就有多少个结构体,有多少结构体就有多少个文件指针。
对磁盘文件的操作必须是先打开,然后读写操作,最后关闭。
mode:文件打开方式
返回值:文件顺利打开后,返回指向该流的文件指针。如果文件打开失败则返回NULL,并把错误代码存在errno中。(errno
是记录系统的最后一次错误代码。代码是一个int型的值,在errno.h中定义)
其中文件打开方式主要有一下几种:
总结为:r为读 w为写 b为二进制文件 a为追加 +为读写。可以组合使用
返回 0,否则返回EOF(-1)。(如果流为NULL,而且程序可以继续执行,fclose设定error number给EINVAL,并返回EOF。)
0。
buffer:用于接收数据的内存地址。
size:要读的每个数据项的字节数,单位是字节(byte)。
count:要读count个数据项,每个数据项size个字节。
stream:文件输入流
返回值:实际读取的元素个数。如果返回值与count不相同,则可能文件结尾或发生错误。从ferror和feof获取错误信息或检测是否到达文件结尾。
buffer:是一个指针,对fwrite来说,是要获取数据的地址(即数据来源地址)。
size:要写入内容的单字节数。
count:要进行写入size字节的数据项的个数。
stream:目标文件指针。
返回值:返回实际写入的数据块数目。
stream:文件指针。
offset:偏移量。
fromwhere:指针的起始位置,为下列其中一种
* SEEK_SET:从距离文件开头 offset 位移量为新的读写位置;
* SEEK_CUR :以目前的读写位置往后增加 offset 个位移量;
* SEEK_END :将读写位置指向文件末尾后再增加 offset 个位移量。
strem:文件指针。(注意:文件指针必须是有效的,且必须指向一个通过 fopen() 或 popen() 成功打开的文件。在附加模式(加参数
"a" 打开文件)中 ftell() 会返回未定义错误。)
返回值:
约束:因为ftell返回long型,根据long型的取值范围-231~231-1(-2147483648~2147483647),故对大于2.1G的文件进行操作时出错。
fd:为已打开的文件描述词,而且必须是以写入模式打开的文件。
length:要改成的大小,如果原来的文件大小比参数length大,则超过的部分会被删去。
返回值:执行成功则返回0,失败返回-1,错误原因存于errno。
错误代码:
EBADF 参数fd文件描述词为无效的或该文件已关闭。
EINVAL 参数fd 为一socket 并非文件,或是该文件并非以写入模式打开。
说明:fd一般可以fileno(FILE *fp)获取,标示文件当前的大小,lenggth则可由用户定义。此函数一般用在文件初始化或者重新为文件分配空间时。
stream:文件输入流。
返回值:某个数据流的文件描述符。
下面简单讲一下在iOS 下,对NSData 的文件读写:
此博文源自 /article/11517861.html
如需转载,请说明博文出处。谢谢!
文件指针
平常所说的文件不同于其他常见的数据类型,比如一个test.txt文档,它有自己的一些属性,比如文件的当前位置、与该文件对应的内存缓冲区地址、文件操作方式等等。对于这些信息都会专门开辟一定内存空间来存储。而且是保存在一个结构体类型的变量中,比如:struct { int fd; //文件号 int cleft; //缓冲区中剩下的字符 int mode; //文件操作模式 char *nextc; //下一个字符位置 char *buff; //文件缓冲区位置 }FILE; /*FILE是一个存储文件信息的结构体类型的变量*/在上述代码中可以看到,文件号、文件操作模式等信息都存储在一个结构体中。
这个结构体是系统自己定义的,定义在stdio.h头文件中,取名为FILE。也就是说FILE是系统名称,不可改变的,不是自定义。
所以只要程序用到一个文件,系统就为此文件开辟一个如上的结构体变量。需要几个文件,系统就开辟几个这样的结构体。
这些结构体变量不用变量名来标识,而是通过指向结构体类型的指针变量去访问,这就是文件指针。
比如:FILE *fp1,*fp2,*fp3; 当引用文件时,就可以把这个文件的结构体首地址赋给某个文件指针(*fp1),通过*fp1就可以调用结构体以找到相关的信息。
一般来说,有多少个文件就有多少个结构体,有多少结构体就有多少个文件指针。
对磁盘文件的操作必须是先打开,然后读写操作,最后关闭。
打开文件
函数原型
FILE * fopen(const char * path,const char * mode);path:需要打开的文件路径
mode:文件打开方式
返回值:文件顺利打开后,返回指向该流的文件指针。如果文件打开失败则返回NULL,并把错误代码存在errno中。(errno
是记录系统的最后一次错误代码。代码是一个int型的值,在errno.h中定义)
其中文件打开方式主要有一下几种:
文件使用方式 | 含义 |
“r”(只读) | 为输入打开一个文本文件 |
“w”(只写) | 为输出打开一个文本文件 |
“a”(追加) | 为文本文件尾增加数据 |
“rb”(只读) | 为输入打开一个二进制文件 |
“wb”(只写) | 为输出打开一个二进制文件 |
“ab”(追加) | 向二进制文件尾增加数据 |
“r+”(读写) | 为读写打开一个文本文件 |
“w+”(读写) | 为读写打开一个新的文本文件 |
“a+”(读写) | 为读写打开一个文本文件 |
“rb+”(读写) | 为读写打开一个二进制文件 |
“wb+”(读写) | 为读写建立一个新的二进制文件 |
“ab+”(读写) | 为读写打开一个二进制文件 |
“t”(文本文件)可以省略不写 |
关闭文件
函数原型:int fclose( FILE *fp );返回值:如果流成功关闭,fclose
返回 0,否则返回EOF(-1)。(如果流为NULL,而且程序可以继续执行,fclose设定error number给EINVAL,并返回EOF。)
读写文件
常用的文件读写函数主要有:字符读写函数:fgetc() 和 fputc (getc 和 putc)
字符串读写函数:fgets() 和 fputs()
数据块读写函数:fread() 和 fwrite()
格式化读写函数:fscanf() 和 fprintf()
fread()
函数原型
size_t fread ( void *buffer, size_t size, size_t count, FILE *stream) ;功能:从一个文件流中读数据,最多读取count个元素,每个元素size字节,如果调用成功返回实际读取到的元素个数,如果不成功或读到文件末尾返回
0。
buffer:用于接收数据的内存地址。
size:要读的每个数据项的字节数,单位是字节(byte)。
count:要读count个数据项,每个数据项size个字节。
stream:文件输入流
返回值:实际读取的元素个数。如果返回值与count不相同,则可能文件结尾或发生错误。从ferror和feof获取错误信息或检测是否到达文件结尾。
fwrite()
函数原型
size_t fwrite(const void* buffer, size_t size, size_t count, FILE* stream);功能:向文件写入一个数据块(注意:这个函数以二进制形式对文件进行操作,不局限于文本文件)。
buffer:是一个指针,对fwrite来说,是要获取数据的地址(即数据来源地址)。
size:要写入内容的单字节数。
count:要进行写入size字节的数据项的个数。
stream:目标文件指针。
返回值:返回实际写入的数据块数目。
fseek()
函数原型
int fseek(FILE *stream, long offset, int fromwhere);功能:重定位流(数据流/文件)上的文件内部位置指针(即:可以移动文件的读写指针到指定的位置,即移动当前文件的位置指针)。如果执行失败(比如offset超过文件自身大小),则不改变stream指向的位置。
stream:文件指针。
offset:偏移量。
fromwhere:指针的起始位置,为下列其中一种
* SEEK_SET:从距离文件开头 offset 位移量为新的读写位置;
* SEEK_CUR :以目前的读写位置往后增加 offset 个位移量;
* SEEK_END :将读写位置指向文件末尾后再增加 offset 个位移量。
ftell()
函数原型
long ftell(FILE *stream);功能:用于获取文件位置指针当前位置相对于文件首的偏移字节数。(使用fseek()后再调用函数ftell()就能非常容易地确定文件的当前位置。)
strem:文件指针。(注意:文件指针必须是有效的,且必须指向一个通过 fopen() 或 popen() 成功打开的文件。在附加模式(加参数
"a" 打开文件)中 ftell() 会返回未定义错误。)
返回值:
handle指定的文件指针的位置,也就是文件流中的偏移量。如果出错,返回 FALSE。
约束:因为ftell返回long型,根据long型的取值范围-231~231-1(-2147483648~2147483647),故对大于2.1G的文件进行操作时出错。
改变文件大小
ftruncate()
函数原型int ftruncate(int fd,off_t length);功能:将参数fd指定的文件大小改为参数length指定的大小。
fd:为已打开的文件描述词,而且必须是以写入模式打开的文件。
length:要改成的大小,如果原来的文件大小比参数length大,则超过的部分会被删去。
返回值:执行成功则返回0,失败返回-1,错误原因存于errno。
错误代码:
EBADF 参数fd文件描述词为无效的或该文件已关闭。
EINVAL 参数fd 为一socket 并非文件,或是该文件并非以写入模式打开。
说明:fd一般可以fileno(FILE *fp)获取,标示文件当前的大小,lenggth则可由用户定义。此函数一般用在文件初始化或者重新为文件分配空间时。
fileno()
函数原型int _fileno( FILE *stream );功能:用来取得参数stream指定的文件流所使用的文件描述符。
stream:文件输入流。
返回值:某个数据流的文件描述符。
下面简单讲一下在iOS 下,对NSData 的文件读写:
读文件
/* * === FUNCTION ================================================== * Name: readDataToBuffer:fromPath: * Description: 从指定 path 的文件读取内容到 buffer * ================================================================= */ -(void)readDataToBuffer:(char *)buffer fromPath:(NSString *)path { FILE *p_r= fopen([path cStringUsingEncoding:NSUTF8StringEncoding], "r"); //打开文件 if (NULL == p_r) { NSLog(@"Open file error to read data !"); return ; } fseek(p_r, 0, SEEK_END); //定位到文件末尾 NSInteger dataLength = ftell(p_r); //获取文件长度 fseek(p_r, 0, SEEK_SET); //定位到文件起始位置 fread(buffer, dataLength, 1, p_r); //读取文件到指定的缓冲区 fclose(p_r); //关闭文件 }
写文件
/* * === FUNCTION ================================================== * Name: writeData:toPath: * Description: 把数据写到指定的文件中 * ================================================================= */ -(void)writeData:(NSData *)data toPath:(NSString *)path { FILE *p_w= fopen([path cStringUsingEncoding:NSUTF8StringEncoding], "ab"); //已追加二进制方式打开文件 if (NULL == p_w) { NSLog(@"Open file error to write data!"); return ; } fseek(p_w, 0, SEEK_END); // 移到文件末尾 fwrite((void *)[data bytes], data.length, 1, p_w); // 写入数据 data = nil; fclose(p_w); //关闭文件 }
此博文源自 /article/11517861.html
如需转载,请说明博文出处。谢谢!
相关文章推荐
- HttpClient读取ASP.NET Web API错误信息的简单方法
- Fetching https://dl-ssl.google.com/android/
- 通过httpclient向服务器传送数据并获得返回值
- Tomcat配置HTTPS
- 网络敲诈勒索案:不交保护费 就让你服务器瘫痪
- netty4发送HttpRequest及HttpReponse太大的问题(半包)
- Neural Networks for Machine Learning by Geoffrey Hinton (6)
- [python] TCP客户端/服务器端
- 设置网络:跳转至系统设置页
- Android学习笔记:Andorid网络请求框架Volley的使用(中)--网络图片加载
- Angular 设置http
- unity3d的网络使用的简单Demo
- 在Ubuntu QML应用中使用WebSocket建立TCP/IP连接
- 我的openwrt学习笔记(二十二):网络时间同步
- Android中解决网络连接异常
- Android OkHttp完全解析 是时候来了解OkHttp了
- 打开tcp_tw_recycle引起的一次投诉分析
- XMLHTTPRequest状态status完整列表
- 我的openwrt学习笔记(二十一):广域网IP地址获取_socket http
- get/post方式调用http接口