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

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

 更新時間: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)一個簡單的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)會給我們提供很多系統(tǒng)調(diào)用用于和設(shè)備(磁盤、CPU)進(jìn)行交互,比如說和文件的交互就是讀寫數(shù)據(jù),當(dāng)然我們的Java程序也需要這些操作,因此JVM也需要給我們提供這些操作,因此JVM就對系統(tǒng)調(diào)用進(jìn)行了一系列的封裝,在Java當(dāng)中具體的形式就是用native修飾的方法。

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

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

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

從上面的圖看當(dāng)我們調(diào)用FileInputStream方法的時候確實(shí)調(diào)用了native方法。我們再來看一些與文件操作相關(guān)的api,他們也是使用Java給我們封裝的native方法實(shí)現(xiàn)的。

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

查看一個目錄下面有哪些文件和目錄

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

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

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

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

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

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

??public?void?attrTest02()?throws?IOException?{
????Path?path?=?Paths.get(".");?//?傳入的參數(shù)就是文件或者目錄的路徑?這個傳入的就是當(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());?//?是不是一個符號鏈接
????System.out.println(attr.isDirectory());?//?是否是目錄
????System.out.println(attr.isOther());?//其他類型
????System.out.println(attr.permissions());?//?打印文件的權(quán)限?是否可讀?可寫?可執(zhí)行
????System.out.println(attr.lastAccessTime());?//?上一次訪問時間
????System.out.println(attr.creationTime());?//?創(chuàng)建時間
????System.out.println(attr.lastModifiedTime());?//?上一次修改時間
????System.out.println(attr.fileKey());?//?打印文件其他相關(guān)參數(shù)?主要是設(shè)備id和inode編號
????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)中給我們提供了一個類表示文件的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ù)的時候我們已經(jīng)得到的文件的所有權(quán)限信息:

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

函數(shù)返回的是一個集合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é)果是一樣的,只是在時間的表示上有所差別而已,這一點(diǎn)沒什么關(guān)系。

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

相關(guān)文章

  • SpringBoot項目導(dǎo)入aliyun oss starter依賴后啟動報錯問題

    SpringBoot項目導(dǎo)入aliyun oss starter依賴后啟動報錯問題

    這篇文章主要介紹了SpringBoot項目導(dǎo)入aliyun oss starter依賴后啟動報錯問題及解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • Java類加載基本過程詳細(xì)介紹

    Java類加載基本過程詳細(xì)介紹

    這篇文章主要介紹了Java類加載基本過程詳細(xì)介紹的相關(guān)資料,需要的朋友可以參考下
    2016-12-12
  • Java 詳解單向加密--MD5、SHA和HMAC及簡單實(shí)現(xiàn)實(shí)例

    Java 詳解單向加密--MD5、SHA和HMAC及簡單實(shí)現(xiàn)實(shí)例

    這篇文章主要介紹了Java 詳解單向加密--MD5、SHA和HMAC及簡單實(shí)現(xiàn)實(shí)例的相關(guān)資料,需要的朋友可以參考下
    2017-02-02
  • JAVA實(shí)現(xiàn)下載文件功能的兩種方法

    JAVA實(shí)現(xiàn)下載文件功能的兩種方法

    這篇文章主要介紹了JAVA實(shí)現(xiàn)下載文件功能的兩種方法,文中示例代碼非常詳細(xì),幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-07-07
  • 詳解Kotlin:forEach也能break和continue

    詳解Kotlin:forEach也能break和continue

    這篇文章主要介紹了詳解Kotlin:forEach也能break和continue的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • Java實(shí)現(xiàn)的KNN算法示例

    Java實(shí)現(xiàn)的KNN算法示例

    這篇文章主要介紹了Java實(shí)現(xiàn)的KNN算法,結(jié)合實(shí)例形式分析了KNN算法的原理及Java定義與使用KNN算法流程、訓(xùn)練數(shù)據(jù)相關(guān)操作技巧,需要的朋友可以參考下
    2018-06-06
  • java生成縮略圖的方法示例

    java生成縮略圖的方法示例

    這篇文章主要介紹了java生成縮略圖的方法,結(jié)合具體實(shí)例形式分析了java生成縮略圖過程中所涉及的各種常見的圖形處理技巧,需要的朋友可以參考下
    2017-03-03
  • MyBatis批量添加、修改和刪除

    MyBatis批量添加、修改和刪除

    本文給大家分享mybatis批量添加,修改,刪除的實(shí)例代碼,本文代碼簡單易懂,對mybatis 批量添加、修改及刪除相關(guān)知識感興趣的朋友一起學(xué)習(xí)吧
    2016-01-01
  • 聊聊DecimalFormat的用法及各符號的意義

    聊聊DecimalFormat的用法及各符號的意義

    這篇文章主要介紹了DecimalFormat的用法及各符號的意義,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Idea中g(shù)it的使用小結(jié)

    Idea中g(shù)it的使用小結(jié)

    這篇文章主要介紹了Idea中g(shù)it的使用小結(jié),本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2024-01-01

最新評論