文章目录[隐藏]
1.2 基于Linux的文件操作
socket操作与文件操作没有区别。
在Linux的世界里,socket也被认为是文件的一种,因此在网络传输过程中自然可以使用文件I/O的相关函数。
Windows和Linux不同,是要区分socket和文件的。
因此在Windows中需要调用特殊的数数据传输相关函数。
底层文件访问(Low-Level File Access)和文件描述符(File Descriptor)
有些函数是Linux提供的,而非ANSI标准定义的函数。
此处的文件描述符是系统分配给文件或套接字的整数。
文件和套接字一般经过创建过程才会被分配文件描述符。
而上表中的3种输入输出对象即使经过特殊的创建过程,程序开始运行后也会被自动分配文件描述符。
文件描述符(文件句柄)
每当生成文件或套接字,操作系统将自动返还分配给他们的整数。这个整数将成为程序员与操作系统之间良好构统的渠道。
实际上,文件描述符只不过是为了方便称呼操作系统创建的文件或套接字而赋予的数而已。
文件描述符有时也称为文件句柄,但“句柄”主要是Windows中的术语。
Linux平台“描述符”。
打开文件
打开文件以读写数据的函数。
两个参数:第一个是参数打开的目标文件名以及路径信息。
第二个参数是文件打开模式(文件特性信息)
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int open(const char *path,int flag);
//成功时返回文件描述,失败时返回-1
下表是此函数第二个参数flag可能的常量值及含义,如需传递多个参数,则应通过位或运算(OR)符组合并传递。
关闭文件
使用文件后必须关闭。
关闭文件时调用的函数。
#include<unisd.h>
int close(int fd);
//成功时返回0,失败时返回-1。
若调用此函数的同时传递文件描述符参数,则关闭(终止)相应文件。另外需要注意的是,此函数不仅仅可以关闭文件,还可以关闭套接字。
将数据写入文件
write函数用于向文件输出(传输)数据。Linux中不区分文件与套接字。因此,通过套接字向其他计算机传递数据时也会用到该函数。
#include<unistd.h>
ssize_t write(int fd,const void *buf,size_t nbytes);
//成功时返回写入的字节数,失败时返回-1
//fd 显示数据传输对象的文件描述符
//buf 保存要传输数据的缓冲地址值
//nbytes 要传输数据的字节数
size_t是通过typedef声明的unsigned int类型,对ssize_t来说,多出来的s是代表signed。即ssize_t是通过typedef声明的sigened int 类型。
ssize_t,size_t等数据类型,这些都是元数据类型(primitive),在sys/types.h头文件中一般由typedef声明定义。
为了给基本数据类型赋予别名,一般会添加大量的typedef声明,而为了与程序员定义的新数据类型加以区分,操作系统定义的数据类型会添加后缀_t.
下述程序将创建新文件并保存数据。
//low_open.c
#include<stdio.h>
#include<stdlib.h>
#include<fcntl.h>
#include<unistd.h>
void error_handling(char *message);
int main(void)
{
int fd;
char buf[] = "Let's go!\n";
fd = open("data.txt",O_CREAT|Q_WRQNLY|O_TRUNC); //文件打开模式为O_CREAT\O_WRONLY和O_TRUNC的组合,因此将创建空文件夹,并只能写。若存在data.txt文件,则清空文件的全部数据。
if(fd==1)
error_handling("open() error!");
printf("file descriptor: %d \n",fd);
if(write(fd,buf,sizeof(bud))==1) //向对应于fd中保存的文件描述的文件传输buf中保存的数据。
error_handling("write() error!");
close(fd);
return 0;
}
void error_handling(char *message)
{
//见前一篇
}
叨叨几句... NOTHING