【从零开始的嵌入式生活】文件I/O 2——文件IO和库(1)

简介: 【从零开始的嵌入式生活】文件I/O 2——文件IO和库(1)

文章目录

文件IO——介绍

文件描述符

文件操作

open函数

close函数

read函数

write函数

lseek函数

目录操作

opendir函数

readdir函数

chmod/fchmod函数用来修改文件的访问权限:

stat/lstat/fstat函数用来获取文件属性:

通过系统提供的宏来判断文件类型:

通过系统提供的宏来获取文件访问权限:

程序库

库的基本概念

静态库特点

静态库创建

共享库

共享库创建

共享库使用

写在最后

文件IO——介绍

posix(可移植操作系统接口)定义的一组函数

不提供缓冲机制,每次读写操作都引起系统调用

核心概念是文件描述符

Linux下, 标准IO基于文件IO实现

6a93e255f05467b40f08f2f0f7f6829.png


文件描述符

每个打开的文件都对应一个文件描述符。

文件描述符是一个非负整数。Linux为程序中每个打开的文件分配一个文件描述符。

文件描述符从0开始分配,依次递增。

文件IO操作通过文件描述符来完成。

上节课有说过三个默认的文件打开表象,分别就是012对应stdin stdout stderrr


文件操作

open函数

#include <fcntl.h>
int open(const char *path, int oflag, mode_t mode);


成功时返回文件描述符;出错时返回EOF

打开文件时使用两个参数

创建文件时第三个参数指定新文件的权限

只能打开设备文件


e68115841ff88f2e539c41ff2fd3446.png

close函数

#include  <unistd.h>
int  close(int fd);


成功时返回0;出错时返回EOF

程序结束时自动关闭所有打开的文件

文件关闭后,文件描述符不再代表文件

read函数

#include  <unistd.h>
ssize_t  read(int fd, void *buf, size_t count);


成功时返回实际读取的字节数;出错时返回EOF

读到文件末尾时返回0

buf是接收数据的缓冲区

count不应超过buf大小

综合应用代码


#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
int main(){
        int fd;
        int n = 0;
        char buf[2];
        fd = open("1.txt", O_RDONLY|O_EXCL, 0666);
        if(fd){
                while(read(fd, buf, 1) > 0){
                        n++;
                }
                printf("n=%d\n", n);
        }
        close(fd);
        return 0;
}


write函数

#include  <unistd.h>
ssize_t  write(int fd, void *buf, size_t count);


成功时返回实际写入的字节数;出错时返回EOF

buf是发送数据的缓冲区

count不应超过buf大小

示例代码


#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
int main(){
       int fd;
       int n = 0;
      char buf[11];
       fd = open("1.txt", O_RDWR|O_APPEND, 0666);
       if(fd){
               fgets(buf, 10, stdin);
               write(fd, buf, 10);
       }
       close(fd);
       return 0;
}

lseek函数

#include  <unistd.h>
off_t  lseek(int fd, off_t offset, intt whence);


成功时返回当前的文件读写位置;出错时返回EOF

参数offset和参数whence同fseek完全一样

目录操作

opendir函数

#include  <dirent.h>
DIR  *opendir(const char *name);


DIR是用来描述一个打开的目录文件的结构体类型

成功时返回目录流指针;出错时返回NULL

readdir函数

#include  <dirent.h>
struct  dirent *readdir(DIR *dirp);


struct dirent是用来描述目录流中一个目录项的结构体类型

包含成员char d_name[256] 参考帮助文档

成功时返回目录流dirp中下一个目录项;

出错或到末尾时时返回NULL

综合示例代码

#include <dirent.h>
#include <stdio.h>
int main(){
       DIR *dir;
       struct dirent *dent;
       dir = opendir(".");
       if(dir)
               while((dent = readdir(dir)) != NULL)
                       printf("%s\n", dent->d_name);
       return 0;
}


chmod/fchmod函数用来修改文件的访问权限:

#include  <sys/stat.h>
int  chmod(const char *path, mode_t mode);
int  fchmod(int fd, mode_t mode);


成功时返回0;出错时返回EOF

root和文件所有者能修改文件的访问权限

stat/lstat/fstat函数用来获取文件属性:

#include  <sys/stat.h>
int  stat(const char *path, struct stat *buf);
int  lstat(const char *path, struct stat *buf);
int  fstat(int fd, struct stat *buf);


成功时返回0;出错时返回EOF

如果path是符号链接stat获取的是目标文件的属性;而lstat获取的是链接文件的属性

struct stat是存放文件属性的结构体类型:


struct stat {
   dev_t         st_dev;       //文件的设备编号
   ino_t         st_ino;       //节点
   mode_t        st_mode;      //文件的类型和存取的权限
   nlink_t       st_nlink;     //连到该文件的硬连接数目,刚建立的文件值为1
   uid_t         st_uid;       //用户ID
   gid_t         st_gid;       //组ID
   dev_t         st_rdev;      //(设备类型)若此文件为设备文件,则为其设备编号
   off_t         st_size;      //文件字节数(文件大小)
   unsigned long st_blksize;   //块大小(文件系统的I/O 缓冲区大小)
   unsigned long st_blocks;    //块数
   time_t        st_atime;     //最后一次访问时间
   time_t        st_mtime;     //最后一次修改时间
   time_t        st_ctime;     //最后一次改变时间(指属性)
};


相关文章
|
1月前
|
搜索推荐 索引
【文件IO】实现:查找文件并删除、文件复制、递归遍历目录查找文件
【文件IO】实现:查找文件并删除、文件复制、递归遍历目录查找文件
34 2
|
1月前
|
编解码 Java 程序员
【文件IO】文件内容操作
【文件IO】文件内容操作
47 2
|
1月前
|
存储 Java API
【文件IO】文件系统操作
【文件IO】文件系统操作
40 1
|
1月前
|
存储 Java 程序员
【Java】文件IO
【Java】文件IO
35 0
|
3月前
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。
|
4月前
|
Java 大数据
解析Java中的NIO与传统IO的区别与应用
解析Java中的NIO与传统IO的区别与应用
|
2月前
|
Java 大数据 API
Java 流(Stream)、文件(File)和IO的区别
Java中的流(Stream)、文件(File)和输入/输出(I/O)是处理数据的关键概念。`File`类用于基本文件操作,如创建、删除和检查文件;流则提供了数据读写的抽象机制,适用于文件、内存和网络等多种数据源;I/O涵盖更广泛的输入输出操作,包括文件I/O、网络通信等,并支持异常处理和缓冲等功能。实际开发中,这三者常结合使用,以实现高效的数据处理。例如,`File`用于管理文件路径,`Stream`用于读写数据,I/O则处理复杂的输入输出需求。
|
3月前
|
Java 数据处理
Java IO 接口(Input)究竟隐藏着怎样的神秘用法?快来一探究竟,解锁高效编程新境界!
【8月更文挑战第22天】Java的输入输出(IO)操作至关重要,它支持从多种来源读取数据,如文件、网络等。常用输入流包括`FileInputStream`,适用于按字节读取文件;结合`BufferedInputStream`可提升读取效率。此外,通过`Socket`和相关输入流,还能实现网络数据读取。合理选用这些流能有效支持程序的数据处理需求。
46 2
|
3月前
|
XML 存储 JSON
【IO面试题 六】、 除了Java自带的序列化之外,你还了解哪些序列化工具?
除了Java自带的序列化,常见的序列化工具还包括JSON(如jackson、gson、fastjson)、Protobuf、Thrift和Avro,各具特点,适用于不同的应用场景和性能需求。
|
3月前
|
缓存 Java
【IO面试题 一】、介绍一下Java中的IO流
Java中的IO流是对数据输入输出操作的抽象,分为输入流和输出流,字节流和字符流,节点流和处理流,提供了多种类支持不同数据源和操作,如文件流、数组流、管道流、字符串流、缓冲流、转换流、对象流、打印流、推回输入流和数据流等。
【IO面试题 一】、介绍一下Java中的IO流