目录-文件

来源:互联网 发布:java将gbk转换成utf8 编辑:程序博客网 时间:2024/05/21 05:23
文件IO(unix)
    everything is a file in unix.
    文件描述符(file descriptor), 操作文件必须通过文件描述符。(进程文件表项的下标)
    >=0的整数
    在unix下,操作系统会为每个进程自动打开三个设备:
        标准输入设备:STDIN_FILENO
        标准输出设备:STDOUT_FILENO
        标准出错设备:STDERR_FILENO

        //printf("hello");
            //=> write(STDOUT_FILENO, "hello", 5);
            
文件IO操作接口函数(API) (fileIO.c)
1.打开/关闭一个文件
2.读写一个文件
//3. ioctl
3. 定位

4. mmap/munmap


1. 打开/关闭一个文件

    NAME
       open, creat - open and possibly create a file or device

    SYNOPSIS
       #include <sys/types.h>
       #include <sys/stat.h>
       #include <fcntl.h>

        open用来打开一个文件(或创建一个文件并打开它)
       int open(const char *pathname, int flags);
       int open(const char *pathname, int flags, mode_t mode);
               pathname: 要打开的文件的文件名(带路径)
               flags: 打开标志。用位域实现
                   O_RDONLY:  RD, read 只读打开
                   O_WRONLY: WR,     write只写打开
                   O_RDWR:  read write 读写打开
                   以上三个标志任选其一
                   O_APPEND: 追加方式。
                O_CREAT : create创建标志(如果文件不存在则创建)
                O_NONBLOCK:  non block 非阻塞方式打开。
                            "阻塞方式": 如果文件为空,read则会等待
                            "非阻塞方式":你懂的
                O_EXCL: 该标志一般和O_CREAT 配合使用(O_CREAT | O_EXCL),
                        用来测试文件是否存在。指定O_CREAT | O_EXCL,
                        如果文件存在,则open会失败,并且errno == EEXIST
                O_TRUNC: truncate(剪断), 截短标志.(清零)
                        假如文件存在,并且是一个普通文件,而且
                        打开方式是O_RDWR或 O_WRONLY,则文件内容会被
                        清空。
                ...
            mode: 用来指定新创建的文件的权限,有两种方式:
                (1) S_IRUSR, S_IWUSR, S_IXUSR   -> S_IRWXU == S_IRUSR | S_IWUSR | S_IXUSR
                    S_IRGRP, S_IWGRP,S_IXGRP   -> S_IRWXG ==
                    S_IROTH, S_IWOTH, S_IXOTH -> S_IRWXO ==

                        S_IRUSR | S_IRGRP | S_IROTH
                (2) 0660
                           

           返回值:
               如果成功返回一个文件描述符,后续对该文件的操作
                   都必须通过此文件描述符。
               失败返回-1, errno被设置

        creat仅用来创建一个文件,
       int creat(const char *pathname, mode_t mode);
           成功返回0,失败返回-1

    =====
        
    NAME
       close - close a file descriptor

    SYNOPSIS
       #include <unistd.h>

       int close(int fd);
           
2. 读写一个文件 read/write
    NAME
       read - read from a file descriptor

    SYNOPSIS
       #include <unistd.h>

        read用来从fd指定的文件中,读取 count个字节到
        buf指定的内存空间。
       ssize_t read(int fd, void *buf, size_t count);
           fd: 文件描述符,表示要从哪个文件里读数据
           buf: 指针,指向一段内存,用来保存从文件中读取
               到的数据
           count: 表示要读多少字节数据
           返回值:
               > 0 表示成功读取到的数据的字节数
               = -1: 表示失败了,errno被设置
               =0: 表示文件结束了。

    
        ==
        NAME
       write - write to a file descriptor

    SYNOPSIS
       #include <unistd.h>

        write用来把buf指向的内存空间中的前面count个字节
        写到fd指定的文件中去
       ssize_t write(int fd, const void *buf, size_t count);
           fd:    文件描述符,表示要写到哪个文件中去
           buf:指针,指向要写的数据
           count:表示要写多少字节数据
           返回值:
               > 0: 表示成功写了多少个字节
               =-1: 失败了,errno被设置
               =0: 表示什么也没写。

           练习:
               用文件IO的接口写一个程序,来实现两个文件的拷贝。

        read/write成功后,光标位置会自动增加n个位置(n表示你成功读或写的
        字节数)

3.定位光标

    NAME
       lseek - reposition read/write file offset

    SYNOPSIS
       #include <sys/types.h>
       #include <unistd.h>

       off_t lseek(int fd, off_t offset, int whence);
        fd: 要重定位的文件
        offset: 偏移量,可正可负,具体含义需要结合第三个参数
        whence: 定位方式,有三种:
            SEEK_SET: 基于文件开头定位
            SEEK_CUR:  基于文件当前位置定位
            SEEK_END:  基于文件末尾定位
        返回值:
            成功返回新光标位置相对于文件开头的偏移量(以字节为单位)
            失败返回-1, errno被设置。

        例子:
            如何求一个文件的大小?
                unsinged long filesize = lseek(fd, 0, SEEK_END);

        注意:
             我们在实际读写文件前,一般要先定位lseek

       
    我们能不能像操作内存一样,去操作文件呢?
    当然可以。
    需要用到mmap
4. mmap

    NAME
           mmap, munmap - map or unmap files or devices into memory

    SYNOPSIS
           #include <sys/mman.h>

           void *mmap(void *addr, size_t length, int prot, int flags,   int fd, off_t offset);
            addr: 映射地址,表示要映射到进程地址空间的哪个位置。
                    一般为NULL, 让操作系统自动为我选择一个合适的地址。
            length:要映射的文件区域的长度。向上取PAGE_SIZE(4K)的整数倍
            prot: 映射后内存区域的权限(应与文件打开权限一致,
                    因为操作此区域内存实际上就是操作文件内容)
                    PROT_EXEC:可执行
                    PROT_READ:可读
                    PROT_WRITE:可写可读
                    PROT_NONE:没访问权限
            flags: 映射标志。决定对映射部分的操作是否对其他进程可见
                    MAP_SHARED:  共享。对其他进程可见,内存操作应用到文件中去
                    MAP_PRIVATE: 私有。对其他进程不可见,内存操作不应用到文件中去
            fd: 文件描述符,表示要映射哪个文件
            offset:偏移量,表示从文件哪个地方开始映射。
                    offset必须为PAGE_SIZE(4K)的整数倍

            返回值:
                成功返回映射后的内存首地址。
                失败返回MAP_FAILED, errno被设置。
            

               munmap就是解映射
           int munmap(void *addr, size_t length);
               addr: 要解映射的 首地址。PAGE_SIZE的整数倍。
                length: 要解映射的长度。PAGE_SIZE

               返回值:
                    成功返回0,
                    失败返回-1, errno被设置。

                    NOTE:
                        进程退出,会自动unmap,但是关闭文件不会自动unmap.
            
          
文件属性操作函数:
1.stat/fstat/lstat: get file status

2.access: 测试调用进程是否有权限去访问某个文件

3.umask : 设置文件权限掩码

4. chmod/fchmod 用来改变某个文件的权限位

5. chown/fchown/lchown 用来改变某个文件的所有者

6. truncate/ftruncate用来把某个文件截短

7. chdir 改变当前工作目录
    getcwd获取当前目录的绝对路径
8. remove /unlink/rmdir   删除一个文件或目录


1. stat/fstat/lstat用来获取文件的属性信息
    NAME
       stat, fstat, lstat - get file status

SYNOPSIS
       #include <sys/types.h>
       #include <sys/stat.h>
       #include <unistd.h>

    在linux内核中一个文件的属性(状态)信息,是用一个
    结构体struct stat来描述的。如下:

    struct stat {

            //dev_t 在内核是用来表示设备号的。设备号相当于
            //是设备的身份ID
               dev_t     st_dev;   //设备号,容纳该文件的那个设备的设备号
               
               ino_t     st_ino;     // inode number , i-node号

               
               mode_t    st_mode;   //文件权限位

               
               nlink_t   st_nlink;   //该文件的硬链接 数,
                               //硬链接与软链接的区别,你们要懂的。

               
               uid_t     st_uid;    //文件所有者的ID(用户ID)

               
               gid_t     st_gid;    //文件所有者的组ID
               
               dev_t     st_rdev;   //文件的设备号(假如该文件是设备)


               
               off_t     st_size; // 文件内容的大小,以字节为单位
                            //普通文件,目录文件,符号链接文件
                            //上述三种文件的文件内容是什么?
                            //目录文件的内容:目录项数组
                            //符号链接文件的内容是: 保存它指向的文件的文件名
               
               blksize_t st_blksize;//文件系统的块大小
               
               blkcnt_t  st_blocks;  //占多少块(固定以512为块大小)
                           
               time_t    st_atime;   // 最后访问时间,"文件内容"
               time_t    st_mtime;   //最后修改时间,"文件内容"
               time_t    st_ctime;   //最后改变时间,"文件属性", i-node
           };

        


        stat用来把path指定的文件的属性信息,保存到
        buf指向的结构体struct stat 中。
       int stat(const char *path, struct stat *buf);

           fstat功能与返回值与stat 一样,只不过,fstat是用文件描述符
           来指定文件的。
       int fstat(int fd, struct stat *buf);


           lstat功能与stat相同,只不过当path是一个符号链接时,获取的是符号
           链接本身的属性信息,而不是它指向的文件。
       int lstat(const char *path, struct stat *buf);

           返回值:
               成功返回0,
               失败返回-1, errno被设置

        例子:
            struct stat st;

            stat(path, &st);
            st.st_size ->

            st.st_mode 包含文件的类型与权限,用下列宏来解析:    
                S_ISREG(st.st_mode)   普通文件  regular file  
                S_ISDIR(st.st_mode)   目录文件directory
                S_ISCHR(st.st_mode)  字符设备  char
                S_ISBLK(st.st_mode)  块设备 block
                S_ISFIFO(st.st_mode)  管道文件  pipe(无名管道,有名管道 fifo)
                S_ISLNK(st.st_mode)  符号链接文件  link
                S_ISSOCK(st.st_mode) 套接字文件 socket

            权限位:
                S_IRUSR , S_IRGRP, S_IROTH
                S_IWUSR
                S_IXUSR
                

            if (st.st_mode & S_IRUSR)
            {
                //用户有读的权限
            }
                
                 

            练习:
                写一个程序,求任意一个文件的类型、权限、
                以及文件(假如该文件是普通文件、目录文件、符号
                链接文件)的大小.
                文件的类型和权限请按命令ls -l的形式打印


2.    access 用来测试调用进程是否有相应的权限去访问由pathname指定的文件

    NAME
           access - determine accessibility of a file

    SYNOPSIS
           #include <unistd.h>

           int access(const char *pathname, int amode);
                pathname: 要测试的文件
                amode:要测试的访问权限, "按位或",可以测试多项权限
                    R_OK : 测试是否可读
                    W_OK :  测试是否可写
                    X_OK :测试是否可执行
                    F_OK :测试文件是否存在
                            R_OK | W_OK

            返回值:
                成功返回0, 所有测试权限都OK
                失败返回-1, 至少有一项测试没通过

3 .umask 设置文件创建的掩码
    NAME
       umask - set and get the file mode creation mask

SYNOPSIS
       #include <sys/stat.h>

        掩码,当中为1的bit位, 表示你在创建文件时不能指定

       mode_t umask(mode_t cmask);

        

        umask(022);
        open(,,0660);

        =>  0644
    
    
4. chmod/fchmod:用来改变文件的权限

    NAME
       chmod, fchmod - change permissions of a file

    SYNOPSIS
       #include <sys/stat.h>

       int chmod(const char *path, mode_t mode);
       int fchmod(int fd, mode_t mode);

        chmod第一个是文件名
        fchmod第一个参数是文件描述符

            mode:新的权限 ,有两种方式指定,你懂的。
                    (1) S_IRUSR

                    (2) 0660
        返回值:
            成功返回0,
            失败返回-1, errno被设置

5. chown/fchown

    NAME
       chown, fchown, lchown - change ownership of a file

    SYNOPSIS
       #include <unistd.h>

       int chown(const char *path, uid_t owner, gid_t group);
       int fchown(int fd, uid_t owner, gid_t group);


6 .文件截短
    NAME
       truncate, ftruncate - truncate a file to a specified length

SYNOPSIS
       #include <unistd.h>
       #include <sys/types.h>

       int truncate(const char *path, off_t length);
       int ftruncate(int fd, off_t length);

        NOTE:
            假如原文件长度> length,  保留文件前面length长度,后面的没了
            假如原文件长度< length, 文件长度延伸至length,


7. chdir改变当前工作目录
    NAME
       chdir, fchdir - change working directory

    SYNOPSIS
       #include <unistd.h>

       int chdir(const char *path);

8. 获取进程当前工作目录的绝对路径名
NAME
       getcwd,  getwd,  get_current_dir_name  -  get  current  working
       directory

SYNOPSIS
       #include <unistd.h>

       char *getcwd(char *buf, size_t size);    
       char *get_current_dir_name(void);


9.    删除一个文件(普通文件或目录文件): remove


    删除普通文件:
        unlink
    删除一个空目录:
        rmdir

    NAME
       remove - remove a file or directory

    SYNOPSIS
       #include <stdio.h>

        remove用来删除pathname指定的文件或目录
       int remove(const char *pathname);
           返回值:
               成功返回0,
               失败返回-1, errno被设置。


    NAME
       unlink - delete a name and possibly the file it refers to

    SYNOPSIS
       #include <unistd.h>

        unlink用来删除一个文件系统中的名字或普通文件
       int unlink(const char *pathname);



    NAME
       rmdir - delete a directory

    SYNOPSIS
       #include <unistd.h>

        rmdir用来删除一个空目录
       int rmdir(const char *pathname);

    DESCRIPTION
       rmdir() deletes a directory, which must be empty.


目录结构及目录操作:(dir.c)

1. 创建、删除目录
    mkdir
    rmdir
    
    
2. 打开一个目录
    opendir
    
    
3. 读一个目录
    readdir

4.关闭一个目录
    closedir
    
    
目录作业:
    1.写一个程序,删除一个目录(可能为空,也可能不为空)
    2.写一个程序,求一个目录下面所有的图片文件(.bmp, .jpg)的个数




1. 创建、删除一个目录
    NAME
       mkdir - create a directory

    SYNOPSIS
       #include <sys/stat.h>
       #include <sys/types.h>

        mkdir用来创建一个目录
        
       int mkdir(const char *pathname, mode_t mode);
           pathname:要创建的目录的路径名
           mode: 新创建的目录的权限,有两种方式指定:
               (1) S_IRUSR, ...
               (2) 0660
           返回值:
                成功返回0,
                失败返回-1, errno被设置。


       NAME
       rmdir - 删除一个空目录

    SYNOPSIS
       #include <unistd.h>

       int rmdir(const char *pathname);
    

2.  打开一个目录opendir
    NAME
       opendir, open a directory

    SYNOPSIS
       #include <sys/types.h>
       #include <dirent.h>

    在linux中,用结构体 DIR 来表示一个打开的目录。

       DIR *opendir(const char *name);
           name: 要打开的目录名
           返回值:
                如果成功,返回一个DIR的指针
                如果失败,返回NULL, errno被设置。


3. 读一个目录readdir

    一个目录的内容,目录项的数组。
    那么目录项是个什么东西呢?

    在linux下目录项用结构体struct dirent,定义如下:
    

      struct dirent {
               ino_t          d_ino;       //I-NODE编号
               off_t          d_off;      //数组的下标
               unsigned short d_reclen;    //该结构体的长度
               unsigned char  d_type;     //该目录项代表的文件的类型(不是所有文件系统都支持)
               
               char           d_name[256]; //该目录项代表的文件的文件名(不带路径)
           };

        d_ino, d_name只有这两个成员变量是被所有系统支持的。
        


    NAME
           readdir,  - read a directory

    SYNOPSIS
           #include <dirent.h>

            readdir用来从dirp指定的目录中,读取下一个
            目录项(struct dirent)的指针。如果一个目录中有多个
            目录项,那么你就需要调用readdir多次,直到它
            返回NULL为止。
            
           struct dirent *readdir(DIR *dirp);

                返回值:
                    成功返回目录中下一个目录项的指针
                    如果失败或读完了,返回NULL。
                            如果errno设置了,就是表示失败了。


4. 关闭一个目录

    NAME
       closedir - close a directory

SYNOPSIS
       #include <sys/types.h>

       #include <dirent.h>

       int closedir(DIR *dirp);


0 0
原创粉丝点击