Linux文件操作
1.linux,一切皆为文件
2.Linux文件可分为:普通文件,目录文件,链接文件,设备文件;
d:目录文件;
l:链接文件;
p:管道文件
s:套接字
c:字符设备;
b:块设备;
p:管道文件,如FIFO文件;
f:堆栈文件,如LIFO
d:表示目录文件
c/b:表示设备文件
3.文件描述符是一个非负的整数,它是一个索引值,并指向内核中每个进程的记录表中;
4.一个进程启动时,都会打开三个文件:
标准输入: STDIN_FILENO 0
标准输出: STDOUT_FILENO 1
标准出错处理:STDERR_FILENO 2
5.creat函数
int creat(const char *filename,mode_t mode)
filename:创建的文件名(包含路径,缺省为当前路径)mode:创建模式
常用创建模式(除了宏定义也可用数字表示 )
S_IRUSR 可读
S_IWUSR 可写
S_IXUSR 可执行
S_IXRWU 可读可写可执行
6.open函数
int open(const char * pathname,int flags);
int open(const char * pathname,int flags,mode_t mode);
返回值:成功返回新分配的文件描述符,出错返回-1并设置errno
pathname是要打开或创建的文件的名字
flags参数可用来说明此函数的多个选择项
-
flags参数
O_CREAT 若此文件不存在则创建它。使用此选择项时,需同时说明第三个参数mode,用其 说明该新文件的存取权限。
O_EXCL | O_CREAT 不能单独使用,根O_creat一起使用
加上O_EXCL 指定文件存在就会出错 没报错 即创建新文件
O_NONBLOCK 如果pathname指的是一个块特殊文件或一个字符特殊文件,则此选择项为
此文件的本次打开操作和后续的I/O操作设置非阻塞方式(空文件,没读到,非阻塞,直接返 回 0);不加默认阻塞(阻塞的话read停在这等待读)。
O_TRUNC 把打开的文件长的截断为0,清空文件内所有内容。(不能跟只读一起用)
以下三个常数中必须指定一个,且仅允许指定一个(这些常数定义在<fcntl.h>头文件中)
O_RDONLY 只读打开
O_WRONLY 只写打开
O_RDWR 读、写打开
mode对于open函数而言,仅当创建新文件时才使用第三个参数
mode创建模式
S_IRUSR 可读
S_IWUSR 可写
S_IXUSR 可执行
S_IXRWU 可读、可写、可执行
7.close函数
int close(int fd) fd: 文件描述符,来源
open 返回值文件描述符
8.read函数
int read(int fd,const void *buf,size_t length)
功能:从文件描述符fd所指定的文件中读取length个字节到buf所指向的缓冲区中,返回值为实际读取的字节数
返回值: -1(出错)
9.write函数
int read(int fd,const void *buf,size_t length)
功能: 从文件描述符fd所指定的文件中读取length个字节到buf所指向的缓冲区中,返回值为实际读取的字节数。
返回值: -1(出错) length 0length = 0时,返回0
10.lseek函数
int lseek(int fd,offset_t offset, int whence)
功能:将文件读写指针相对whence移动offset个字节。操作成功时,返回文件指针相对于文件头的位置
whence可使用下述值:
SEEK_SET:相对文件开头
SEEK_CUR:相对文件读写指针的当前位置
SEEK_END:相对文件末尾
offset可取负值,表示向前移动。例如下述调用
可将文件指针相对当前位置向前移动5个字节:
lseek(fd, -5, SEEK_CUR)
lseek来计算文件长度:
- 由于lseek函数的返回值为文件指针相对于文件头的位置,因此下面调用的返回值就是文件的长度: lseek(fd, 0, SEEK_END)
11.file_copy.c实现文件内容拷贝
#include <stdio.h>
#include <stdlib.h>
//系统调用函数
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>//read,write,close头文件
#include <errno.h>
#include <string.h>
#define BUFFER_SIZE 1024
int main(int argc, const 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 \n\a",argv[0]);
exit(1);
}
if((from_fd = open(argv[1],O_RDONLY)) == -1)
{
fprintf(stderr,"open %s Error:%s\n",argv[1],strerror(errno));
exit(1);
}
if((to_fd = open(argv[2],O_RDWR | O_CREAT,S_IRUSR | S_IWUSR)) == -1)
{
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 > 0)
{
ptr += bytes_write;
bytes_read -= bytes_write;
}
if(bytes_write == -1)
{
break;
}
}
}
}
close(from_fd);
close(to_fd);
return 0;
}
C库函数
1.C库函数的文件操作是独立于具体的操作系统平台的,不管是在DOS、Windows、Linux还是在VxWorks中都是这些函数。
2.
FILE *fopen(const char *filename, const char *mode)
filename:打开的文件名(包含路径,缺省为当前路径)
mode:打开模式
“r” :只读,文件必须已存在
“w”:只写,如果文件不存在则创建,如果文件已存在则把文件长度截断(Truncate)为0字节再重新写,也就是替换掉原来的文件内容
“a”:只能在文件末尾追加数据,如果文件不存在则创建
“r+”:允许读和写,文件必须已存在
“w+”:允讲读和写,如果文件不存在则创建,如果文件已存在则把文件长度截断为0字节再重新写
“a+”:允许读和追加数据,如果文件不存在则创建
b用于区分二进制文件和文本文件,这一点在DOS、Windows系统中是有区分的,但Linux不区分二进制文件和文本文件(不需要写"b")
3.fwrite函数
size_t fwrite(const void * ptr,size_t size, size_t n,FILE * stream)
功能:从缓冲区ptr所指的数组中把n个字段写到stream指向的文件中,每个字段长为size个字节,返回实际写入的字段数
4.fread函数
size_t fread(void *ptr,size_t size,size_t n, FILE * stream)
功能: 从stream指向的文件中读取n个字段,每字段为size字节,并将读取的数据放入ptr所指的字符数组中,返回实际已读取的字段数。
5.C库函数实现file_copy.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, const char *argv[])
{
FILE *fp_from;
FILE *fp_to;
char ch;
if((fp_from = fopen("test1.txt","w+")) == NULL)
{
printf("Can not open file strike and key exit!");
exit(1);
}
if((fp_to = fopen("test2.txt","w+")) == NULL)
{
printf("Can not open file strike and key exit!");
exit(1);
}
printf("please input character in test1\n");
ch = getchar();
while(ch != '\n')
{
fputc(ch,fp_from);
ch = getchar();
}
ch = fgetc(fp_from);
while(ch != EOF)
{
fputc(ch,fp_to);
ch = fgetc(fp_from);
}
fclose(fp_from);
fclose(fp_to);
return 0;
}
三hello
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define BUFFER_SIZE 1024
int main(int argc, const char *argv[])
{
int fd;
int i;
int bytes_read;
char buffer[BUFFER_SIZE];//数据缓存区
char *ptr = "hello";
if((fd = open("hello.txt",O_RDWR | O_CREAT,S_IRUSR | S_IWUSR | S_IXUSR)) == -1)
{
perror("open error!\n");
exit(-1);
}
for(i = 0; i < 3; i++)
{
write(fd,ptr,5);//将ptr中的5个字节写入fd
write(fd,"\n",1);//将一个'\n'写入fd,实现换行功能
}
lseek(fd,0,SEEK_SET);//定位文件读写指针
for(i = 0; i < 3; i++)
{
bytes_read = read(fd,buffer,6);//从fd中读取6个字节到缓存区
if(-1 == bytes_read)
{
perror("read error!\n");
break;
}
write(1,buffer,6);//将缓存区的6个字节写到屏幕上
}
close(fd);
return 0;
}