在Linux中,几乎一切都 是文件。所有Linux的IO(输入输出)都可以按照文件的方式实现。
关于文件IO的函数:
open/read/write/close/ioctl。
目录是文件,设备也是文件,
比如:
/dev/tty 是设备键盘和显示器。
/dev/null 代表空。
liujing@ubuntu:~/projects/ConsoleApplication1/bin/x64/Debug$ ls
ConsoleApplication1.out
liujing@ubuntu:~/projects/ConsoleApplication1/bin/x64/Debug$ ls -a
. .. ConsoleApplication1.out
liujing@ubuntu:~/projects/ConsoleApplication1/bin/x64/Debug$ ls -a > a.txt
liujing@ubuntu:~/projects/ConsoleApplication1/bin/x64/Debug$ ls
a.txt ConsoleApplication1.out
liujing@ubuntu:~/projects/ConsoleApplication1/bin/x64/Debug$ cat a.txt
.
..
a.txt
ConsoleApplication1.out
liujing@ubuntu:~/projects/ConsoleApplication1/bin/x64/Debug$ rm a.txt
liujing@ubuntu:~/projects/ConsoleApplication1/bin/x64/Debug$ ls
ConsoleApplication1.out
liujing@ubuntu:~/projects/ConsoleApplication1/bin/x64/Debug$ ls -a > /dev/tty
. .. ConsoleApplication1.out
cat 什么都不敲,表示键盘
liujing@ubuntu:~/projects/ConsoleApplication1/bin/x64/Debug$ cat
444
444
abcdefg
abcdefg
!@#
!@#
利用/dev/null清空文件
liujing@ubuntu:~/projects/ConsoleApplication1/bin/x64/Debug$ ls -al a.txt
-rw-rw-r-- 1 liujing liujing 153 Aug 12 13:55 a.txt
liujing@ubuntu:~/projects/ConsoleApplication1/bin/x64/Debug$ cat /dev/null > a.txt
liujing@ubuntu:~/projects/ConsoleApplication1/bin/x64/Debug$ ls -al a.txt
-rw-rw-r-- 1 liujing liujing 0 Aug 12 13:55 a.txt
#include
#include
int open(const char* filename,int oflag, …)
Unix/Linux系统在使用open函数时,建立一个文件描述符的表格,在表格中找到没有被使用的最小 正整数,用这个整数映射文件表。 所有文件相关信息存在文件表,但在使用时,用那个整数(文件描述符)就行。
// 结构体
struct Emp {
char name[20]; // 姓名
int age; // 年龄
double sal; // 薪水
};
// 使用open时,如果新建文件,需要提供权限0666(有屏蔽), 0表示8进制,rwx, 权限掩码
int fd = open("a.txt",O_RDWR|O_CREAT|O_TRUNC,0666);
// 写
int res = write(fd,"hello c",7);
// 一次读完
char buf[100] = {};
int res = read(fd,buf,sizeof(buf));//考虑是否可能需要循环
// 循环读, 边读边写
char buf[3] = {};
while(1){
int res = read(fd, buf, sizeof(buf));//需要写循环
if(res == -1) perror("read"), exit(-1);
if(res == 0) break; //效果更好
int res2 = write(fd2, buf, res);
if(res2 == -1) perror("write"), exit(-1);
}
// 写结构体数据
struct Emp emp = {"zhangfei",1800,12000.0};
int res = write(fd, &emp, sizeof(emp));
// 读结构体数据
struct Emp emp;
int res = read(fd, &emp, sizeof(emp));
说明, 其存储的数据直接在文本中查看是乱码
----------------------------------------------------------
但如何保存数据为文本不乱码?
方法:
全部转换成字符串写入(sprintf/printf/fprintf)
Emp emp = {"zhangfei", 18000, 12000.0};
char buf[100] = {};
sprintf(buf, "%s %d %lf", emp.name, emp.age, emp.sal);
write(fd, buf, strlen(buf));
以后在开发中,关于文件的读和写,最好使用标C的函数,因为标C的IO函数都有缓冲区,可以提高效率,
而 系统调用虽然在内核也有小的缓冲区,但效果还是比较慢。
也可以自定义缓冲区 提升效率。
char buf[1024] = {};
int index = 0;
strcpy/strcat --> strlen == 1024 --> write
用户登录和用户注册,用今天的文件函数。
存储/读取
姓名,年龄,薪水 char*/int/double
结构体
补充:
strlen 与 sizeof
区别一
#include
#include
int main()
{
char buf[] = "abcd";
printf("sizeof(buf) = %d\n",sizeof(buf));
printf("strlen(buf) = %d\n",strlen(buf));
return 1;
}
// 结果
// sizeof(buf) = 5 算上了\0(这里其实和区别二有点契合)
// strlen(buf) = 4 只算了到\0之前的所有数据长度(不包括\0)
区别二(其实也算是区别一)
#include
#include
int main()
{
char str[100] = {0};
strcpy(str, "abcd");
int str_len = strlen(str);
int str_size = sizeof(str);
printf("strlen(str) = %d\n", (str_len));
printf("sizeof(str) = %d\n", (str_size));
return 0;
}
// 结果
// strlen(str) = 4 只算了到\0之前的所有数据长度(不包括\0)
// sizeof(str) = 100 算上了char[]所占用的总长度(并不关注其中实际用了多少数据)
文件表 – 对应内存
liujing@ubuntu:~/projects/ConsoleApplication1/bin/x64/Debug$ ls -i
132574 a.txt 132575 b.txt 131612 ConsoleApplication1.out 132577 emp.txt
命令ls -i
显示出来的数字为
数据在硬盘上的硬盘地址
文件偏移量
off_t lseek(int fd, off_t offset, int whence);
whence
- SEEK_SET
-- The offset is set to offset bytes.
- SEEK_CUR
-- The offset is set to its current location plus offset bytes.
- SEEK_END
-- The offset is set to the size of the file plus offset bytes.
lseek(fd, 3, SEEK_SET);//从头开始+3
lseek(fd,2,SEEK_CUR); // 当前位置往后+2
lseek(fd, -1, SEEK_END); // -1 修改的是尾部文件结束符
lseek(fd, -2, SEEK_END); // -2 才能修改到文件最后实际的内容
另注意:
read/write 函数使用完之后,文件指针都会往后+1