精华内容
下载资源
问答
  • Linux文件写入同步

    2021-04-20 17:13:45
    概述 之前在一个项目中总是会出现设备突然断电后,某些文件成为0byte或者文件数据只写入一半的情况, 经过研究后发现该问题的复现操作...完成这一步,linux的虚拟文件系统就会返回写入完成,但此时数据并未写入到磁盘

    概述

            之前在一个项目中总是会出现设备突然断电后,某些文件成为0byte或者文件数据只写入一半的情况,
    经过研究后发现该问题的复现操作为在写入文件时进行突然的断电或将程序kill,再追入其中发现这个问题      
    实质上与linux的文件系统有关,linux为了提升系统的运行速率设计了虚拟文件系统,该系统实际上并不会 
    立刻将你通过代码写入文件的数据写入磁盘,而是以一种缓冲区的方式先完成了写入数据的临时性存储, 
    完成这一步,linux的虚拟文件系统就会返回写入完成,但此时数据并未写入到磁盘,如果此时发生断电等 
    异常情况,就会出现开篇所述的问题,现将文件数据写入流程以及一些注意点记录如下:
    

    文件数据的实际写入以及对应Func如下

    fileWrite->usrCache: fwrite
    usrCache->sysCache: fflush
    sysCache->diskCache: fsync
    diskCache->disk: barrier
    
    • usrCache --> sysCache
    • 应用程序write文件完成之后,
      文件数据是暂存于USER CACHE,
      利用FFLUSH,将USER CACHE
      中的数据刷新到SYS CACHE
    • sysCache-diskCache/disk
    • 利用FSYNC将SYS CACHE中的数据
      刷新到DISK上,如果DISK存在DISK CACHE,那么FSYNC只保证数据刷新到DISK CACHE,FSYNC函数不关心DISK CACHE到DISK的过程,如果无DISK CACHE,那么FSYNC可以保证数据写到了DISK上
    • diskCache --> disk
    • 如果数据从DISK CACHE到DISK的过程中断电,那么数据存在丢失风险,解决方案有以下三种:
      • 启用备用电源,保证DISK数据完成传输。
      • 使用内核WRITE BARRIER机制(使IO操作后显式刷新DISK来保证FSYNC后,数据一定写到磁盘上)
      • FSYNC后加入延时,通过预留一定时间来达到数据写入DISK的目标

    Note

    • Fopen
    • FILE *fopen(const char *path, const char *mode);
      • mode 设置为 RB+;以读写方式打开文件,文件必须存在,否则报错。文件指针置于文件头。以覆盖的方式去写文件,保留源文件中未覆盖内容。
      • mode 设置为WB+;以读写方式打开文件,文件不存在则创建文件,存在会先清空后写数据。文件指针置于文件头。先清空后写数据的方式写文件。
    • 由RB+和WB+的文件处理逻辑可以得出:
      • RB+方式打开文件,如果出现异常中断,会导致文件损坏,但不会出现0字节现象。
      • WB+方式打开文件,如果出现异常中断,会导致文件损坏,甚至于0字节现象发生。

    • O_DIRECT
    • 直接IO操作:Linux允许应用程序在执行磁盘IO时绕过缓冲区高速缓存,从用户空间直接将数据传递到文件或磁盘设备,称为直接IO(direct IO)或者裸IO(raw IO)。
    • O_DIRECT是C语言open函数的flag参数,fopen不支持。为了保证IO同步,通常必须要和O_SYNC参数一同使用。而O_SYNC参数的作用是每写一次文件都会同步到磁盘,在文件整理过程中会循环写文件,如果开启O_SYNC会大大降低性能。
    • 同时使用直接IO需要遵守的一些限制:制:
      • 用于传递数据的缓冲区,其内存边界必须对齐为块大小的整数倍
      • 数据传输的开始点,即文件和设备的偏移量,必须是块大小的整数倍
      • 待传递数据的长度必须是块大小的整数倍。

    • SYNC
    • sync命令:sync将内存中缓冲的所有数据写出到磁盘。sync除了执行sync,syncfs,fsync和fdatasync系统调用外什么也不做。
    • sync()函数:将文件系统下的所有文件都同步,它总是返回成功,因而存在数据还未实际写入磁盘就已返回成功的可能,故此sync()函数不可靠。
    • syncfs(fd):成功返回0,失败返回-1,syncfs()类似于sync(),但是仅同步fd文件。
    • fsync(fd)函数:把文件描述符fd指向的文件缓存在内核中的所有已修改的数据写入文件系统,包含数据与文件元数据(文件大小,文件修改时间等)。但是fsync不会写入对指向文件的目录项的修改,也就是说如果新创建了一个文件,要是确保下次能正确读出的话,就需要把所在目录也fsync一下。阻塞式,直到设备数据传输完成。
    • fdatasync(fd)函数:和fsync作用差不多,但是不会写入对下次正确读取文件作用不大的一些元数据(比如上次访问时间,上次修改时间等),但是大小如果改变了,是会写进去的。阻塞式,只同步文件数据。
    展开全文
  • Linux文件写入操作

    2021-03-21 10:39:22
    上一讲写到Linux环境下文件的创建,这讲承上启下 先看代码 #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include<fcntl.h> #include<stdio.h> #include<...

    上一讲写到Linux环境下文件的创建,这讲承上启下

    1. 先看代码
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <unistd.h>
    #include<fcntl.h>
    #include<stdio.h>
    #include<string.h>
    int main()
    {
            int fd;
            char *buf="LLP IS MY WIEF!";
            fd=open("./qqq.c",O_RDWR);
            if(fd==-1)
            {
                    printf("open file failed!\n");
                    fd=open("./qqq.c",O_RDWR|O_CREAT,0600);
                    if(fd>=0)
                    {
                            printf("creat file success!\n");
                    }
    
            }
            printf("open success!,fd=%d\n",fd);
            write(fd,buf,strlen(buf));
            close(fd);
            return 0;
    }
    
    1. 这里write函数的固定格式为write(int fd,const void * buf,size_t count).
    2. 运行结果为
      表示运行成功

    然后打开qqq.c文件
    在这里插入图片描述

    如果我们在Linux环境下不知道某个函数需要什么头文件我们可以用man函数进行查询
    在这里插入图片描述

    man 2 + 函数名
    
    展开全文
  • 通常在项目开始前,会对整个文件写入性能进行一个评估,对文件写入效率有个基本了解后,再进行程序设计。 如下为文件写入效率测试的代码,供大家参考: #include #include #include #include int main_running_flag...

          在项目开发中,难免遇到需要频繁存储数据的应用场景。在存储过程中,往往需要考虑文件的IO的性能,会不会对整个程序正常运行产生影响。通常在项目开始前,会对整个文件写入性能进行一个评估,对文件写入效率有个基本了解后,再进行程序设计。

    如下为文件写入效率测试的代码,供大家参考: 

    #include <stdio.h>
    #include <string.h>
    #include <sys/time.h>
    #include <signal.h>
    
    int main_running_flag = 0;
    static void main_exit_proc(int signal)
    {
    	switch(signal)
    	{
    		case SIGINT:
    		{
    			main_running_flag = 0;
    		}break;
    		default:break;
    	}
    }
    
    static unsigned long long get_now_time()
    {
    	unsigned long long time = 0;
    	struct timeval now_time;
    	gettimeofday(&now_time, NULL);
    	time = now_time.tv_sec;
    	time *= 1000*1000; 
    	time += now_time.tv_usec;
    	return time;
    }
    
    int main(int argc, char *argv[])
    {
    	if(argc != 2 || strlen(argv[1]) < 1 )
    	{
    		printf("please input write context in argv[1]!!\n");
    		return 0;
    	}
    
    	/*接收用户中断信息号,退出程序*/
    	signal(SIGINT, main_exit_proc);
    
    	FILE *fp = NULL;
    	fp = fopen("test_write.txt","a+");
    	if(fp)
    	{	
    		char buff[1024]={0};
    		sprintf(buff,"%s\n",argv[1]);
    		int len = strlen(argv[1]);
    		unsigned long long last_write_time = get_now_time();
    		unsigned long long cur_write_time = 0;
    		unsigned long long file_size = 0;
    		unsigned long long offset_time = 0;
    		unsigned long long total_time = 0;
    		unsigned long long write_times = 0;
    		int show_size = 10;
    		main_running_flag = 1;
    		while(main_running_flag)
    		{
    			fwrite(argv[1],1,len,fp);
                            fflush(fp);
    			file_size += len;
    			cur_write_time = get_now_time();
    			offset_time = cur_write_time-last_write_time,
    			total_time += offset_time;
    			write_times++;
    			if(file_size / (1024*1024) == show_size )
    			{
    				printf("-- %d~%dM write total time:%llds%lldms%lldus, now_file_size = %lld\n",show_size-10, show_size, 
    							total_time/(1000*1000), total_time%(1000*1000)/1000, total_time%1000 ,file_size);
    				show_size += 10;
    				total_time = 0;
    				write_times = 0;
    			}
    			last_write_time = cur_write_time;
    		}
    		fclose(fp);
    	}
    	return 0;
    }
    

    测试结果(测试环境:windows10 WSL子系统 Ubuntu18.04):

    每次写入1个字符,每写入10M的数据约需要7s400多ms的时间。

    每次写入3个字符,每写入10M的数据约需要2s500多ms的时间。

    每次写入15个字符,每写入10M的数据约需要600多ms的时间。、

    修改代码,每次写入5M数据。

     

    测试结果如下: 

    写入文件大小至1340M左右时,每写入10M数据所需时间从2ms增加至约20ms。 

    写入文件大小至8230M左右时,每写入10M数据所需时间从20ms增加至约400+ms。  

    测试结论

     

    1. 写入相同大小的数据,写入的次数越多,耗时越多。

    2. 同一个文件,写入的文件大小至某个临界值时,文件写入效率会急剧减慢,并不是随文件增大逐渐减慢。

    由于不同硬件平台及系统架构的差异,如上结论仅供参考,应以程序实测为准。 

    展开全文
  • #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdio.h> #include <unistd.h> #include <string.h> int main() { ...if(fd ==

    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <string.h>
    int main()
    {
    int fd;
    char *buf=“cao kuangyuan hen shuai!”;
    fd = open("./file1",O_RDWR);
    if(fd == -1){
    printf(“open file1 failed\n”);

                fd = open("./file1",O_RDWR|O_CREAT,0600);
                if(fd>0){
                        printf("creat file1 success!\n");
                }
    
        }
        printf("open success : fd = %d\n",fd);
        //ssize_t write(int fd, const void *buf, size_t count);
        write(fd,buf,strlen(buf));
        close(fd);
    
        return 0;
    

    }
    在这里插入图片描述
    在这里插入图片描述

    展开全文
  • 程序启动了多个线程或多个进程,这些线程或进程都会写入一个文件,这时就有可能会造成文件错乱的情况,也就是多个线程或进程同时写入一个文件,造成这个文件错乱了,有些行被插入到了另一些行里去了。 这时很多同学...
  • linux 文件写入问题

    2012-03-05 19:02:12
    linux中,1g的数据,每recv一次数据就写入文件中,和在内存中建立一个buffer,每接收1兆的数据再写如到文件中,他们之间的差别大吗? linux自己有缓存,我再创建一个缓存有必要吗?菜鸟,谢谢各位了。
  • 修改Tomcat 配置文件保存提示失败。文件系统是否已满? 解决过程: 首先使用 df -h 查询当前系统磁盘的使用情况 查看是否存在使用率 已近100%? (当时,我的home 目录120G 全部使用完毕) 根据查询到内存目录...
  • REDIS从LINUX文件写入批量数据

    千次阅读 2016-07-02 20:32:44
    按照以上redis命令规则,创建一个events_to_redis.sql文件,内容是用来生成redis数据协议格式的SQL: -- events_to_redis.sql     SELECT  CONCAT(   "*4\r\n" ,   '$' , LENGTH(redis_cmd),  '\r\n' ...
  • 文件写入操作编程1.写入操作的api:编程实例 1.写入操作的api: 在Linux终端中输入man 2 write可以查询 #include <unistd.h> ssize_t write(int fd, const void *buf, size_t count); 参数介绍: write(int ...
  • linux bash 写入文件

    千次阅读 2020-06-04 15:31:34
    要将Bash命令的输出写入文件,可以使用右尖括号符号(>)或双右尖符号(>>): 右尖括号(>) 右尖括号号(>)用于将bash命令的输出写入磁盘文件。如果没有指定名称的文件,则它将创建一个具有相同名称的新...
  • 1. 日志文件写入失败,尤其是之前一直写的正确, 但最近写入失败,问题原因肯有可能是linux挂载磁盘满了使用df-h 查看 2. 删除过大文件, 进入目录 使用 du -sh *查看文件夹以及文件的大小。 3. 删除过大文件 ...
  • linux文件无法写入

    2021-05-27 18:10:48
    运行代码的时候需要写入文件的操作,运行完代码也没有报错,但是打开文件是空的,输出也没问题就是不能写入,代码也不报错。。。 可能的原因:你的文件是只读文件(read only),尝试修改文件权限就可以了。(chmod ...
  • Qt linux文件同步写入

    2017-07-17 18:12:00
    因为linux 系统机制问题,文件的创建和写入并不会直接写入硬盘。而是先写入缓存,当系统要关闭或须要时才写入硬盘。为防止突然掉电,应将缓存中的文件及时同步到硬盘上去。linux 下的sync 命令具有数据同步功能。...
  • linux批量写入文件

    千次阅读 2018-11-21 09:48:23
    cat &gt;&gt;/etc/hosts&lt;&lt;EOF this is a test just this EOF
  • Linux 环境下文件写入 img

    千次阅读 2018-11-15 15:33:06
    Linux 环境下文件写入 img
  • linux文件写入模式

    千次阅读 2016-08-26 15:18:35
    函数申明: FILE *fopen(char *filename, char *mode) 函数用途: 打开一个文件 头 文 件: stdio.h 输入参数: filename: 文件名称 mode:打开模式,含义具体如下: "r ":只读方式打开一个文本文件 "rb ":
  • linux写echo写入文件与sed写入文件

    千次阅读 2019-02-27 20:36:27
    一、echo写入文件 echo写入文件有两种模式,一种是覆盖写入,一种是追加写入 覆盖写入是在文件末尾,另起一行,将字符串写入文件 追加写入 [aizhiwenben@web01 ~]$ touch b.txt [aizhiwenben@web01 ~]$ echo "...
  • 公司系统中上传功能不合理场景:windows本地和linux远程写入文件都在本地,导致本地和远程不能访问同一资源。 一番思考,找到一种方案:不管哪种环境,都统一写到linux远程服务器。就能实现资源在不同环境下的共享...
  • linux往文本文件写入ESC字符 在终端输入 printf “\033” > file.txt \033是ESC字符的8进制 可以用man ascii查看 ESC字符就会保存在file.txt中
  • //定义写入文件 FILE *pFile; //定义文件路径变量 char json_file[1024]; //变量赋值 sprintf(local_file,"/tmp/test.json"); //打开文件 pFile = fopen(local_file,"a+"); //定义写入变量 char content...
  • linux 日志写入到指定文件

    千次阅读 2019-09-28 03:52:07
    test.log 2>&1 >...1 表示不仅命令行正常的输出保存到test.log中,产生错误信息的输出也保存到test.log文件中; 转载于:https://www.cnblogs.com/guoshuai-yangxu/p/11542822.html...
  • Linux环境下文件写入失败可能原因

    千次阅读 2019-02-10 17:50:11
    Linux环境下文件写入失败可能原因 一.空间爆满 df -h #查看空间占用情况 二.文件数量inodes超出限制 df -i 解决办法 &lt;1&gt; 使用NetApp的存储服务器则修改inodes数量 maxfiles volname [new_number_of_...
  • 库函数: #include <unistd.h> 文件的读取: ssize_t read(int fd, void *buf, size_...文件写入: ssize_t write(int fd, const void *buf, size_t count); 返回值:成功则write()会返回实际写入的字.
  • 思路是什么呢,很容易,那就是打开文件写入东西,关闭文件呗,对吧,开始编程。 简单的,定义一个字符串,指向它的指针作为write的第二个参数,strlen计算这个字符的长度 ,并且把write函数返
  • 由于linux系统存在权限问题,所以一般的文件写入语句无法起作用,需要手动设置权限: path = "/home/username/test" // 根据个人需求修改 File f = new File(path); f.setWritable( true, false); // 在Ubuntu上手动...
  • 一个java项目在windows下文件读写都没有问题,但是部署在Linux下的时候写入文件时有问题。 是要编辑一个文件,先打开了这个文件把里面的内容读出来,然后编辑,完了之后保存,如果打开编辑的时间超过了20秒,保存的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 11,696
精华内容 4,678
关键字:

linux文件写入

linux 订阅