Linux 文件编程
一、Linux系统调用及用户编程接口(API)
用户程序直接访问系统内核 内核将无法管理资源 而且很不安全
Linux 文件
Linux一点哲学 “一切皆文件”,在Linux中对目录和设备的操作等同于对文件的操作;
Linux文件可分为:普通文件(-),目录文件(d),链接文件(l),设备文件(b/c);套接口文件(s),无名管道(p);
1.文件描述符
0 代表 键盘
1 代表 显示屏
2.创建create
创建文件 用的少
errno对应的错误编码有哪些?
[(https://www.cnblogs.com/luanyulin/p/10833350.html)]
处理errno的错误编码的函数?1.函数名 2.头文件3.参数用法
S_IRGRP 同组内人可读权限
S_IROTH 其他人可读权限
3.打开OPEN:
文件已经存在 使用第一个方法
查看strerr函数?
定义函数:char * strerror(int errnum);
函数说明:strerror()用来依参数errnum 的错误代码来查询其错误原因的描述字符串, 然后将该字符串指针返回.
返回值:返回描述错误原因的字符串指针.
常用perror(“open error这个字符串是我写的 会在其后面显示错误原因 相当于一个提醒” )这个函数 显示内容包含错误原因
flags参数
还有一种打开方式O_APPEND 追加(只写)
文件里面有文件读写指针 指针指哪就在哪读写 前三种打开方式 文件指针指在文件开头
而追加模式 文件指针是在文件末尾 即在文件末尾写
文件中还有 EOF 文件结束标志 读文件时遇到这个字符 表示文件已经结束
四个打开方式 只能选一个
O_EXCL 不能单独使用
必须O_CREAT | O_EXCL这样使用 如果文件已经存在 就会报错 所以O_EXCL保证了文件是新创建的
O_TRUNC如果flags中加入这个 相当于将文件内容清空
这个不能与只读选项一起使用
O_WRONLY | O_CREAT | O_TRUNC
只写 创建 清空 这三个一起使用 就相当于
>一般不使用第三个参数 所以使用第一种open函数
4.读read
read函数只返回0 即什么都没读到 其是有特殊用处的
网络编程时 客户端与服务端链接 服务器分配一个进程去服务客户端 当客户端下线 这个进程会read这个客户端的socket接口
如果返回0 表示客户端已经下线
部分读 即只读了一部分 length是100 文件中有100个 但只读了80个
则需要循环 当没遇到EOF 且 文件中有 就循环去读
5.写write
write函数一般不会返回0 除非你给的length就是0
6.定位(将文件读写指针进行定位)
7.代码(使用系统调用函数来写文件复制函数)
使用系统调用函数来写文件复制函数
#include <unistd.h>
#include<fcntl.h>
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<errno.h>
#include<string.h>
#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);
}
//open source file
if((from_fd = open(argv[1],O_RDONLY)) == -1)
{
fprintf(stderr,"open %s Error:%s\n",argv[1],strerror(errno));
exit(1);
}
//create target file
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);
}
//file copy
while(bytes_read = read(from_fd,buffer,BUFFER_SIZE))
{
//error found
if((bytes_read == -1)&&(errno != EINTR))
break;
else if(bytes_read > 0)
{
ptr = buffer;
while(bytes_write = write(to_fd,ptr,bytes_read))
{
//error found
if((bytes_write == -1)&&(errno != EINTR))
break;
//write all bytes
else if(bytes_read == bytes_read)
break;
//write part bytes
else if(bytes_write > 0)//处理部分写的问题
{
ptr += bytes_write; //将ptr指针定位到写到的地方
bytes_read -= bytes_write;//算出有多少没写进去 下次先将这剩下的写进去
}
}
//error found when write
if(bytes_write ==-1)
break;
}
}
close(from_fd);
close(to_fd);
return 0;
}
二、C库函数
1.打开fopen
打开几个文件 就需要创建几个文件指针 例如:FILE *fp
2.读fread
3.写fwrite
4.读字符fgetc
5.写字符fputc
6.练习
#include<stdio.h>
#include<stdlib.h>
int main(){
FILE *fp1 , *fp2 , *fp3;
char ch1 ,ch2 ,ch3;
if((fp1 = fopen("text1.txt","r+")) == NULL){
printf("open text1 fail!\n");
exit(1);
}
if((fp2 = fopen("text2.txt","r+")) == NULL){
printf("open text2 fail\n");
exit(1);
}
if((fp3 = fopen("text3.txt","w+")) == NULL){
printf("create or open text3 fail\n");
exit(1);
}
ch1 = fgetc(fp1);
ch2 = fgetc(fp2);
while(ch1 != EOF && ch2 != EOF){
if(ch1 > '9' || ch1 < '0'){
fputc(ch1,fp3);
ch1 = fgetc(fp1);
ch2 = fgetc(fp2);
}
else{
ch1 = ch1 - '0';
ch2 = ch2 - '0';
ch3 = ch1 + ch2;
ch3 = ch3 + '0';
fputc(ch3,fp3);
ch1 = fgetc(fp1);
ch2 = fgetc(fp2);
}
}
fclose(fp1);
fclose(fp2);
fclose(fp3);
}
7.代码(使用库函数进行文件复制)
使用库函数进行文件复制
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(){
FILE *fp;
FILE *fd;
char ch;
char p[20] = "hello";
if((fp = fopen("c1.txt","w+")) == NULL){
printf("open c1 fail\n");
exit(1);
}
else{
fwrite(p,1,5,fp);
}
if((fd = fopen("c2.txt","w+")) == NULL){
printf("open c2 fail\n");
exit(1);
}
else{
fseek(fp,0,SEEK_SET);//这句必须要加 将fp所指文件的读写指针放到文件头
ch = fgetc(fp);//这时候取fp值时 是文件第一个值 没有上面那句 就只能取EOF了
while(ch != EOF){
fputc(ch,fd);
ch = fgetc(fp);
}
}
fclose(fp);
fclose(fd);
}