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

最近,在现场调试程序的同事反馈回了一个问题:目的文件已不在原目录,程序还会继续执行写文件操作。我们了解了一下,具体的情况是这样的:某软件(运行在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程序员从校园到职场》。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

知识的港湾

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值