一.Linux文件操作
1.什么是文件?Linux如何看待文件?
文件: 以实现某种功能、或某个软件的部分功能为目的而定义的一个单位。
可通过操作系统或者程序对外提供信息,也能对内输入信息,可以被创建,删除。
Linux一切皆是文件
2.如何来操作文件?
在Linux中对目录和设备的操作都等同于对文件的操作,都是使用文件描述符来进行的。
3.什么是文件描述符?linux内核如何分配描述符?
v 文件描述符是一个非负的整数,它是一个索引值,并指向在内核中每个进程打开文件的记录表。
v 当打开一个现存文件或创建一个新文件时,内核就向进程返回一个文件描述符;当需要读写文件时,也需要把文件描述符作为参数传递给相应的函数。
v 当开始运行程序时,也就是系统开始运行时,它一般会有三个已经打开的文件描述符。他们是:0:标准输入1:标准输出2:标准错误
4.什么是带缓存IO操作?什么是不带缓存IO操作?
标准I/O库就是带缓存的I/O,尽可能地减少使用read和write调用的次数,它由ANSI C标准说明。
不带缓存的I/O对是文件描述符操作(create open read write lseek close),带缓存的I/O是针对流的。
二.不带缓存的IO操作
有缓存与无缓存的区别 (见一.4)
有哪些API函数?函数的作用,入参,返回值是什么?
系统调用——创建creat
函数的作用:创建一个文件
函数的原型:int creat(const char *pathname,mode_t mode);
文 件 头:#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
返 回 值:成功:新的文件描述符
出错:-1
mode:创建模式
S_IRUSR:可读
S_IWUSR:可写
S_IXUSR:可执行
S_IXRWU:可读、可写、可执行
系统调用——打开open
函数的作用:打开一个文件;
函数的原型:int open(const char *pahtname, int flags);
int open(const char *pahtname, int flags, mode_t mode);
返 回 值:文件描述符---成功;出错:-1;
flags:
参数:
O_RDONLY: 只读
O_WRONLY: 只写
O_RDWR: 可读可写
O_CREAT: 如果原来这个文件不存在,那么有这个参数就可以创建这个文件;
O_APPEND: 原来有内容,则会自动保留文件内容,自动向下读写;
O_TRUNC: 文件存在,有内容,文件清空;
系统调用——读read
函数的作用: 从打开的文件中读取数据
函数的原型:ssize_t read(int fd, void *buf, size_t count);
头 文 件: #include <unistd.h>
返 回 值:正常是实际读到的字节数;
如果是在文件结束或者是无数据,返回0;
出错,-1;
系统调用——写write
函数的作用: 向打开的文件中写数据
函数的原型: ssize_t write(int fd, const void *buf, size_t count);
头 文 件: #include <unistd.h>
返 回 值: 成功会返回实际写入的字节数;
出错:-1;
系统调用——定位lseek
函数的功能:进行文件定位
函数的原型: int lseek(int fd, offset_t offset, int whence);
函数的参数:fd:
offset: 指针的微调,在指定的指针向前移动为负, 向后为正;
whence: SEEK_SET:放在文件头
SEEK_CUR:当前的位置;
SEEK_END: 文件尾;
返 回 值:返回文件当前指针到文件开始的地方有多少字节;
出错-1;
示例:拷贝函数:
如何实现写完一个文件,就立刻读出来?
v 先关闭文件指针,再打开,之后read读出
v lseek调整文件指针位置到开头,之后read读出
如何实现文件指针的移动?如何求一个文件的大小长度?
lseek(fd,-5,SEEK_CUR) 指针从当前位置向前移动5个字节
求文件大小:lseek(fd,0,SEEK_END)
三.带缓存的IO操作
库函数——打开fopen
函数的作用: 打开文件
函数的原型:FILE *fopen(const char *pth, const char *mode)
mode:
r:读,文件必须存在;
r+:打开可读写,文件必须存在;
w:打开只写文件,文件不存在就会创建文件;文件清0;
w+:打开可读写的文件,
a:附加的形式打开只写文件,不存在就创建,存在就写到原来的文件尾。
a+:以附加的形式打开可读写的文件,不存在就创建,存在就写到原来的文件尾。
b:二进制文件
文 件 头:#include <stdio.h> #include " "
返 回 值: 成功是指向=文件流的指针;
出错返回NULL;
[html] view plain copy
1. #include <stdio.h>
2. int main()
3. {
4. FILE * fp;
5. fp = fopen(“hello.c”,“r+”);
6. if(fp != NULL)
7. {
8. printf(“fopen is ok!\n”);
9. }
10.fclose(fp);
11. return 0;
12.}
13.
库函数——字符写fputc
函数的作用: 将一个指定的字符写入到文件流中;
函数的原型: int fputc(int c, FILE *stream);
返 回 值: 返回写入成功的字符,c; EOF则表示失败。
库函数——字符读fgetc
函数的作用:从文件流中读取一个字符
函数原型: intfgetc(FILE *stream)
返 回 值:返回值正常的是读取的字符;EOF表示到了文件尾;
库函数——字符串写fputs
函数的作用:将一个字符串写入到文件内
函数的原型:int fputs(const char *s, FILE *stream)
返 回 值:成功返回写成字符数; EOF表示出错
#include <string.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#define BUFFER_SIZE 1024
int main(int argc,char **argv)
{
FILE *from_fd;
FILE *to_fd;
long file_len=0;
char buffer[BUFFER_SIZE];
char *ptr;
/*判断入参*/
if(argc!=3)
{
printf("Usage:%s fromfile tofile\n",argv[0]);
exit(1);
}
/* 打开源文件 */
if((from_fd=fopen(argv[1],"rb"))==NULL)
{
printf("Open %s Error\n",argv[1]);
exit(1);
}
/* 创建目的文件 */
if((to_fd=fopen(argv[2],"wb"))==NULL)
{
printf("Open %s Error\n",argv[2]);
exit(1);
}
/*测得文件大小*/
fseek(from_fd,0L,SEEK_END);
file_len=ftell(from_fd);
fseek(from_fd,0L,SEEK_SET);
printf("from file size is=%d\n",file_len);
/*进行文件拷贝*/
while(!feof(from_fd))
{
fread(buffer,BUFFER_SIZE,1,from_fd);
if(BUFFER_SIZE>=file_len)
{
fwrite(buffer,file_len,1,to_fd);
}
else
{
fwrite(buffer,BUFFER_SIZE,1,to_fd);
file_len=file_len-BUFFER_SIZE;
}
memset(buffer, 0, BUFFER_SIZE);
//bzero(buffer,BUFFER_SIZE); //清零
}
fclose(from_fd);
fclose(to_fd);
exit(0);
}
结果
如何判断文件读写结束?
v 基于缓存:用read函数当返回值为0时,表示到了文件尾
v 基于无缓存:用feof函数,检查文件流是否到了文件尾
如何判断文件读写结束?
v 基于缓存:用read函数当返回值为0时,表示到了文件尾
v 基于无缓存:用feof函数,检查文件流是否到了文件尾vv