您的位置:首页 > 运维架构 > Linux

1.Linux应用编程——文件

2016-06-12 20:40 459 查看
文件I/O

文件IO和标准IO的区别:

静态库和共享库的区别:

静态库的特点:

共享库的特点:

文件描述符:

1.对于Linux内核而言, 所有的文件或设备都对应一个文件描述符(Linux的设计哲学: 一切皆文件), 这样可以简化系统编程的复杂程度;

2.当打开/创建一个文件的时候, 内核向进程返回一个文件描述符(是一个非负整数). 后续对文件的操作只需通过该文件描述符即可进行, 内核记录有关这个打开文件的信息;

3.一个进程启动时, 默认已经打开了3个文件, 标准输入(0, STDIN_FILENO), 标准输出(1, STDOUT_FILENO), 标准错误输出(2, STDERR_FILENO), 这些常量定义在unistd.h头文件中;

其中, 文件描述符基本上是与文件描述指针(FILE*)一一对应的, 如文件描述符0,1,2 对应 stdin, stdout, stderr;

文件指针与文件描述符的转换

fileno: 将文件指针转换成文件描述符

int fileno(FILE *stream);

fdopen: 将文件描述符转换成文件指针

FILE *fdopen(int fd, const char *mode);

基础API

1.open

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

int open(const char *pathname, int flags);

int open(const char *pathname, int flags, mode_t mode);

参数说明:

pathname:需要打开文件的路径(相对路径,绝对路径都行)

falgs:文件打开的模式(若有O_CREAT存在,则必须追加mode)

mode:新建文件的存取权限

flags常用值

2.read

#include <unistd.h>

ssize_t read(int fd, void *buf, size_t count);

fd:文件描述符

buf:读取的数据所存储的空间

count:每次读取数据的大小(若为1则每读一字节系统调用一次)

返回值:返回从文件复制到规定缓冲区的字节数,如果返回0,表示已到达文件尾或无可读取的数据,错误返回-1,count为0也返回0。

3.write

#include <unistd.h>

ssize_t write(int fd, const void *buf, size_t count);

解释同上

成功:返回成功写入文件的字节数

4.close

#include <unistd.h>

int close(int fd);

关闭文件描述符, 使得文件描述符得以重新利用

实例——拷贝argv[1]文件中的内容到argv[2]中

#include <stdio.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

int main(int argc, const char *argv[])

{

int fd1=0,fd2=0;

int buf[100];

int len=0,size=0;

if(argc<3)

{

return -1;

}

if((fd1=open(argv[1],O_RDONLY))<0)

{

perror("fail of open");

return -2;

}

if((fd2=open(argv[2],O_WRONLY|O_CREAT|O_TRUNC,0664))<0)

{

perror("fail of open");

return -2;

}

len=read(fd1,buf,100);

size=write(fd2,buf,len);

fprintf(stdout,"%d\n",len);

close(fd1);

close(fd2);

return 0;

}

5.lseek

对应于C库函数中的fseek, 通过指定相对于当前位置, 末尾位置或开始位置的字节数来重定位currp:

off_t lseek(int fd, off_t offset, int whence);

返回值: 新的文件偏移值;(若要获取文件长度,可先将文件移动到头,在移动到尾部,取返回值)

offset:偏移量

Whence取值:

SEEK_SET: 文件头

SEEK_CUR:文件当前位置

SEEK_END:文件尾

目录访问

6.opendir

#include <sys/types.h>

#include <dirent.h>

DIR *opendir(const char *name);

返回值:

成功:
返回目录指针;(作为readdir的输入)

失败:
返回NULL;

7.readdir

struct dirent *readdir(DIR *dirp);

返回值:

成功: 返回一个指向dirent结构的指针, 它包含指定目录的下一个连接的细节;

没有更多连接时, 返回0;

struct dirent

{

ino_t d_ino; /* inode number */

off_t d_off; /* not an offset; see NOTES */

unsigned short d_reclen; /* length of this record */

unsigned char d_type; /* type of file; not supported

by all filesystem types */

char d_name[256]; /* filename */

};

8.closedir: 关闭目录


int closedir(DIR *dirp);

9.stat

功能:获取文件元数据

#include <sys/types.h>

#include <sys/stat.h>

#include <unistd.h>

int stat(const char *path, struct stat *buf);

int fstat(int fd, struct stat *buf);

int lstat(const char *path, struct stat *buf);

stat结构体

struct stat

{

dev_t st_dev; /* ID of device containing file */

ino_t st_ino; /* inode number */

mode_t st_mode; /* protection */

nlink_t st_nlink; /* number of hard links */

uid_t st_uid; /* user ID of owner */

gid_t st_gid; /* group ID of owner */

dev_t st_rdev; /* device ID (if special file) */

off_t st_size; /* total size, in bytes */

blksize_t st_blksize; /* blocksize for filesystem I/O */

blkcnt_t st_blocks; /* number of 512B blocks allocated */

time_t st_atime; /* time of last access */

time_t st_mtime; /* time of last modification */

time_t st_ctime; /* time of last status change */

};

实例:利用stat、opendir、readdir实现ls
-l

#include <stdio.h>

#include <unistd.h>

#include <sys/types.h>

#include <dirent.h>

#include <grp.h>

#include <sys/types.h>

#include <pwd.h>

#include <sys/stat.h>

#include <time.h>

#include <string.h>

#include <stdlib.h>

int ss(char *argv,char *name)

{

struct stat st;//这里需要注意,若定义指针,不开辟空间会导致野指针的问题,固这里直接定义结构体,函数调用时直接用区地址符。

int i=0;

char *time=NULL;

if(stat(argv,&st) != 0)//用stat得到文件爱女的详细信息,并存入st结构体

{

perror("fail of stat");//perror打印有erron返回的函数的错误信息

return -1;

}

// printf("\n%d\n",st.st_mode);

if(S_ISREG(st.st_mode))//判断文件的权限

printf("-");

if(S_ISDIR(st.st_mode))

printf("d");

if((st.st_mode & S_IRUSR)== S_IRUSR)

printf("r");

else printf("-");

if((st.st_mode & S_IWUSR)== S_IWUSR)

printf("w");

else printf("-");

if((st.st_mode & S_IXUSR)== S_IXUSR)

printf("x");

else printf("-");

if((st.st_mode & S_IRGRP)== S_IRGRP)

printf("r");

else printf("-");

if((st.st_mode & S_IWGRP)== S_IWGRP)

printf("w");

else printf("-");

if((st.st_mode & S_IXGRP)== S_IXGRP)

printf("x");

else printf("-");

if((st.st_mode & S_IROTH)== S_IROTH)

printf("r");

else printf("-");

if((st.st_mode & S_IWOTH)== S_IWOTH)

printf("w");

else printf("-");

if((st.st_mode & S_IXOTH)== S_IXOTH)

printf("x");

else printf("-");

time=ctime(&st.st_ctime);

i=strlen(time);

*(time+i-1)=*(time+i);

//getpwuid得到文件的用户ID getgrgid得到文件的组ID

printf(" %5ld ",st.st_nlink);

printf("%5s %5s %7ld %5s %s\n",getpwuid(st.st_uid)->pw_name,getgrgid(st.st_gid)->gr_name,st.st_size,time,name);

return 0;

}

int main(int argc, const char *argv[])

{

DIR *dr=NULL;

int len,size;

struct dirent *buf;

char* p=NULL;

char* path=NULL;

if(argc<2)//文件延展性

{

return -1;

}

if((dr=opendir(argv[1]))==NULL)//打开目录,返回一个指向DIR的指针

{

perror("fail of opendir");

return -2;

}

while(buf=readdir(dr))//扫描目录,返回一个结构体指针,结构体中保存目录中的有关资料

{

path=malloc(strlen(argv[1])+strlen(buf->d_name)+2);//因为不知道文件长度,每次读取重新开辟空间

strcpy(path,argv[1]);//将目录copy到path所指向空间的头,实现目录在前,文件在后的规范

strcat(path,buf->d_name);//将文件名添加在目录的后面

ss(path,buf->d_name);//调用函数,用stat得到文件的详细信息并打印

free(path);//释放这个指针,高诉系统,这片空间用完了,你可以使用了

path=NULL;//需要注意,释放不代表清零,数据依旧存在,指针依旧指向这片空间,为避免危险操作,将指针指向NULL

}

closedir(dr);//关闭目录

return 0;

}

[拓展]

1.getpwuid

struct passwd *getpwuid(uid_t uid);

//passwd结构体

struct passwd

{

char *pw_name; /* username */

char *pw_passwd; /* user password */

uid_t pw_uid; /* user ID */

gid_t pw_gid; /* group ID */

char *pw_gecos; /* user information */

char *pw_dir; /* home directory */

char *pw_shell; /* shell program */

};

2.getgrgid

struct group *getgrgid(gid_t gid);

//group结构体

struct group

{

char *gr_name; /* group name */

char *gr_passwd; /* group password */

gid_t gr_gid; /* group ID */

char **gr_mem; /* group members */

};

3. readlink

ssize_t readlink(const char *path, char *buf, size_t bufsiz);

4. localtime

struct tm *localtime(const time_t *timep);

//tm结构体

struct tm

{

int tm_sec; /* seconds */

int tm_min; /* minutes */

int tm_hour; /* hours */

int tm_mday; /* day of the month */

int tm_mon; /* month */

int tm_year; /* year */

int tm_wday; /* day of the week */

int tm_yday; /* day in the year */

int tm_isdst; /* daylight saving time */

};

sudo !! 上一个命令权限不够,然后这个命令可以升级超级用户复制执行上一个命令
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: