Linux系统调用——文件访问
Linux中的文件编程可以使用两种方法:
- Linux的系统调用
- C语言库函数
前者依赖与Linux系统,后者与操作系统无关。
<meta name="referrer" content="no-referrer" />
系统调用——创建
int creat(const char* filname, mode_t mode)
mode:
S_IRUSER 可读 -> 1
S_IWUSER 可写 -> 2
S_IXUSER 可执行 -> 4
S_IRWXU 可读、写、执行 -> 7
int main(int argc,char *argv[])
其中argc:参数的个数
argv:保存的参数的值
rwx->124
数字rwxrwrwx表示:文件所有者 文件所有者所在的组 其他用户
- file_creat.c:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
void create_file(char *filename){
/*创建的文件所具有的属性*/
if(creat(filename,0755)<0){
printf("creat file %s failure!\n",filename);
exit(EXIT_FAILURE);
}else{
printf("creat file %s success!\n",filename);
}
}
int main(int argc,char *argv[]){
int i;
if(argc<2){
perror("you have't input the filename,please try again!\n");
exit(EXIT_FAILURE);
}
for(i=1; i<argc; i++){
create_file(argv[i]);
}
exit(EXIT_SUCCESS);
}
文件描述
在Linux中,所有打开的文件都对应一个<font color = red>文件描述符</font>。文件描述符是一个非负整数。当打开一个文件时,系统就分配一个整数。范围是0 - OPEN_MAX,现在可以允许每个进程同时打开1024个文件。
系统调用——打开
/*0打开函数*/
int open(const char *pathname,int flags)
int open(const char *pathname,int flags, mode_t mode) flag里面包含O_CREAT
flags:打开标志
O_RDONLY 只读
O_WRONLY 只写
O_RDWR 读写
O_APPEND 追加
O_CREAT 创建
O_NOBLOCK 非阻塞
如果使用了O_CREATE标志,则使用的函数是:int open(const char *pathname,int flags, mode_t mode);
如果文件中没有此文件就自动创建一个
int main(int argc, char *argv[]){
int fd;
if(argc<2){
puts("please input the open file pathname!\n");
exit(1);
}
if((fd=open(argv[1],O_CREAT|O_RDWR,0755))<0){
perror("open file failure!\n");
exit(1);
}else{
printf("open file %s success!\n",fd);
}
close(fd);
exit(0);
}
系统调用——关闭系统
int close(int fd)
系统调用——读
int read(int fd,const void *buf,size_t length)
从文件描述符fd所指定的文件中读取length个字节到buf所指向的缓冲区中返回值为读取的字节数
系统调用——写
int write(int fd,const void *buf,size_t length)
把length个字节从buf指向的缓冲区中写到文件描述符fd所指向的文件中,返回值为写入的字节数
系统调用——定位
int lseek(int fd,offset_t offset, int whence)
offset可取负值,表示向前移动
将文件读写指针相对whence移动offset个字节。成功时,返回文件指针相对于文件头的位置。
whence:
SEEK_SET:相对文件开头
SEEK_CUR:相对文件读写指针的当前位置
SEEK_END:相对文件末尾
计算文件长度:
lseek(fd,0,SEEK_END)
系统调用——访问判断
int access(const char *pathname,int mode)
mode:R_OK,W_OK,X_OK,F_OK(文件存在)
成功,返回为0。失败返回-1。
#include <unistd.h>
#include <stdio.h>
int main()
{
if(access("/etc/passwd",R_OK)==0) //判断文件passwd是否可读
printf("/etc/passwd can be read!\n");
}
系统调用——文件的读写(复制)
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<errno.h>
#include<fcntl.h> //for open
#include<unistd.h> //for close
#define BUFFER_SIZE 1024
int main(int argc,char **argv)
{
int from_fd,to_fd;
int bytes_read,bytes_write;
char buffer[BUFFER_SIZE];
char *ptr;
if(argc!=3)
{
fprintf(stderr,"Usage: %s fromfile tofile/n/a",argv[0]);
exit(1);
}
/*打开源文件*/
if((from_fd=open(argv[1],O_RDONLY))==-1)
{
fprintf(stderr,"Open %s Error:%s/n",argv[1],strerror(errno));
exit(1);
}
/*创建目的文件*/
if((to_fd=open(argv[2],O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR))==-1)
{
fprintf(stderr,"Open %s Error:%s/n",argv[2],strerror(errno));
exit(1);
}
/*拷贝文件*/
while(bytes_read=read(from_fd,buffer,BUFFER_SIZE))
{
if((bytes_read==-1)&&(errno!=EINTR)) break;
else if(bytes_read>0)
{
ptr=buffer;
while(bytes_write=write(to_fd,ptr,bytes_read))
{
if((bytes_write==-1)&&(errno!=EINTR)) break;
else if(bytes_write==bytes_read) break;
else if(bytes_write>0)
{
ptr+=bytes_write;
bytes_read-=bytes_write;
}
}
if(bytes_write==-1) break;
}
}
close(from_fd);
close(to_fd);
exit(0);
}