本次训练计划是Linux操作系统下的文件IO系统调用与文件拷贝,如有时间希望大家也能抽时间去玩一下Windows的文件系统调用,对比两者学习,本人因为秋招时间将至,时间仓促,暂时抽不出时间写Windows的文件系统调用方面的博客,后期会有更新!
int open(const char *path, int oflag, ... /*mode_t mode*/);
open()系统调用用来打开一个文件,并返回一个文件描述符(file description), 并且该文件描述符是当前进程最小、未使用的
文件描述符数值。
参数: path: 要打开的文件、设备的路径
oflag: 由多个选项进行“或”运算构造oflag参数 。
必选: O_RDONLY (只读)、 O_WRONLY(只写)、 O_RDWR(读写)
可选: O_APPEND 每次写时都追加到文件的尾端。
O_CREAT 文件不存在则创建它,使用该选项需要第三个参数mode
O_TRUNC 如果文件存在,而且为只写或读写成功打开,则将其长度截取为0;
O_NONBLOCK 如果path是一个FIFO、块设备、字符特殊文件则此选项为文件的本次打开和后续的I/O操作
设置非阻塞模式方式。
O_EXEC、O_SEARCH、O_CLOEXEC、O_NOCTTY....
mode: oflag带O_CREAT选项时可以用来创建文件,这时必须带该参数用来指定创建文件的权限模式,如066。 否则不
需要。使用示例代码:
int fd;
fd = open(“text.txt”, O_RDWR|O_CREAT|O_TRUNC, 0666);
fd = open(“text.txt”, O_WRONLY|O_APPEND);
int creat(const char *path, mode_t mode);
此函数用来创建一个新文件并返回其fd。它等价于 open(path, O_WRONLY|O_CREAT|O_TRUNC, mode);
int fd;
fd=creat(“text.txt”, 0644);
int close(int fd);
该函数用来关闭一个打开的文件描述符,关闭一个文件时还会释放该进程加在该文件上的所有记录锁。当一个进程终止时,
内核将会自动关闭它所有打开的文件。
ssize_t write(int fd, const void *buf, size_t nbytes);
write()函数用来往打开的文件描述符fd指向的文件中写入buf指向的数据,其中nbytes指定要写入的数据大小。如果返回值
<0则说明写入出错,譬如尝试往一个只读的文件中写入则会抛错,错误的原因系统会保存到errno变量中去。如果>0则为实
际写入的数据大小。
ssize_t read(int fd, void *buf, size_t nbytes);
read()函数用来从打开的文件描述符对应的文件中读取数据放到buf指向的内存空间中去,最多不要超过nbytes个字节,这里
的nbytes一般是buf剩余的空间大小。如read成功,则返回实际读到的字节数(由nbytes或读到文件尾决定,其中EOF宏用
来判断是否到了文件尾),如果返回值小于0则表示出错,如尝试读一个没有权限读的文件时就会抛错。
off_t lseek(int fd, off_t offset, int whence);
我们在从文件里读出内容,或往文件写如内容的时候都有一个起始地址,这个起始地址就是当前文件偏移量,当我们对文件
进行读写的时候都会使文件偏移量往后偏移。这点就类似于我们打开记事本开始编辑文本时的光标,我们读或写入时从光标
所在位置开始读写,每读写一个字节都会使光标往后偏移。通过lseek()这个函数我们可以调整文件偏移量的地址。
其中 whence 可以是以下三个值:
而offset就是相对于whence 的偏移量,譬如:
lseek(fd, 0, SEEK_SET); 将文件偏移量设置到了文件开始的第一个字节上;
lseek(fd, 0, SEEK_END); 将文件偏移量设置到文件最后一个字节上;
lseek(fd, -1, SEEK_END); 将文件偏移量设置到文件最后的倒数第一个字节上;
#include
#include
#include
#include
#include
#include
#include
#define buffsize 1024 //定义存储数据的长度大小为buffsize
#define message_str "Hello World\n" //写入创建文件的内容
int main(int argc , char *argv[])
{
/*Linux操作系统:return 0 为正常返回,return -1 出错,很多时候会用-1、-2等数据来比较错误,用echo $?在终端会有上次运行的返回值,以此来判断程序发生错误的位置*/
int fd = -1; //考虑最糟糕的情况,所以一开始赋值为-1
int rv = -1; //考虑最糟糕的情况,所以一开始赋值为-1
char buff[buffsize]; //创建buff
fd = open("hello.txt",O_RDWR | O_CREAT | O_TRUNC , 0666);
if(fd < 0)
{
perror("创建文件失败!");
return 0;
}
printf("Open file return file director:[%d]\n",fd);
rv = write(fd,message_str,strlen(message_str));
if(rv < 0)
{
printf("write %d bytes into file failure:%s\n",rv,strerror(errno));
goto cleanup;
}
lseek(fd,0,SEEK_SET);
memset(buff,0,sizeof(buff));
rv = read(fd,buff,sizeof(buff));
if(rv < 0)
{
printf("Read data from file failure: %s\n",strerror(errno));
goto cleanup;
}
printf("Read %d bytes data from files: %s\n",rv,buff);
cleanup:
close(fd);
return 0 ;
}
int mkdir(const char *pathname, mode_t mode);//创建文件夹
int rmdir(const char *pathname);//删除文夹
DIR *opendir(const char *pathname);//打开文件夹
struct dirent * readdir(DIR *dp);//读文件夹
int closedir(IDR *dp);//关闭文件夹
int chdir(const char * pathname);//改变文件操作目录
#include
#include
#include
#include
#include
#include
#include
#include
#define TEST_DIR "dir"
int main(int argc, char **argv)
{
int rv;
int fd1;
int fd2;
DIR *dirp;
struct dirent *direntp;
/* 创建文件夹dir, 并设置文件夹权限为755 */
if (mkdir(TEST_DIR, 0777) < 0)
{
printf("create directory '%s' failure: %s\n", TEST_DIR, strerror(errno));
return -1;
}
/* 更改当前工作路径到文件夹dir下去 */
if (chdir(TEST_DIR) < 0)
{
printf("Change directory to '%s' failure: %s\n", TEST_DIR, strerror(errno));
rv = -2;
goto cleanup;
}
/* 在dir文件夹下 创建普通文本文件file1.txt,并设置其权限位为644 */
if ((fd1 = creat("file1.txt", 0777)) < 0)
{
printf("Create file1.txt failure: %s\n", strerror(errno));
rv = -3;
goto cleanup;
}
/* 在dir文件夹下 创建普通文本文件file2.txt,并设置其权限位为644 */
if ((fd2 = creat("file2.txt", 0777)) < 0)
{
printf("Create file2.txt failure: %s\n", strerror(errno));
rv = -4;
goto cleanup;
}
/* 更改当前工作路径到父目录去 */
if (chdir("../") < 0)
{
printf("Change directory to '%s' failure: %s\n", TEST_DIR, strerror(errno));
rv = -5;
goto cleanup;
}
/* 打开dir文件夹 */
if ((dirp = opendir(TEST_DIR)) == NULL)
{
rv = -6;
printf("opendir %s error: %s\n", TEST_DIR, strerror(errno));
goto cleanup;
}
/* 列出dir里面的所有文件和文件夹 */
while ((direntp = readdir(dirp)) != NULL)
{
printf("Find file: %s\n", direntp->d_name);
}
/* 关闭所有打开的文件夹 */
closedir(dirp);
cleanup:
if (fd1 >= 0)
{
close(fd1);
}
if (fd2 >= 0)
{
close(fd2);
}
}
#include
#include
#include
#include
#include
#include
#include
#include
char buff[1024];
int len;
int main(int argc,char const*argv[])
{
char const *src_path = argv[1];
char const *des_path = argv[2];
int fd, fd2;
fd = open(src_path,O_RDWR | O_CREAT);
fd2 = open(des_path,O_RDWR | O_CREAT,0666);
while(len=read(fd,buff,sizeof(buff)))
{
write(fd2,buff,len);
}
return 0;
}
文件IO系统调用、文件夹操作系统调用和文件拷贝,是学习Linux最为基础的一部分,但是也是很重要的一部分,后面将会使用以上三者实现树莓派与DS18B20温度传感器进行通讯并采集环境温度。