欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

通過Java實(shí)現(xiàn)自己動(dòng)手寫ls命令

 更新時(shí)間:2022年10月10日 14:46:19   作者:一無是處的研究僧  
在前面的文章中,我們仔細(xì)的介紹了關(guān)于ls命令的使用和輸出結(jié)果,在本篇文章當(dāng)中我們用Java代碼自己實(shí)現(xiàn)ls命令,更加深入的了解ls命令

介紹

在前面的文章Linux命令系列之ls——原來最簡單的ls這么復(fù)雜當(dāng)中,我們仔細(xì)的介紹了關(guān)于ls命令的使用和輸出結(jié)果,在本篇文章當(dāng)中我們用Java代碼自己實(shí)現(xiàn)ls命令,更加深入的了解ls命令。

代碼實(shí)現(xiàn)

文件操作的基本原理

如果我們使用Java實(shí)現(xiàn)一個(gè)簡單的ls命令其實(shí)并不難,因?yàn)镴ava已經(jīng)給我們提供了一些比較方便和文件系統(tǒng)相關(guān)的api了,困難的是理解api是在做什么事兒!

事實(shí)上這些api都是操作系統(tǒng)給我們提供的,然后Java進(jìn)行了一些列的封裝,將這些操作給我們進(jìn)行提供,我們仔細(xì)來看一下封裝的層次,首先操作系統(tǒng)會(huì)給我們提供很多系統(tǒng)調(diào)用用于和設(shè)備(磁盤、CPU)進(jìn)行交互,比如說和文件的交互就是讀寫數(shù)據(jù),當(dāng)然我們的Java程序也需要這些操作,因此JVM也需要給我們提供這些操作,因此JVM就對(duì)系統(tǒng)調(diào)用進(jìn)行了一系列的封裝,在Java當(dāng)中具體的形式就是用native修飾的方法。

如果你是一個(gè)比較有經(jīng)驗(yàn)Java程序員那么一定見過Java當(dāng)中的native方法,這些方法都是Java給我們封裝的底層接口,比如說在FileInputStream當(dāng)中有一個(gè)read方法,這個(gè)方法就是讀取文件當(dāng)中的內(nèi)容,我們看一下這個(gè)方法是如何實(shí)現(xiàn)的:

????public?int?read()?throws?IOException?{
????????return?read0();
????}

這里讓大家的感受更加深入一點(diǎn),我在這里貼一張FileInputStream的源代碼圖片:

從上面的圖看當(dāng)我們調(diào)用FileInputStream方法的時(shí)候確實(shí)調(diào)用了native方法。我們?cè)賮砜匆恍┡c文件操作相關(guān)的api,他們也是使用Java給我們封裝的native方法實(shí)現(xiàn)的。

上面主要談了一些基本的文件操作過程的原理,簡要說明了Java將很多系統(tǒng)操作封裝成native方法供我們調(diào)用,現(xiàn)在我們來看看要想實(shí)現(xiàn)ls命令,我們需要哪些api。

查看一個(gè)目錄下面有哪些文件和目錄

在Java當(dāng)中給我們提供了一個(gè)類File,我們可以使用這個(gè)類去得到一個(gè)目錄下面有哪些文件和目錄。

??public?void?fileTest()?{
????File?file?=?new?File("./");
????//?file.listFiles()?將當(dāng)前?file?對(duì)應(yīng)的目錄下所有的文件和目錄都得到
????for?(File?listFile?:?file.listFiles())?{
??????System.out.println(listFile.getName());?//?將文件或者目錄的名字打印
????}

查看文件和目錄的元數(shù)據(jù)

在Java當(dāng)中給我們提供了一個(gè)工具類查看文件的一些元信息(metadata),比如說文件的uid(用戶id)、gid(用戶組id)、文件的大小和文件的鏈接數(shù)目(nlink)。

??Path?path?=?Paths.get(".");
??System.out.println(Files.getAttribute(path,?"unix:dev"));?//?打印存儲(chǔ)當(dāng)前目錄數(shù)據(jù)的設(shè)備的設(shè)備id
??System.out.println(Files.getAttribute(path,?"unix:ino"));?//?打印存儲(chǔ)當(dāng)前目錄數(shù)據(jù)inode號(hào)
??System.out.println(Files.getAttribute(path,?"unix:mode"));//?打印存儲(chǔ)當(dāng)前目錄數(shù)據(jù)的mode數(shù)據(jù)?這個(gè)數(shù)據(jù)主要用于表示文件的類型
??System.out.println(Files.getAttribute(path,?"unix:uid"));?//?打印存儲(chǔ)當(dāng)前目錄所屬用戶的用戶id
??System.out.println(Files.getAttribute(path,?"unix:gid"));?//?打印存儲(chǔ)當(dāng)前目錄所屬組的組id
??System.out.println(Files.getAttribute(path,?"unix:size"));//?打印存儲(chǔ)當(dāng)前目錄數(shù)據(jù)所占的空間大小
??System.out.println(Files.getAttribute(path,?"unix:nlink"));//?打印存儲(chǔ)當(dāng)前目錄數(shù)據(jù)的鏈接數(shù)

除了上面的方式,我們還可以使用下面的方式去得到文件的元數(shù)據(jù):

??public?void?attrTest02()?throws?IOException?{
????Path?path?=?Paths.get(".");?//?傳入的參數(shù)就是文件或者目錄的路徑?這個(gè)傳入的就是當(dāng)前目錄
????PosixFileAttributes?attr?=?Files.readAttributes(path,?PosixFileAttributes.class,?NOFOLLOW_LINKS);
????System.out.println(attr.owner());?//?打印用戶名
????System.out.println(attr.group());?//?打印用戶組名
????System.out.println(attr.isRegularFile());?//?是不是一般文件
????System.out.println(attr.isSymbolicLink());?//?是不是一個(gè)符號(hào)鏈接
????System.out.println(attr.isDirectory());?//?是否是目錄
????System.out.println(attr.isOther());?//其他類型
????System.out.println(attr.permissions());?//?打印文件的權(quán)限?是否可讀?可寫?可執(zhí)行
????System.out.println(attr.lastAccessTime());?//?上一次訪問時(shí)間
????System.out.println(attr.creationTime());?//?創(chuàng)建時(shí)間
????System.out.println(attr.lastModifiedTime());?//?上一次修改時(shí)間
????System.out.println(attr.fileKey());?//?打印文件其他相關(guān)參數(shù)?主要是設(shè)備id和inode編號(hào)
????System.out.println(attr.size());?//?文件的大小
??}
root?//?這里是用戶名
root?//?這里是用戶組名
false
false
true
false
[GROUP_READ,?OTHERS_EXECUTE,?OWNER_WRITE,?OWNER_EXECUTE,?OTHERS_READ,?OWNER_READ,?GROUP_EXECUTE]
2022-10-09T18:08:47.791072133Z
2022-10-09T13:10:51Z
2022-10-09T18:08:23.746949182Z
(dev=1000012,ino=16176823)
192

文件權(quán)限

在Java當(dāng)中給我們提供了一個(gè)類表示文件的9中權(quán)限(文件的作者的讀寫執(zhí)行,作者所在組的讀寫執(zhí)行,和其他人的讀寫執(zhí)行,一共九種權(quán)限):

package?java.nio.file.attribute;

public?enum?PosixFilePermission?{

????/**
?????*?Read?permission,?owner.?作者讀權(quán)限
?????*/
????OWNER_READ,

????/**
?????*?Write?permission,?owner.?作者寫權(quán)限
?????*/
????OWNER_WRITE,

????/**
?????*?Execute/search?permission,?owner.?作者的執(zhí)行權(quán)限
?????*/
????OWNER_EXECUTE,

????/**
?????*?Read?permission,?group.?作者所在組的讀權(quán)限
?????*/
????GROUP_READ,

????/**
?????*?Write?permission,?group.作者所在組的寫權(quán)限
?????*/
????GROUP_WRITE,

????/**
?????*?Execute/search?permission,?group.
?????*/
????GROUP_EXECUTE,

????/**
?????*?Read?permission,?others.?其他人讀權(quán)限
?????*/
????OTHERS_READ,

????/**
?????*?Write?permission,?others.?其他人寫權(quán)限
?????*/
????OTHERS_WRITE,

????/**
?????*?Execute/search?permission,?others.?其他人執(zhí)行權(quán)限
?????*/
????OTHERS_EXECUTE;
}

在上面查看文件或者目錄的元數(shù)據(jù)的時(shí)候我們已經(jīng)得到的文件的所有權(quán)限信息:

System.out.println(attr.permissions());
//[GROUP_READ,?OTHERS_EXECUTE,?OWNER_WRITE,?OWNER_EXECUTE,?OTHERS_READ,?OWNER_READ,?GROUP_EXECUTE]

函數(shù)返回的是一個(gè)集合set,里面存放的就是文件的各種權(quán)限的信息,比如在我們的例子當(dāng)中我們可以看到,有組讀,其他人執(zhí)行,作者自己寫,作者執(zhí)行,其他人讀,作者讀權(quán)限,如果我們想判斷某種權(quán)限,只需要看看集合當(dāng)中是否包含即可。

完整代碼實(shí)現(xiàn)

在上面我們已經(jīng)談到了所有的關(guān)于實(shí)現(xiàn) ls 命令的細(xì)節(jié)了,接下來看一下我們的代碼實(shí)現(xiàn):

import?java.io.File;
import?java.io.IOException;
import?java.nio.file.Files;
import?java.nio.file.Path;
import?java.nio.file.Paths;
import?java.nio.file.attribute.PosixFileAttributes;
import?java.nio.file.attribute.PosixFilePermission;
import?java.util.Objects;
import?java.util.Set;

import?static?java.nio.file.LinkOption.NOFOLLOW_LINKS;

public?class?LS?{

??public?static?boolean?hasRight(Set<PosixFilePermission>?set,?PosixFilePermission
?????????????????????????????????permission)?{
????return?set.contains(permission);
??}

??public?static?void?echoCharacter(Set<PosixFilePermission>?set)?{
????//?user
????if?(hasRight(set,?PosixFilePermission.OWNER_READ))
??????System.out.print('r');
??????else
??????System.out.print('-');
????if?(hasRight(set,?PosixFilePermission.OWNER_WRITE))
??????System.out.print('w');
????else
??????System.out.print('-');
????if?(hasRight(set,?PosixFilePermission.OWNER_EXECUTE))
??????System.out.print('x');
????else
??????System.out.print('-');

????//?group
????if?(hasRight(set,?PosixFilePermission.GROUP_READ))
??????System.out.print('r');
????else
??????System.out.print('-');
????if?(hasRight(set,?PosixFilePermission.GROUP_WRITE))
??????System.out.print('w');
????else
??????System.out.print('-');
????if?(hasRight(set,?PosixFilePermission.GROUP_EXECUTE))
??????System.out.print('x');
????else
??????System.out.print('-');

????//?others
????if?(hasRight(set,?PosixFilePermission.OTHERS_READ))
??????System.out.print('r');
????else
??????System.out.print('-');
????if?(hasRight(set,?PosixFilePermission.OTHERS_WRITE))
??????System.out.print('w');
????else
??????System.out.print('-');
????if?(hasRight(set,?PosixFilePermission.OTHERS_EXECUTE))
??????System.out.print('x');
????else
??????System.out.print('-');
??}

??public?static?void?echoType(PosixFileAttributes?attributes)?{
????if?(attributes.isDirectory())
??????System.out.print('d');
????else?if?(attributes.isRegularFile())
??????System.out.print('-');
????else?if?(attributes.isSymbolicLink())
??????System.out.print('l');
????else
??????System.out.print('o');
??}

??public?static?void?echoFileInformation(String?args)?throws?IOException?{
????Path?path?=?Paths.get(args);
????PosixFileAttributes?attributes?=?Files.readAttributes(path,?PosixFileAttributes.class,?NOFOLLOW_LINKS);
????echoType(attributes);
????echoCharacter(attributes.permissions());

????System.out.printf("\t%-2d",?Files.getAttribute(path,?"unix:nlink"));
????System.out.print("\t"?+?attributes.owner().getName());
????System.out.print("\t"?+?attributes.group().getName());
????System.out.printf("\t%-5d",?attributes.size());
????System.out.printf("\t?%10s",?attributes.lastAccessTime());
????System.out.println("\t"?+?path.getFileName());
??}

??public?static?void?main(String[]?args)?throws?IOException?{

????File?file?=?new?File(args[0]);
????for?(File?listFile?:?Objects.requireNonNull(file.listFiles()))?{
??????echoFileInformation(listFile.toString());
????}
??}
}

上面的代碼很短,如果大家了解了上main所談到的api的話,就應(yīng)該很容易理解了。下面我們看看程序的輸出結(jié)果:

可以看到我們的程序的輸出結(jié)果和ls命令的輸出結(jié)果是一樣的,只是在時(shí)間的表示上有所差別而已,這一點(diǎn)沒什么關(guān)系。

以上就是通過Java實(shí)現(xiàn)自己動(dòng)手寫ls命令的詳細(xì)內(nèi)容,更多關(guān)于Java實(shí)現(xiàn)ls命令的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論