linux檔案管理小結之自定義more
阿新 • • 發佈:2019-01-29
1.more命令功能
more命令用於檢視內容超過一屏的文字(類似於cat)
基本功能:
1.輸入backspace :內容翻一屏
2.輸入enter : 內容翻一行
3.輸入q:退出
4.實時顯示已讀檔案比例
2.實現思路
- 從命令中獲取需要操作的檔案
- 開啟檔案:open(filename,O_RDONLY);
- 獲取檔案總行數:
lseek(fd,0,SEEK_END);//移動檔案指標至檔案末
page_sum = lseek(fd,0,SEEK_CUR);//計算與檔案頭偏移量,即可得到檔案總行數- 命令初始讀取內容(定義整屏為10行)
設定一標誌量 儲存 每次需要顯示的行數,假設n,則執行n次下操作
用read(fd,str,1); 每次讀取一個位元組,讀到’\n’停止
並且在每次讀完之後需要用lseek(fd,0,SEEK_CUR)來獲取當前已顯示行數,用於得到檔案已閱比例- 每次操作完成後接受使用者指令
see_more();
函式接受使用者輸入,根據輸入值返回要翻的頁數- close(fd);
過程收穫
- 反顯文字:
做這個時才瞭解到linux 上 printf的功能好豐富,清屏,移動游標,一應俱全;- 保證more的提示資訊總顯示在終端的最下端,並不重複顯示
剛開始準備使用,printf(“\033[s”)記錄游標位置,輸出後,再用printf(“\033[u\033[K”);游標歸位並清行;
然而在輸出提示資訊中,還需要接受使用者的輸入,會產生換行符,而換行之後,游標歸位會失效,記錄於此。
最終是用printf(“\033[1A\033[K”)將游標上移一行,並清空該行內容,用以覆蓋提示資訊- 檔案比例的實現
這個的實現細節上文已經提到,之所以再做贅述,是因為筆者在實現過程中因為此功能卡頓很久
因為需要按行讀的緣故,想要使用fgets()來讀取文字,但是開啟檔案又用的是系統函式open(),而非fopen(),於是就產生了混用的情況。
而結果是每次用lseek()讀取當前檔案指標偏移量時,得到的值都是檔案首與檔案尾的偏移量,改為fseek()後,值變為0,探究無果,不知其因,記錄於此,日後再談
程式碼
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#define PAGENUM 10 //定義一屏為10行
void do_more(int fd);
int see_more( int sum, int now);
int main( int argc, char **argv )
{
int fd;
if( argc == 1 )//引數不合法則返回
{
return 0;
}
else
{
while( argc-->1 )
{
if( (fd = open(*++argv,O_RDONLY)) != -1 )
{
do_more(fd);
close(fd);
}
else
{
printf("Error: can't open file\n");
exit(1);
}
}
}
return 0;
}
void do_more(int fd)
{
char str[3];
int page_num = 0;//儲存每次需要跳轉的行數
int rel;
int page_now = 0;//儲存當前行數(初始為0)
int page_sum;//儲存總行數
lseek(fd,0,SEEK_END);//移動檔案指標至檔案末
page_sum = lseek(fd,0,SEEK_CUR);//計算與檔案頭偏移量,即檔案總行數
lseek(fd,0,SEEK_SET);//移動檔案指標至檔案頭
while( page_now<page_sum )
{
while(read(fd,str,1))//每次讀一行
{
if(str[0] =='\n')
{
printf("\n");
break;
}
printf("%c",str[0]);
}
page_now = lseek(fd, 0, SEEK_CUR);//實時更新已讀行數
if( page_num == PAGENUM )
{
rel = see_more( page_sum, page_now);//獲取使用者輸入
printf("\033[1A\033[K");//將游標上移一行,並清空該行內容,用以覆蓋提示資訊
if( rel == 0 )
{
break;
}
else
{
page_num -= rel;
}
}
page_num++;
}
}
int see_more(int sum,int now)
{
int rel;
printf("\033[7m --更多-- enter翻行 backspace翻頁 q退出 %.2f%% \033[0m",now*100.0/sum);//反顯輸出提示資訊以及檔案已讀比例
while(rel = getchar())
{
if(rel == 'q')
{
return 0;
}
if(rel == ' ')
{
return PAGENUM;
}
if(rel == '\n')
{
return 1;
}
}
return 0;
}