wirte函数原型:
ssize_t write (int fd,const void * buf,size_t count);
作用:
write( ) 会把参数buf所指的内存写入count个字节到参数fd所指的文件内。当然,文件读写位置也会随之移动。
返回值:
如果顺利,write( )会返回实际写入的字节数。当有错误发生时则返回-1,错误代码存入errno中
1、EINTR:此调用被信号所中断。
2、EAGAIN:当使用不可阻断I/O时(O_NONBLOCK),若无数据可读取则返回此值。
3、EADF:参数fd非有效的文件描述词,或该文件已关闭
---------------------------------------------------------------------------------------------------------------------------------
read函数原型:
ssize_t read(int fd,void * buf ,size_t count);
作用:
read( ) 会把参数 fd 所指的文件传送 count 个字节到 buf 指针所指的内存中。若参数 count 为0,则read( )不会有作用并返回0。返回值为实际读取到的字节数,
如果返回 0,表示已到达文件尾或是无可读取的数据,此外文件读写位置会随读取到的字节移动
返回值:
如果顺利,read( ) 会返回实际读到的字节数,最好能将返回值与参数count作比较,若返回的字节数比要求读取的字节数少,则有可能读到了文件尾、从管道(pipe)或终端机读取,或者是read( )被信号中断了读取动作。当有错误发生时则返回-1,错误代码存入errno中,而文件读写位置则无法预期
1、EINTR:此调用被信号所中断。
2、EAGAIN:当使用不可阻断I/O时(O_NONBLOCK),若无数据可读取则返回此值。
3、EBADF:参数fd非有效的文件描述词,或该文件已关闭
---------------------------------------------------------------------------------------------------------------------------------
lseek函数原型
off_t lseek(int fildes,off_t offset ,int whence);
作用
每一个已打开的文件都有一个读写位置,在打开文件时通常其读写位置指向文件开头,若是以附加的方式打开文件(如O_APPEND),则读写位置会指向文件尾。
当read( ) 或write( )时,读写位置会随之增加,lseek( )便是用来控制该文件的读写位置的。
参数fildes为已打开的文件描述词;
参数offset为根据参数whence来移动读写位置的位移数,
参数whence为下列其中一种。
1、SEEK_SET:参数offset即为新的读写位置。
2、SEEK_CUR:以目前的读写位置往后增加offset个位移量。
3、SEEK_END:将读写位置指向文件尾后再增加offset个位移量。
当 whence 值为SEEK_CUR或SEEK_END时,参数offet允许负值的出现。下列是较特别的使用方式:
1、欲将读写位置移到文件开头时,lseek(int fildes,0,SEEK_SET)。
2、欲将读写位置移到文件尾时,lseek(int fildes,0,SEEK_END)。
3、想要取得目前文件位置时,lseek(int fildes,0,SEEK_CUR)
返回值
当调用成功时则返回目前的读写位置,也就是距离文件开头多少个字节;若有错误则返回-1,errno会存放错误代码
Linux系统不允许lseek( )对tty装置作用,此项动作会令lseek( )返回ESPIPE
---------------------------------------------------------------------------------------------------------------------------------
读一行写一行 实现文件复制 demo
代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
int read_line(int fd, void *ptr, int max_len)
{
int n_r;
int i = 0;
char *buffer = (char *)ptr;
char temp;
for (i = 0; i < max_len; i++)
{
n_r = read(fd, &temp, 1);
if (n_r < 0)
{
perror("read error:");
}
if (n_r == 0)
{
if (i == 0)
{
return 0;
}
return i;
}
if (temp == '\n')
{
buffer[i] = temp;
buffer[i + 1] = '\0';
return i + 1;
}
else
{
buffer[i] = temp;
}
}
buffer[i] = '\n';
buffer[i + 1] = '\0';
return i;
}
int main(int argc, char **argv)
{
if (argc != 3)
{
printf("Please input file name!\n");
exit(1);
// void exit(int status) 头文件 --- <stdlib.h> status --- 给父进程的返回值
// 关闭所有文件,终止正在执行的进程
// exit(1) 表示异常退出
// exit(x) x != 0 都表示异常退出
// exit(0) 表示正常退出
}
int fd;
int to_fd;
char buffer[1024];
if ((fd = open(argv[1], O_RDWR | O_CREAT, 0655)) < 0)
{
perror("open file error:");
exit(1);
}
if ((to_fd = open(argv[2], O_RDWR | O_CREAT | O_TRUNC, 0655)) < 0)
// O_TRUNC 会将文件原本的内容全部丢弃,文件大小变为 0。
{
perror("open file error:");
exit(1);
}
#if 0
lseek(fd,0,SEEK_SET);
// SEEK_CUR -- 表示当前位置
// SEEK_END -- 表示结尾位置
// SEEK_SET -- 从文件开始
// 返回值 成功反悔当前位置到开始位置的长度
// 失败返回-1 并设置error
memset(buffer,0,sizeof(buffer));
while(read_line(fd,buffer,sizeof(buffer)-1) != 0) //遇到“/n”或者缓冲最大值时,停止读取数据
{
printf("%s\n",buffer);
memset(buffer,0,sizeof(buffer));
}
#endif
while (read_line(fd, buffer, sizeof(buffer) - 1) != 0)
{
write(to_fd, buffer, strlen(buffer));
memset(buffer, 0, sizeof(buffer));
}
close(fd);
return 0;
}
运行结果:
superlan@GodFather:~/C_Language/file_io$ ./a.out open.c open.txt
superlan@GodFather:~/C_Language/file_io$ ls
a.out creat.c lseek_return.c open.c open.txt read_line_by_line.c read_line.c three_hello.c
superlan@GodFather:~/C_Language/file_io$ ls -l
总计 48
-rwxrwxr-x 1 superlan superlan 16392 7月 30 21:02 a.out
-rw-rw-r-- 1 superlan superlan 658 7月 30 14:47 creat.c
-rwxrwxrwx 1 superlan superlan 442 4月 5 20:56 lseek_return.c
-rw-rw-r-- 1 superlan superlan 476 7月 30 16:25 open.c
-rw-r-xr-x 1 superlan superlan 476 7月 30 21:06 open.txt
-rwxrwxrwx 1 superlan superlan 2709 7月 30 21:04 read_line_by_line.c
-rwxrwxrwx 1 superlan superlan 853 7月 30 21:01 read_line.c
-rwxrwxrwx 1 superlan superlan 1317 4月 6 16:12 three_hello.c