classday1-文件IO
一.
1.c基础-c高级-数据结构-高级编程
应用层 c语言 数据结构 java Android linux命令
—————————————————————————————————linux高级编程 也属于应用层 是应用层与内核层的过渡层 linux内核向用户提供的接口层
内核层
——————————————————————————————————————
硬件层
2.为什么要学?
文件管理
进程管理
网络管理
内存管理
设备管理
3.学习方法:
学习接口函数 三要素:功能 参数 返回值
4.相关知识:
IO input output
文件io
标准io
目录io
进程 进程 进程控制 进程间通信(单机 非单机)线程
网络:一个网络中 两台机器通信 tcp udp 循环服务器 并发服务器
二、文件IO
流程:
打开–读写–关闭
open–read/write-close
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags, mode_t mode);// "/home/linux/stu.txt"
功能: 打开或创建文件
参数1:打开的文件的路径 包括文件名 路径:可以是绝对路径 也可以是相对路径
参数2:打开文件的方式
参数3:对新文件的访问权限 可有可无 如果参数2是O_CREAT 则参数3生效
返回值:成功返回文件描述符 失败-1
(1)O_CREAT:如果文件不存在 则创建 如果文件存在 则打开
例:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include<stdio.h>
int main()
{
int fd = open("./today",O_CREAT,0666);
if(fd==-1)
{
printf("open error");
return 0;
}
printf("文件描述符:%d\n",fd);//3
return 0;
}
(2)文件描述符的分配规则:当前尚未分配的最小的非负整数
标准方向:
标准输入--键盘 0
标准输出 -屏幕 1
标准错误输出-屏幕 2
(3)文件权限
ls -l //显示文件的详细信息
drwxrwxr-x 2 linux linux 4096 Jul 31 23:28 hao
-rw-rw-r-- 1 linux linux 0 Jul 26 19:49 file.c
文件属性 文件所有者 文件所属组 文件大小 文件创建时间 文件名
drwxrwxr-x
第一个字符代表文件类型
d 表示这个文件是目录
- 表示这个文件是普通文件
c 表示这个文件是字符设备文件
l 表示这个文件是链接文件
b 表示这个文件是块设备文件
s 表示这个文件是套接字文件
p 表示这个文件是管道文件
rwx rwx r-x //r 可读 w 可写 x 可执行
第一个rwx 代表文件所有者对文件的访问权限 读写执行
第二个rwx 代表文件所属组对文件的访问权限 读写执行
第三个r-x 代表其他用户对文件的访问权限 读和执行
chmod 更改文件的访问权限
linux@ubuntu:~$ chmod +x test.c //增加执行权限
linux@ubuntu:~$ chmod -x test.c //去掉执行权限
rwx rwx r-x
111 111 101
7 7 5
chmod 777 test.c
掩码:将生成的权限掩掉
查看掩码的命令:umask //0 002是默认掩码
修改掩码:umask 0000 //将掩码修改为000
000 000 010 掩码002
111 111 101 (掩码002取反的结果)
110 110 110 创建文件给予的权限666转为二进制表达
---------------------
110 110 100
/////文件实际权限:mode&(~umask)
注意:
1、文件的默认权限是没有x的,即文件的最大默认权限为666(-rw-rw-rw)
2、由于进入目录和目录的x权限有关,故目录的最大默认权限为777(drwxrwxrwx)
(4)O_EXCL
测试文件是否存在 如果O_CREAT时 文件已经存在 则open返回错误信息
例子:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include<stdio.h>
int main()
{
int fd = open("./today",O_CREAT|O_EXCL,0666);
if(fd==-1)
{
printf("open error");
return 0;
}
printf("文件描述符:%d\n",fd);
return 0;
}
(5)O_TRUNC:清空文件内容
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include<stdio.h>
int main()
{
int fd = open("./today",O_CREAT|O_TRUNC,0666);
if(fd==-1)
{
perror("open");
return 0;
}
printf("文件描述符:%d\n",fd);
return 0;
}
2.
#include <stdio.h>
void perror(const char *s);
功能:返回上一个函数的错误信息
参数:原形输出
///////////////////////////////
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include<stdio.h>
int main()
{
int fd = open("./today",O_CREAT|O_EXCL,0666);
if(fd==-1)
{
perror("open");//open:xxxx
// printf("open error");
return 0;
}
printf("文件描述符:%d\n",fd);
return 0;
}
-
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);功能:写数据到文件
参数1:往哪个文件写 open返回值
参数2:想写的内容
参数3:想写多少个字节
返回值:成功返回实际写的字节数 失败-1ssize_t是有符号整形 (32位机下)
O_WRONLY:以只写方式打开文件
例子:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include<stdio.h>
#include<unistd.h>
int main()
{
int fd = open("./today",O_CREAT|O_WRONLY,0666);
if(fd==-1)
{
perror("open");
return 0;
}
char buf[]="hello world";
ssize_t ret = write(fd,buf,sizeof(buf));
if(ret==-1)
{
perror("write");
return 0;
}
printf("ret:%d\n",ret);
return 0;
}
练习1:实现从键盘输入字符串后 将其保存到文件 输入'0'结束
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include<stdio.h>
#include<unistd.h>
void input_string(char *buf)
{
int i=0;
do
{
scanf("%c",&buf[i]);// a回车b回车
getchar();//取走回车
i++;
}while(buf[i-1]!='0');
buf[i-1] = '\0';
}
int main()
{
char buf[1024]={0};
int fd = open("./new.txt",O_CREAT|O_WRONLY,0777);
if(fd<0)
{
perror("666"); //666:xxxxx
return 0;
}
input_string(buf);//helloworld
ssize_t ret = write(fd,buf,strlen(buf)+1);
//ssize_t ret = write(fd,buf,sizeof(buf));
if(ret<0)
{
perror("write error");
return 0;
}
return 0;
}
4.头文件编写:
//my.h
#ifndef _MY_H
#define _MY_H
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#endif
//open.c
#include"my.h"
void input_string(char *buf)
{
int i=0;
do
{
scanf("%c",&buf[i]);// a回车b回车
getchar();//取走回车
i++;
}while(buf[i-1]!='0');
buf[i-1] = '\0';
}
int main()
{
char buf[1024]={0};
int fd = open("./new.txt",O_CREAT|O_WRONLY,0777);
if(fd<0)
{
perror("666"); //666:xxxxx
return 0;
}
input_string(buf);
ssize_t ret = write(fd,buf,sizeof(buf));
if(ret<0)
{
perror("write error");
return 0;
}
return 0;
}
编译执行:gcc open.c
./a.out
练习2:键盘输入人的姓名和年龄 将信息存入文件
要求:文件名字从命令行获取
int main(int argc,char *argv[])
{
//1.打开要写入的文件
open(argv[1],O_CREAT|OWRONLY,0666);
//2.定义变量
char name[200]="\0";
int age;
//给变量赋值
//将数据写入文件
}
运行:./a.out a.txt
#include"my.h"
#define N 2
typedef struct
{
char name[20];
int age;
}person_t;
int main(int argc,char*argv[])//./a.out a.txt
{
if(argc!=2)
{
printf("%s filename\n",argv[0]);
return 0;
}
int fd = open(argv[1],O_CREAT|O_WRONLY,0777);
if(fd<0)
{
perror("open");
return 0;
}
ssize_t ret;
int i;
person_t x;
for(i=0;i<N;i++)
{
puts("input name age:");
scanf("%s%d",x.name,&x.age);
ret = write(fd,&x,sizeof(person_t));
if(ret<0)
{
perror("write");
return 0;
}
}
return 0;
}
-
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
功能:从文件中读数据
参数1:文件
参数2:读到的数据存放的位置
参数3:最多读多少字节
返回值:成功返回实际读到的字节数 失败-1 读到文件结尾返回0O_RDONLY 文件的访问方式为只读
#include"my.h"
int main()
{
int fd = open("b.txt",O_RDONLY);//以只读方式打开文件
if(fd<0)
{
perror("open");
return 0;
}
char buf[100]="\0";
ssize_t ret = read(fd,buf,sizeof(buf));
if(ret<0)
{
perror("read");
return 0;
}
printf("read:%s\n",buf);
return 0;
}
6.关闭文件
#include <unistd.h>
int close(int fd);
O_RDWR:以读写方式打开文件
-
#include <sys/types.h> #include <unistd.h> off_t lseek(int fd, off_t offset, int whence); 功能:调整位置指针 参数1:文件描述符 参数2:相对于参照的偏移量 参数3:参照: SEEK_SET 当前文件的开头 SEEK_CUR 当前文件指针的位置 SEEK_END 当前文件末尾
返回值:成功返回文件指针当前位置 失败-1
////////////////////////////////////////
#include"my.h"
int main()
{
int fd = open("a.c",O_CREAT|O_RDWR,0666);//以读写方式打开文件
if(fd<0)
{
perror("open");
close(fd);//关闭文件
return 0;
}
int age=18;
ssize_t ret = write(fd,&age,sizeof(age));//文件的位置指针在文件结尾
if(ret<0)
{
perror("write");
close(fd);
return 0;
}
lseek(fd,0,SEEK_SET);//相对文件开头 偏移0 --》将文件位置指针定位到文件起始位置
int x;
ssize_t ret1 = read(fd,&x,sizeof(x));
if(ret1<0)
{
perror("read");
close(fd);
return 0;
}
printf("read:%d\n",x);
close(fd);
return 0;
}
练习3:将练习2的内容读出来
///////////////////////////
#include"my.h"
#define N 2
typedef struct
{
char name[20];
int age;
}person_t;
int main(int argc,char*argv[])//./a.out a.txt
{
if(argc!=2)
{
printf("%s filename\n",argv[0]);
return 0;
}
int fd = open(argv[1],O_RDWR,0777);
if(fd<0)
{
perror("open");
return 0;
}
ssize_t ret;
int i;
person_t x;
for(i=0;i<N;i++)
{
puts("input name age:");
scanf("%s%d",x.name,&x.age);
ret = write(fd,&x,sizeof(person_t));
if(ret<0)
{
perror("write");
return 0;
}
}
lseek(fd,0,SEEK_SET);
person_t y;
ssize_t ret1;
for(i=0;i<N;i++)
{
ret1 = read(fd,&y,sizeof(person_t));
if(ret1<0)
{
perror("read");
return 0;
}
printf("name:%s age:%d\n",y.name,y.age);
}
return 0;
}
作业:实现文件的拷贝 类似功能:cp a.txt b.txt
要求:源文件名字和目标文件名从main命令行传参
//cp a.c b.c
//程序 open.c
int main(int argc,char*argv[])
{
1.打开源文件 fd_src = open(argv[1],…)
2.打开目标文件 fd_dst = open(argv[2]…)
while(1)
{
ret = read(fd_src,buf,sizeof(buf));
if(ret<=0)//出错或到文件结尾 则结束循环
{
break;
}
write(fd_dst,buf,ret);
}
3.关闭文件
}
//gcc open.c -o mycp
//./mycp a.c b.c