IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    [原]目的文件已不在原目录,程序还会继续执行写文件操作吗?

    zhouzxi发表于 2015-09-17 17:36:34
    love 0

    最近,在现场调试程序的同事反馈回了一个问题:目的文件已不在原目录,程序还会继续执行写文件操作。我们了解了一下,具体的情况是这样的:某软件(运行在Linux下)有一个功能是在配置好的某个目录中生成文件,在文件生成的过程中,现场同事将已经生成的文件移动到了另外一个目录中;过了一段时间后发现,程序继续向移动之后的文件中写入内容,导致该文件不断增大。
    为了还原现场问题,我们编写了以下程序:

    /**********************************************************************
    * 版权所有 (C)2015, Zhou Zhaoxiong。
    *
    * 文件名称:WriteFileNonStop.c
    * 文件标识:无
    * 内容摘要:不停地写文件
    * 其它说明:无
    * 当前版本:V1.0
    * 作    者:Zhou Zhaoxiong
    * 完成日期:20150917
    *
    **********************************************************************/
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <time.h>
    #include <sys/time.h>
    
    // 数据类型重定义
    typedef signed   int        INT32;
    typedef signed   char       INT8;
    typedef unsigned char       UINT8;
    typedef unsigned short int  UINT16;
    typedef unsigned int        UINT32;
    
    
    // 函数声明
    void Sleep(UINT32 iCountMs);
    void WriteFileNonStop(void);
    INT32 main();
    
    
    /**********************************************************************
    * 功能描述:主函数
    * 输入参数:无
    * 输出参数:无
    * 返 回 值:无
    * 其它说明:无
    * 修改日期        版本号     修改人            修改内容
    * -------------------------------------------------------------------
    * 20150917       V1.0   Zhou Zhaoxiong        创建
    *********************************************************************/
    INT32 main()
    {
        WriteFileNonStop();   // 写文件
    
        return 0;             // main函数返回0
    }
    
    
    /**********************************************************************
     * 功能描述: 把内容写到本地文件中
     * 输入参数: pszContentLine-一条文件记录
     * 输出参数: 无
     * 返 回 值: 无
     * 其它说明: 无
     * 修改日期            版本号            修改人           修改内容
     * ----------------------------------------------------------------------
     * 20150917           V1.0          Zhou Zhaoxiong        创建
     ************************************************************************/
    void WriteFileNonStop(void)
    {
        FILE  *fp                  = NULL;
        INT8   szLocalFile[500]    = {0};
        INT8   szCurDate[20]       = {0};
        INT8   szContentBuf[200]   = {0};
    
        snprintf(szLocalFile, sizeof(szLocalFile)-1, "%s/zhouzhaoxiong/zzx/WriteFileNonStop/File/File.txt", getenv("HOME"));
        fp = fopen(szLocalFile, "a+");
        if (fp == NULL)
        {
             printf("WriteFileNonStop: open local file failed, file=%s\n", szLocalFile);
             return;
        }
    
        while (1)      // 不停地写文件
        {
            strcpy(szContentBuf, "hello, world!\n");
            printf("WriteFileNonStop: LocalFile=%s, ContentBuf=%s", szLocalFile, szContentBuf);
    
            fputs(szContentBuf, fp);
            fflush(fp);
    
            Sleep(10 * 1000);   // 每10s写一次
        }
    
        fclose(fp);
        fp = NULL;
    
        return;
    }
    
    
    /**********************************************************************
    * 功能描述: 程序休眠
    * 输入参数: iCountMs-休眠时间(单位:ms)
    * 输出参数: 无
    * 返 回 值: 无
    * 其它说明: 无
    * 修改日期          版本号       修改人              修改内容
    * ------------------------------------------------------------------
    * 20150917         V1.0     Zhou Zhaoxiong           创建
    ********************************************************************/
    void Sleep(UINT32 iCountMs)
    {
        struct timeval t_timeout = {0};
    
        if (iCountMs < 1000)
        {
            t_timeout.tv_sec = 0;
            t_timeout.tv_usec = iCountMs * 1000;
        }
        else
        {
            t_timeout.tv_sec = iCountMs / 1000;
            t_timeout.tv_usec = (iCountMs % 1000) * 1000;
        }
        select(0, NULL, NULL, NULL, &t_timeout);   // 调用select函数阻塞程序
    }
    

    该程序命名为“WriteFileNonStop.c”,其实现的功能是:每隔10秒向当前用户的“zhouzhaoxiong/zzx/WriteFileNonStop/File/”目录下的“File.txt”文件中写入“hello, world!”。我们之所以要用一个“while”循环来不断地写文件,就是为了查看在我们将文件移走或删除之后,程序会怎么处理。
    利用“gcc -g -o WriteFileNonStop WriteFileNonStop.c”命令编译程序之后,生成了“WriteFileNonStop”文件。接下来,我们要复现现场的问题。
    1.执行“WriteFileNonStop”命令,可以看到程序运行正常,并且在“zhouzhaoxiong/zzx/WriteFileNonStop/File/”目录下有文件生成。
    程序运行情况:

    ~/zhouzhaoxiong/zzx/WriteFileNonStop> gcc -g -o WriteFileNonStop WriteFileNonStop.c
    ~/zhouzhaoxiong/zzx/WriteFileNonStop> WriteFileNonStop
    WriteFileNonStop: LocalFile=/home/zxin10/zhouzhaoxiong/zzx/WriteFileNonStop/File/File.txt, ContentBuf=hello, world!
    WriteFileNonStop: LocalFile=/home/zxin10/zhouzhaoxiong/zzx/WriteFileNonStop/File/File.txt, ContentBuf=hello, world!
    WriteFileNonStop: LocalFile=/home/zxin10/zhouzhaoxiong/zzx/WriteFileNonStop/File/File.txt, ContentBuf=hello, world!
    WriteFileNonStop: LocalFile=/home/zxin10/zhouzhaoxiong/zzx/WriteFileNonStop/File/File.txt, ContentBuf=hello, world!

    文件生成情况:

    ~/zhouzhaoxiong/zzx/WriteFileNonStop/File> ll
    -rw-rw-rw- 1 zhou dba 42 Sep 17 16:30 File.txt
    ~/zhouzhaoxiong/zzx/WriteFileNonStop/File> tail -f File.txt 
    hello, world!
    hello, world!
    hello, world!
    hello, world!
    hello, world!

    2.我们将生成的“File.txt”文件移动到其它目录中,可以看到程序继续运行,并且文件中继续有内容生成。

    ~/zhouzhaoxiong/zzx/WriteFileNonStop/File> mv File.txt ..
    ~/zhouzhaoxiong/zzx/WriteFileNonStop/File> ll
    total 0
    ~/zhouzhaoxiong/zzx/WriteFileNonStop/File> cd ..
    ~/zhouzhaoxiong/zzx/WriteFileNonStop> ll
    drwx------ 2 zhou dba  4096 Sep 17 16:34 File
    -rw-rw-rw- 1 zhou dba   392 Sep 17 16:34 File.txt
    -rwxrwxrwx 1 zhou dba 14897 Sep 17 16:29 WriteFileNonStop
    -rw------- 1 zhou dba  3434 Sep 17 16:29 WriteFileNonStop.c
    ~/zhouzhaoxiong/zzx/WriteFileNonStop> tail -f File.txt
    hello, world!
    hello, world!
    hello, world!
    hello, world!
    hello, world!
    hello, world!
    hello, world!
    hello, world!
    hello, world!
    hello, world!
    hello, world!
    hello, world!

    3.我们将“File.txt”文件删除掉,可以看到程序继续运行,但没有文件生成。

    ~/zhouzhaoxiong/zzx/WriteFileNonStop> rm File.txt
    ~/zhouzhaoxiong/zzx/WriteFileNonStop> ll
    drwx------ 2 zhou dba  4096 Sep 17 16:34 File
    -rwxrwxrwx 1 zhou dba 14897 Sep 17 16:29 WriteFileNonStop
    -rw------- 1 zhou dba  3434 Sep 17 16:29 WriteFileNonStop.c
    ~/zhouzhaoxiong/zzx/WriteFileNonStop> cd File
    ~/zhouzhaoxiong/zzx/WriteFileNonStop/File> ll
    total 0

    4.为了对程序进行更全面的验证,在写文件的过程中,我们将文件移动到另外一个Linux用户下(即当前用户下的程序无法访问另外一个用户),发现程序依然继续运行,但没有文件生成。

    通过以上测试验证的结果,我们得出了以下的结论:
    第一,C语言中的写文件操作是通过文件句柄来向对应的文件中写入内容的,如果程序有访问文件句柄的权限,那么不管文件放在哪个目录下,都能够成功写入。
    第二,在写文件的过程中,如果将文件删除,或者是放到了程序无权访问的目录下,那么程序也不会报错,而是继续执行。因此,对于需要写文件的软件来说,一定要确保相关目录下的文件不会被误移动或误删除。


    欢迎大家关注并支持本人新书《C程序员从校园到职场》。



沪ICP备19023445号-2号
友情链接