linux c删除文件中指定内容行或指定行

用C语言来操作文件内容还是有点烦的(尤其是删除内容,或者是修改非等长度的内容),没有现成的API调用,只能自己手动写;

网上查了下资料基本就两个方案:

1、增加个临时文件;把源文件内容逐个字节或者逐行读取出来,然后修改或者丢弃,放到临时文件中,当把源文件中所有内容过滤后,再把临时文件全部覆盖回源文件;

2、读取到内存中修改;把整个文件读取到内存中,然后修改,再覆盖回到源文件;


第1种方案,会多一个临时文件,这样不太安全,使用C语言来做这种事,很大一方面就是考虑到安全性;

第2种方案,读取到内存中,这种方法有个缺陷是你不知道源文件大小,如果源文件很大的话,你要分配很大内存;


我们应该怀疑下,为什么 shell 命令可以很方便的删除、修改文件内容,这绝对不会有临时文件产生,也不会占用多大内存,或者可以说占用的内存不会随着文件的大小而改变?


我想了下,有个新方案,或许就是shell命令的原理;(我没有去研究shell命令的删除实现);

扫描二维码关注公众号,回复: 3377796 查看本文章


新方案是利用文件指针,如下图:


其实看下上面的图就应该知道了,就是利用文件指针,类似队列那样,一个是入队列一个是出队列;

流程:

a、首先保存两个位置,1、读取文件内容的偏移量;2、写入文件内容的偏移量;

b、用 seek + 读文件偏移量  来设置下读取内容指针偏移量,读取一行数据; 同时修改下读取偏移量;

c、对这一行数据进行判断,修改,或者删除;

d、用seek + 写入偏移量 来设置下文件位置指针,把 c 步骤中修改的内容回写到文件;同时修改下写入偏移量;

e、循环读取所有源文件内容;

f、根据写入文件偏移量(因为写入的才是有效的数据,写入偏移量就代表了文件大小),截取下文件,把无效内容干掉;

转载地址:http://blog.csdn.net/yuzhihui_no1/article/details/70188384


下面是代码实现:

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

#define BUFF_LEN 256 

/*
 * 删除文件中无效内容
 * */
int clean_invalue_info(FILE *file_fd)
{
	assert(file_fd);

	char buff[BUFF_LEN] = {0};
	int buff_len = 0;

	long offset_read = 0;
	long offset_write = 0;

	while(fgets(buff, BUFF_LEN, file_fd)) {
        buff_len = strlen(buff);

        if (strstr(buff, "yzh")) { //有效数据要考虑移动
			if (offset_read == offset_write) {
				offset_write = offset_write + buff_len;
		        offset_read = offset_read + buff_len;
				continue;
			} else {
			    /*移动数据*/
			    fseek(file_fd, offset_write, SEEK_SET);
			    fputs(buff, file_fd);
			    offset_write = offset_write + buff_len;

		        offset_read = offset_read + buff_len;
		        fseek(file_fd, offset_read, SEEK_SET);
				continue;
			}
		}
		offset_read = offset_read + buff_len;
	}
	ftruncate(fileno(file_fd),offset_write);
}

int testt(FILE *file_fd)
{
	char buff[BUFF_LEN] = {0};
	int buff_len = 0;
	long offset_read = 0;
	char *str = "11111111111";

	fseek(file_fd, 0, SEEK_SET);
	fputs(str, file_fd);
	fgets(buff, BUFF_LEN, file_fd);
	printf("1. %s\n", buff);

	buff_len = strlen(buff);
	fgets(buff, BUFF_LEN, file_fd);
	printf("2. %s\n", buff);

	fseek(file_fd, buff_len, SEEK_SET);
	fgets(buff, BUFF_LEN, file_fd);
	printf("3. %s\n", buff);

	return 0;
}


int main(int argc, char *argv[])
{
	FILE *file_fd = fopen("./tt", "r+");
	clean_invalue_info(file_fd);
//    testt(file_fd);
	fclose(file_fd);

	return 0;
}

上面代码已经调试通过,为方便理解,没有优化过;

转载地址:http://blog.csdn.net/yuzhihui_no1/article/details/70188384


猜你喜欢

转载自blog.csdn.net/YuZhiHui_No1/article/details/70188384