アイデア:
1. プロセスでは、open() はファイルを開きます。これは、各行の終わりが '\n' であるためです。これにより、ファイル ポインターをファイルの 11 行目に配置し、後続のデータ read() を配列、次にファイル内のポインターを 10 行目に再配置し、データを格納したばかりの配列を書き込み、ファイルの現在のポインターを読み取り、最後に ftruncate() を使用してファイルを切り捨てます。
2. プロセス内で、open() はファイルを 2 回開きます。1 回は読み取り専用で、もう 1 回は読み取り/書き込みです。読み取り専用ファイル ポインターはファイルの 11 行目にあり、読み取り/書き込みファイル ポインターは次の場所にあります。ファイルの 10 行目. データは次に read() コピー write() を読み取り/書き込みファイル ポインターの後ろに書き込み、最後に fruncate() が読み取り/書き込みファイル ポインターの後ろの内容を切り捨てます。
コード
私は2番目の方法を使用します.アイデアは理解しやすいです:
#include <sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc,char **argv)
{
int fd1,fd2;
int rpos = 0, wpos = 0,pos = 0;//读取位置,写入位置,当前位置
char str[2]; //临时数组
int row = 0; //行数判断
int trun_num =0 ; //需要截断的位置
//如果传入参数不够,给出提示
if(argc < 2) {
printf("Usage...\n");
exit(1);
}
//只读方式打开
fd1 = open(argv[1],O_RDONLY);
if(-1 == fd1){
perror("open()");
exit(1);
}
//以读写方式打开
fd2 = open(argv[1],O_RDWR);
if(-1 == fd2){
perror("open()");
exit(1);
}
//找到读取位置
while(1){
if(row == 10) {
rpos = pos;
break;
}
if(read(fd1,str,1) <= 0) break;
//printf("%s\n",str);
if(str[0] == '\n') row = row+1;//判断是否到了一行的截止
pos = pos + 1;
}
pos = 0;
row = 0;
//找到写入位置
while(1){
if(row == 9) {
wpos = pos;
break;
}
if(read(fd2,str,1) <= 0) break;
if(str[0] == '\n') row = row+1;//判断是否到了一行的截止
pos = pos + 1;
}
//读取数据写入文件
while(1){
if(read(fd1,str,1)<= 0) break;
write(fd2,str,1);
}
//从写入位置开始截断
trun_num = lseek(fd2,0,SEEK_CUR);
ftruncate(fd2,trun_num);
close(fd1);//关闭文件
close(fd2);
exit(0);
}
要約する
上記のコードでファイルの 10 行目を削除することはできますが、少し面倒なので、最初に書き込み位置を見つけてから、読み取り位置を見つける方が簡単です。