天天看點

Linux之連結Linux之連結

Linux之連結

一、連結以及基礎知識

本章導讀中給大家稍微提了一下的是硬連結,在介紹前面 stat 函數提到過符号連結,不過這硬連結,符号連結和連結完全不是一回事。

在 linux 中,檔案目錄包含檔案名清單,每一個檔案名對應一個 inode 編号。每個檔案名叫目錄項,每個名字到 inode 的映射叫連結。

類似 windows 下的快捷方式叫做符号連結(軟連接配接)和硬連結。雖然有點繞口,但是在 linux 程式設計的書籍在最開始就是這麼翻譯過來的,能夠了解就行了。

前面強調過在 linux 系統中每一個 inode 都是唯一的,但是發現,如下圖所示,在最小系統下使用指令“ls -i”,會發現兩個相同的 inode。

Linux之連結Linux之連結

其實這就是硬連結,硬連結的個數可以是多個。

和硬連結對應的是軟連結,也可以叫符号連結或者symlinks,軟連接配接不是檔案系統的檔案名和 inode 的映射,而是一種指針,在運作的時候解釋。

在 linux 指令中,有 ln 指令可以建立連結,如下圖所示,使用“man ln”檢視一下。

Linux之連結Linux之連結

如上圖所示,可以看到關于ln的功能描述。它是用來建立一個TARGET到真實的檔案的link(連結)。這也算是 linux 中一種特殊的檔案,就像 windows 下的快捷方式,也屬于 window下的檔案。

二、硬連結 link

1、使用 man 學習 link 函數

如下圖所示,使用指令“man 2 link”。

Linux之連結Linux之連結

最後介紹一下 link 函數。

int link(const char *oldpath, const char *newpath);
//參數*oldpath:已有的檔案路徑。
//參數*newpath:建立的硬連結檔案路徑。
//傳回值:成功傳回 0,錯誤傳回-1。
           

2、函數例程

編寫簡單的 link.c 檔案測試 link 函數。

#include <stdio.h>
//link函數頭檔案
#include <unistd.h>

int main(int argc,char *argv[])
{
	int ret;
	
	if(argc <3){
		printf("\nPlease input file path\n");
		return 1;
	}

//測試link函數
	ret = link(argv[1],argv[2]);
	if(ret)
	{
		printf("link failed");
		return 1;
	}
	printf("link %s to %s success!\n",argv[1],argv[2]);
	
	return 0;
}
           

3、運作結果

如下圖所示,使用 vi 編輯器建立一個 linktest.c 檔案。檔案中内容為“hello linux link!”

Linux之連結Linux之連結

接着運作程式,如下圖所示。

Linux之連結Linux之連結

然後使用 ls -i指令檢視,如下圖所示。

Linux之連結Linux之連結

如上圖所示,可以看到硬連結建立的完全一樣的檔案,inode 是相同的。

使用 vi 指令打開 linktest,檢視其中的内容。如下圖所示,一模一樣。

Linux之連結Linux之連結

三、符号連結 symlink

1、使用 man 學習 symlink 函數

如下圖所示,使用指令“man 2 symlink”。函數 symlink 和 link 函數用法差不多。

接着介紹一下 symlink 的用法。

Linux之連結Linux之連結
int symlink(const char *oldpath, const char *newpath);
//參數*oldpath:已有的檔案路徑。
//參數*newpath:建立的符号連結檔案路徑。
//傳回值:成功傳回 0,錯誤傳回-1。
           

2、函數例程

編寫簡單的 symlink.c 檔案測試 symlink 函數。

#include <stdio.h>
//symlink函數頭檔案
#include <unistd.h>

int main(int argc,char *argv[])
{
	int ret;
	
	if(argc <3){
		printf("\nPlease input file path\n");
		return 1;
	}

//測試symlink函數
	ret = symlink(argv[1],argv[2]);
	if(ret)
	{
		printf("symlink failed");
		return 1;
	}
	printf("symlink %s to %s success!\n",argv[1],argv[2]);
	
	return 0;
}
           

3、運作結果

使用程式給前一個實驗中 linktest.c 檔案建立軟連接配接,如下圖所示。運作程式如下。

Linux之連結Linux之連結

如下圖所示,使用 ls 指令檢視建立的軟連接配接檔案,可以發現和之前的并不是同一個檔案,inode 不一樣,說明是不同的檔案。

Linux之連結Linux之連結

使用指令vi symlink.c打開之後也是顯示同樣的内容,如下圖所示。

Linux之連結Linux之連結

四、解除連結 unlink

1、 使用 man 學習 unlink 函數

如下圖所示,使用指令“ man 2 unlink”。

Linux之連結Linux之連結

接着介紹一下 unlinke 的用法。

int unlink(const char *pathname);參數:
//參數*pathname:連結檔案的路徑。
//傳回值:成功傳回 0,錯誤傳回-1。
//當 unlink 指向的是軟連結,則會删除軟連結,不會删除目标檔案。
//當 unlink 指向的是硬連結,如果,如果是最後一個連結,則就相當于删除了檔案。
           

另外還有一個 remove 函數,可以直接用來删除 path。

如果 path 是目錄則 remove 調用 rmdir。

如果 path 是檔案則 remove 調用 unlink。

2、函數例程

編寫簡單的 unlink.c 檔案測試 unlink 函數。

#include <stdio.h>
//unlink函數頭檔案
#include <unistd.h>

int main(int argc,char *argv[])
{
	int ret;
	
	if(argc <2){
		printf("\nPlease input file path\n");
		return 1;
	}

//測試unlink函數
	ret = unlink(argv[1]);
	if(ret)
	{
		printf("unlink failed");
		return 1;
	}
	printf("unlink %s is success!\n",argv[1]);
	
	return 0;
}
           

3、運作結果

運作程式如下所示,這裡取消了前一個實驗建立的軟連接配接檔案。

Linux之連結Linux之連結

五、拷貝檔案

檔案進行中拷貝和移動檔案是最基本的操作。可以通過 cp 指令和 mv 指令實作。mv 可以了解為“重命名”;

cp 拷貝要注意和建立硬連結區分開來,硬連結的 inode 是相同,它們是同一個檔案,但是 cp 拷貝之後,inode 索引節點是不同的,它們是不同的檔案。

1、拷貝簡介

Linux 下并沒有專門的拷貝函數和接口,需要通過 open,read,wite 等檔案操作函數實作。

如下圖所示,是 linux 下拷貝的流程圖。

一般步驟是 open 之後将資料讀至記憶體,然後寫入新的檔案。

Linux之連結Linux之連結

2、拷貝例程

編寫簡單的 cpfile.c 檔案完成拷貝功能。

#include <stdio.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

//argv[1] is oldpath ; argv[2] is newpath
#define LENTH 1024
int main(int argc,char *argv[])
{
	int fds,fdt;
	char buffer[LENTH];
	char *fileold,*filenew;
	
	fileold = argv[1];
	filenew = argv[2];
	
	if(argc <3){
		printf("\nPlease input file path\n");
		return 1;
	}

	//打開oldpath		
	fds = open(fileold,O_RDWR);
	if(fds<0)
	{
		printf("Please make sure file path\n");
		return 1;
	}
	
	//打開newpath,如果沒有則建立目标檔案
	fdt = open(filenew,O_WRONLY|O_CREAT);
	if(fdt<0)
	{
		printf("Please make sure file path\n");
		return 1;
	}

	//讀和寫操作
	while(read(fds,buffer,LENTH)){
		write(fdt,buffer,strlen(buffer));
	}
	
	//關閉檔案
	close(fds);
	close(fdt);
	
	printf("cp to finished!\n");
	printf("cp %s to %s success!\n",fileold,filenew);
	return 0;
}
           

3、運作結果

運作程式如下圖所示,用到了前面實驗建立的 linktest.c 檔案。

Linux之連結Linux之連結

接着檢視一下 cptest 檔案,和原來的 linktest.c 不是同一個檔案。

Linux之連結Linux之連結

打開複制生成的 cptest 檔案,内容沒變,如下圖所示。

Linux之連結Linux之連結

六、移動檔案

1、使用 man 學習 rename 函數

Linux 下移動檔案可以使用 rename 實作。如下圖所示,使用指令“man 2 rename”,檢視 rename 文檔。

最後介紹一下 rename 函數。

Linux之連結Linux之連結
int rename(const char *oldpath, const char *newpath);
//參數*oldpath:舊的檔案路徑。
//參數*newpath:新的檔案路徑。
//傳回值:成功傳回 0,錯誤傳回-1。
           

2、函數例程

#include <stdio.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

//argv[1] is oldpath ; argv[2] is newpath
int main(int argc,char *argv[])
{
	int ret;
	if(argc < 3){
		printf("\nPlease input file path\n");
		return 1;
	}
	if(ret = rename(argv[1],argv[2])){
		printf("\nerr\n");
	}
		
	printf("rename %s to %s success!\n",argv[1],argv[2]);
	return 0;
}
           

3、運作結果

運作程式如下。

Linux之連結Linux之連結

接着使用 ls 指令檢視,有新的 renametest 檔案,原來的檔案 cptes 消失了。

Linux之連結Linux之連結

繼續閱讀