文件操作
打开和关闭
头文件
1 2 3 4
| #include <fcntl.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h>
|
常用函数
1 2 3
| int open(const char *pathname, int flags); int open(const char *pathname, int flags, mode_t mode); int close(int fd);
|
open 函数有两个形式.其中 pathname 是我们要打开的文件名(包含路径名称,缺省是认为在
当前路径下面).flags 可以去下面的一个值或者是几个值的组合.
O_RDONLY:以只读的方式打开文件.
O_WRONLY:以只写的方式打开文件.
O_RDWR:以读写的方式打开文件.
O_APPEND:以追加的方式打开文件.
O_CREAT:创建一个文件.
O_EXEC:如果使用了 O_CREAT 而且文件已经存在,就会发生一个错误.
O_NOBLOCK:以非阻塞的方式打开一个文件.
O_TRUNC:如果文件已经存在,则删除文件的内容.
前面三个标志只能使用任意的一个.如果使用了 O_CREATE 标志,那么我们要使用 open 的第二种形式.还要指定 mode 标志,用来表示文件的访问权限.mode 可以是以下情况的组合.
S_IRUSR 用户可以读 S_IWUSR 用户可以写
S_IXUSR 用户可以执行 S_IRWXU 用户可以读写执行
S_IRGRP 组可以读 S_IWGRP 组可以写
S_IXGRP 组可以执行 S_IRWXG 组可以读写执行
S_IROTH 其他人可以读 S_IWOTH 其他人可以写
S_IXOTH 其他人可以执行 S_IRWXO 其他人可以读写执行
S_ISUID 设置用户执行 ID S_ISGID 设置组的执行 ID
我们也可以用数字来代表各个位的标志.Linux 总共用 5 个数字来表示文件的各种权限.
00000.第一位表示设置用户 ID.第二位表示设置组 ID,第三位表示用户自己的权限位,第四
[18 of 104]
Linux 操作系统 C 语言编程入门
位表示组的权限,最后一位表示其他人的权限.
每个数字可以取 1(执行权限),2(写权限),4(读权限),0(什么也没有)或者是这几个值的和
..
比如我们要创建一个用户读写执行,组没有权限,其他人读执行的文件.设置用户 ID 位那么
我们可以使用的模式是–1(设置用户 ID)0(组没有设置)7(1+2+4)0(没有权限,使用缺省)
5(1+4)即 10705:
open(“temp”,O_CREAT,10705);
如果我们打开文件成功,open 会返回一个文件描述符.我们以后对文件的所有操作就可以
对这个文件描述符进行操作了.
拷贝文件例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| #include <fcntl.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <errno.h>
#define BUFFER_SIZE 4096 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(-1 == (from_fd = open(argv[1], O_RDONLY))) { fprintf(stderr, "Open %s Error: %s\n", argv[1], strerror(errno)); exit(1); } if(-1 == (to_fd = open(argv[2], O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR))) { 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; } } } } close(from_fd); close(to_fd);
return 0; }
|
获取文件信息
文件具有各种各样的属性,除了我们上面所知道的文件权限以外,文件还有创建时间,大小等等属性.有时侯我们要判断文件是否可以进行某种操作(读,写等等).这个时候我们可以使用 access 函数.
1 2
| #include <unistd.h>; int access(const char *pathname,int mode);
|
pathname:是文件名称,mode 是我们要判断的属性.可以取以下值或者是他们的组合.
R_OK 文件可以读,W_OK 文件可以写,X_OK 文件可以执行,F_OK 文件存在.当我们测试成功
时
,函数返回 0,否则如果有一个条件不符时,返回-1.
如果我们要获得文件的其他属性,我们可以使用函数 stat 或者 fstat.
头文件
1 2
| #include <sys/stat.h>; #include <unistd.h>;
|
常用函数
1 2
| int stat(const char *file_name,struct stat *buf); int fstat(int filedes,struct stat *buf);
|
信息结构体
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| struct stat { dev_t st_dev; ino_t st_ino; mode_t st_mode; nlink_t st_nlink; uid_t st_uid; gid_t st_gid; dev_t st_rdev; off_t st_off; unsigned long st_blksize; unsigned long st_blocks; time_t st_atime; time_t st_mtime; time_t st_ctime; };
|
stat 用来判断没有打开的文件,而 fstat 用来判断打开的文件.我们使用最多的属性是 st_
mode.通过着属性我们可以判断给定的文件是一个普通文件还是一个目录,连接等等.可以
使用下面几个宏来判断.
S_ISLNK(st_mode):是否是一个连接.S_ISREG 是否是一个常规文件.S_ISDIR 是否是一个目
录 S_ISCHR 是否是一个字符设备.S_ISBLK 是否是一个块设备 S_ISFIFO 是否 是一个 FIFO
文
件.S_ISSOCK 是否是一个 SOCKET 文件
Misc
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386
| #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <dirent.h> #include <string.h> void sys_01() { int fd = open("Logan.txt",O_RDONLY); if(fd == -1) { perror("open"); exit(1); } int fd2 = open("Newfile",O_CREAT | O_WRONLY | O_EXCL, 0755); if(fd2 == -1) { perror("open2"); exit(1); } char buf[2048] = {0}; int count = read(fd,buf,sizeof(buf)); if(count == -1) { perror("read"); exit(1); } while(count) { int sizeofwrite = write(fd2,buf,count); printf("write bytes %d\n",sizeofwrite); count = read(fd,buf,sizeof(buf)); }
close(fd); close(fd2); } void sys_02() { int fd = open("Logan.txt",O_RDWR); if(fd == -1) { perror("open file"); exit(1); } int sizeoffile = lseek(fd,0,SEEK_END); printf("Size fo file %d\n",sizeoffile); lseek(fd,1000,SEEK_END); printf("Size fo file %d\n",sizeoffile); write(fd,"A",1); close(fd); }
void sys_03() {
struct stat st; int fd = -1; fd = open("Logan.txt",O_RDWR); if(fd == -1) { perror("open file"); exit(1); } fstat(fd,&st); printf("Size of file %d\n",st.st_size); } void sys_04() {
int ret = access("Logan.txt",W_OK); if(ret == -1) { perror("access"); exit(1); } printf("you can write this file.\n"); }
void sys_05(int argc,char **argv) { int ret = chmod(argv[2],strtol(argv[1],NULL,8)); if(argc < 3) { printf("Useage: ./a.out 755 filename"); } if(ret == -1) { perror("Chmod"); exit(1); } printf("Mode changed!\n"); } void sys_06(int argc,char **argv) {
} void sys_07() {
int trun = truncate("Logan.txt",12); if(trun == -1) { perror("truncate"); exit(1); } printf("OK!");
} void sys_08() {
} void sys_09() { int ret = rename("./Logan.txt","OK.txt"); if (ret == -1) { perror("rename"); exit(1); } printf("OK!"); } void sys_10(int argc,char **argv) { char path[256] = {0}; if(argc < 2) { printf("Useage: ./a.out path"); exit(1); } int ret = chdir(argv[1]); if(ret == -1) { perror("chdir"); exit(1); } getcwd(path, sizeof(path)); printf("current path: %s\n",path); }
int getFileNum(char *root) { DIR* dir = NULL; dir = opendir(root); if(dir == NULL) { perror("opendir"); exit(1); } struct dirent* ptr = NULL; char path_name[1024] = {0}; int total = 0; while( (ptr = readdir(dir)) ) { if(strcmp(ptr->d_name,".") == 0 || strcmp(ptr->d_name,"..") == 0) { continue; } if(ptr->d_type == DT_DIR) { sprintf(path_name,"%s/%s",root,ptr->d_name); total += getFileNum(path_name); } if(ptr->d_type == DT_REG) { total++; } } closedir(dir); return total;
} void sys_11(int argc,char **argv) { if(argc < 2) { printf("Usage:./a.out filepath\n"); exit(1); } printf("Number of Curent file:%d\n",getFileNum(argv[1])); } void sys_12() {
int fd = open("Logan.txt",O_RDWR); if(fd == -1) { perror("open"); exit(1); } printf("file open fd = %d\n",fd); int ret = dup(fd); if(ret == -1) { perror("dup"); exit(1); } printf("dup fd = %d\n",ret); char* buf = "你是猴子派来的救兵吗?\n"; char *buf_2 = "你大爷的! 我是程序猿!!\n"; write(fd, buf,strlen(buf)); write(ret, buf_2,strlen(buf_2)); close(fd); close(ret); } void sys_13() { char *txt1 = "我是" char *txt2 = "Logan" int fd = open("Logan.txt",O_WRONLY); if(fd == -1) { perror("open"); exit(1); } if(write(fd,txt1,strlen(txt1)) == -1) { perror("write"); eixt(1); } int flag = fcntl(fd, F_GETFL, 0);
}
int main(int argc,char **argv) { sys_12(); return 0; }
|
实现 ls
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
| #include <sys/types.h> #include <sys/stat.h> #include <stdio.h> #include <stdlib.h> #include <time.h> #include <pwd.h> #include <grp.h> #include <string.h> int main(int argc,char *argv[]) { if(argc < 2) { printf("Useage: ./a.out filename\n"); exit(1); } struct stat st; int ret = stat(argv[1],&st); if(ret == -1) { perror("stat"); exit(1); } char perms[11] = {0}; switch(st.st_mode & S_IFMT) { case S_IFLNK: perms[0] = '1'; break; case S_IFDIR: perms[0] = 'd'; break; case S_IFREG: perms[0] = '-'; break; case S_IFBLK: perms[0] = 'b'; break; case S_IFCHR: perms[0] = 'c'; break; case S_IFSOCK: perms[0] = 's'; break; case S_IFIFO: perms[0] = 'P'; break; default: perms[0] = '?'; break; } perms[1] = (st.st_mode & S_IRUSR) ? 'r' : '-'; perms[2] = (st.st_mode & S_IWUSR) ? 'w' : '-'; perms[3] = (st.st_mode & S_IXUSR) ? 'x' : '-'; perms[4] = (st.st_mode & S_IRGRP) ? 'r' : '-'; perms[5] = (st.st_mode & S_IWGRP) ? 'w' : '-'; perms[6] = (st.st_mode & S_IXGRP) ? 'x' : '-'; perms[7] = (st.st_mode & S_IROTH) ? 'r' : '-'; perms[8] = (st.st_mode & S_IWOTH) ? 'w' : '-'; perms[9] = (st.st_mode & S_IXOTH) ? 'x' : '-';
int linkNum = st.st_nlink; char* fileUser = getpwuid(st.st_uid)->pw_name; char* fileGrp = getgrgid(st.st_gid)->gr_name; int fileSize = (int)st.st_size; char* time = ctime(&st.st_mtime); char mtime[512] = {0}; strncpy(mtime, time, strlen(time)-1);
char buf[1024]; sprintf(buf,"%s %d %s %s %d %s %s",perms,linkNum,fileUser,fileGrp,fileSize,mtime,argv[1]); printf("%s\n",buf);
return 0; }
|