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

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

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-07 01:56:53

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

将Java程序打包成可执行EXE文件的步骤

需要的工具myeclipse .jar2exe(附上下载地址,直接解压就可以用链接: https://pan.baidu.com/s/1qYPRgXu 密码: wbva) 1.将Java项目导出成.jar包 鼠标右键项目名,选择导出 导出的方式选择Runnable JAR file,点击next继续 选择导出文件的路径: jar文件成功导出到桌面 2.用工具将jar文件打包成EXE可执行文件 选择刚才导出的jar文件 选择要导出程序的类型: 选择主类,图片可不选 导出程序的具体设置: 选择辅助j

io流之写文件

用Java程序写文件有多种方式,对于不同类型的数据,有不同的写方法.写文件的关键技术点如下: 1.FileOutputStream打开文件输出流,通过write方法以字节为单位写文件,是写文件最通用的方法,能写任何类型的文件,特别适合写二进制数据文件. 2.OutputStreamWriter打开文件输出流,通过write方法以字符为单位写文件,能够将字符数组和字符串写入文件. 3.PrintWriter打开文件输出流,通过print和println方法将字符串写入文件,与System.out的

这程序还厉害的。。。

 <html> <body> <script type="text/javascript"> var d=new Date(); document.write("从 1991/02/02 至今已过去 " + d.getTime() + " 毫秒"); </script> </body> </html> 从 1991/02/02 至今已过去 1402917686044 毫秒

apk安装时把程序附带文件拷贝到手机指定目录下

项目已搞定,今天把.apk文件弄到另外一台非调试手机上用,发现一个问题.因为要画图,所以绘图的点的数据保存在一个.txt的文本文件中,上次直接把它用usb传到指定文件夹下的,但是明显不科学,因为用户下载了你的.apk文件,你却告诉他,还要把这个文本文件拷贝到指定的文件夹下,所以,我就要解决这个问题,就是把文本文件打包在apk文件中,安装.apk时就让创建一个程序文件夹,然后把文本文件拷贝到这个目录文件夹里,用户运行程序,就可以绘图,不用再让他拷贝一份绘图的点的坐标的数据.同理,其实我这里还有设计

java基础知识回顾之javaIO类--File类应用:获取指定目录下面的指定扩展名的文件,将文件的绝对路径写入到目的文件当中

/** * File文件综合应用 * 需求:获取指定目录下面,指定扩展名的文件,将文件的绝对路径写到文本文件当中. *  * 思路:1.需要深度遍历.--递归 * 2.遍历的过程中过滤指定扩展名的文件--过滤器FileNameFilter,将文件存入容器中 * 3.将容器中的内容遍历,写入到指定文件中 * */ 代码:  FilenameFilter 过滤器: package com.lp.ecjtu.File.filter; import java.io.File; import java.i

该文件没有程序与之关联来运行该操作。请在控制面板的目录选项中创建关联 解决代码

打开控制面板-目录选项,或者打开随意一个目录,在菜单条--工具--目录选项 1.切换到文件类型选项卡,在以注冊的文件类型中找到要打开的文件类型 2.选中后点击以下的"高级"按扭 3.在弹出的对话框中的操作一栏里选择一个操作(相应该类文件右键菜单上的命令),然后点编辑 4.在弹出的对话框中点击"浏览"按扭,找到要打开该文件的程序 假设在第1步中找不到WMV,能够点击"新建"按扭 5.在弹出的对话框中输入要打开的文件类型,确定,到第1步 假设在第3步

编写一个程序,将 d: \ java 目录下的所有.java 文件复制到d: \ jad 目录下,并 将原来文件的扩展名从.java 改为.jad

1.编写一个程序,将 d: \ java 目录下的所有.java 文件复制到d: \ jad 目录下,并 将原来文件的扩展名从.java 改为.jad package copy; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; i

国家食品药品监督管理总局11号文件发布的已使用化妆品原料名称目录

已使用化妆品原料名称目录 序号 中文名称 INCI名称/英文名称 00001 1-(3,4-二甲氧基苯基)-4,4-二甲基-1,3-戊二酮 1-(3,4-DIMETHOXYPHENYL)-4,4-DIMETHYL-1,3-PENTANEDIONE 00002 1,10-癸二醇 1,10-DECANEDIOL 00003 1,2-丁二醇 1,2-BUTANEDIOL 00004 1,2-己二醇 1,2-HEXANEDIOL 00005 1,2-戊二醇 PENTYLENE GLYCOL 00006

rsync保持原目录嵌套关系同步文件

rsync -R是保持原目录嵌套关系的参数.比如有个绝对路径/root/test/3/4/5/6/7,现在想把其中3目录下的4目录以及里面包含的所有内容,保持着原目录嵌套关系拷贝到/tmp/oldfile/,就先cd到3目录,再执行rsync -avuzRP 4 /tmp/oldfile/ 这主要应用于,很多目录下包含太多不需要的目录,且目录套目录有太多目录,最终是一个文件,你所需要的不只是那个文件,而是要完整的目录嵌套关系的情况. 原文地址:https://blog.51cto.com/zhu