设为首页 加入收藏

TOP

C中级 - 文件辅助操作(一)
2018-10-21 16:09:02 】 浏览:100
Tags:中级 文件 辅助 操作

引言 - 业务有点麻烦

    C 功能很强大, 同样书写起来会谨慎(拖泥带水). 不妨通过一个小问题来描述裹脚的 C

需求:
    用 C 创建一个文件!

难点在于
    1. 文件路径切割成 目录 + 文件名
    2. 目录 多级创建
    3. 跨平台
这个问题也挺适合做线下面试作业.

本文围绕下面几个重点讲述
    1. 获取文件更新时间
    2. 目录创建和文件删除
    3. 配置自动更新
应对平台是 Winds cl 和 Linux gcc :)

    在开始之前, 先介绍一些文件辅助基础函数, 构造了两个最初的原始的 mkdir 和 mtime 函数.
mkdir 在 shell 中用于构建目录,常很用. 对于 mtime 是 Linux 对于文件最后修改时间. 
最初来自于下面文件详细信息结构中
struct stat {
    unsigned long   st_dev;     /* Device.  */
    unsigned long   st_ino;     /* File serial number.  */
    unsigned int    st_mode;    /* File mode.  */
    unsigned int    st_nlink;   /* Link count.  */
    unsigned int    st_uid;     /* User ID of the file's owner.  */
    unsigned int    st_gid;     /* Group ID of the file's group. */
    unsigned long   st_rdev;    /* Device number, if device.  */
    unsigned long   __pad1;
    long            st_size;    /* Size of file, in bytes.  */
    int             st_blksize; /* Optimal block size for I/O.  */
    int             __pad2;
    long            st_blocks;  /* Number 512-byte blocks allocated. */
    long            st_atime;   /* Time of last access.  */
    unsigned long   st_atime_nsec;
    long            st_mtime;   /* Time of last modification.  */
    unsigned long   st_mtime_nsec;
    long            st_ctime;   /* Time of last status change.  */
    unsigned long   st_ctime_nsec;
    unsigned int    __unused4;
    unsigned int    __unused5;
};
在结构体中 st_atime, st_mtime, st_ctime 字段可以知道, Linux 文件有三个时间属性: 

1. mtime: 文件内容最后修改时间
2. ctime: 文件状态改变时间, 如权限, 属性被更改
3. atime: 文件内容被访问时间, 如 cat, less 等

在默认情况下, ls 显示出来的是该文件的 mtime, 即文件内容最后修改时间. 
如果你需要查看另外两个时间, 可以使用 ls -l --time ctime 命令.

消化上面小知识, 加上下面先入为主的设计思路, 就构建了代码 head 部分
#ifndef _H_FILE
#define _H_FILE

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifdef __GNUC__

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

//
// mkdir - 通用的单层目录创建函数宏, 等价于 mkdir path
// path     : 目录路径加名称
// return   : 0表示成功, -1表示失败, 失败原因都在 errno
// 
#undef  mkdir
#define mkdir(path)                                 \
mkdir(path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)

//
// mtime - 得到文件最后修改时间
// path     : 文件名称
// return   : 返回时间戳, -1 表示错误
//
inline time_t mtime(const char * path) {
    struct stat ss;
    // 数据最后的修改时间
    return stat(path, &ss) ? -1 : ss.st_mtime;
}

#endif

#ifdef _MSC_VER

#include <io.h>
#include <direct.h>
#include <windows.h>

// int access(const char * path, int mode /* 四个检测宏 */);
#ifndef F_OK
#   define  F_OK    (0)
#endif       
#ifndef X_OK 
#   define  X_OK    (1)
#endif       
#ifndef W_OK 
#   define  W_OK    (2)
#endif       
#ifndef R_OK 
#   define  R_OK    (4)
#endif

inline time_t mtime(const char * path) {
    WIN32_FILE_ATTRIBUTE_DATA wfad;
    if (!GetFileAttributesEx(path, GetFileExInfoStandard, &wfad))
        return -1;
    // 基于 winds x64 sizeof(long) = 4
    return *(time_t *)&wfad.ftLastWriteTime;
}

#endif

#endif
原始的 mkdir 仿照 Winds 上面的 mkdir 接口设计. 
    _Check_return_ _CRT_NONSTDC_DEPRECATE(_mkdir)
    _ACRTIMP int __cdecl mkdir(
        _In_z_ char const* _Path
        );
最终行为和 Linux 的 mkdir 创建目录命令一致(0665,即-rw-rw-r-x).
mtime 得到文件最后修改时间. 主要用于获取时间变化促使配置自动更新.
F_OK, X_OK, W_OK, R_OK 在 Winds 上实现 access 接口缺少的宏定义.
更加具体可以参照

file.h

前言 - 文件辅助操作

前言部分可能最精华, 开始步入正轨 ~
//
// mkdirs - 创建多级目录
// path     : 目录路径
// return   : < 0 is error, 0 is success
//
int 
mkdirs(const char * path) {
    char c, * p, * s;

    // 参数错误直接返回
    if (!path || !*path) return -2;
    // 文件存在 or 文件一次创建成功 直接返回
    if (!access(path, F_OK) || !mkdir(path))
        return 0;

    // 跳过第一个 ['/'|'\\'] 检查是否是多级目录
    p = (char *)path;
    while ((c = *++p) != '\0')
        if (c == '/' || c == '\\')
            break;
    if (c == '\0') return -1;

    // 开始循环构建多级目录
    s = p = strdup(path);
    while ((c = *++p) != '\0') {
        if (c == '/' || c == '\\') {
            *
首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇浮点数据有损压缩算法 附完整C代码 下一篇【数据结构】循环队列 C语言实现

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目