亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java基礎之文件概述

 更新時間:2021年05月07日 10:41:30   作者:norang  
這篇文章主要介紹了Java基礎之文件概述,文中有非常詳細的代碼示例,對正在學習java基礎的小伙伴們有一定的幫助,需要的朋友可以參考下

一、基本概念和常識

下面,我們先介紹一些基本概念和常識,包括二進制思維、文件類型、文本文件的編碼、文件系統(tǒng)和文件讀寫等。

1.1 二進制思維

為了透徹理解文件,我們首先要有一個二進制思維。 所有文件, 不論是可執(zhí)行文件、圖片文件、視頻文件、Word文件、壓縮文件、txt 文件,都沒什么可神秘的,它們都是以0和1的二進制形式保存的。我們 所看到的圖片、視頻、文本,都是應用程序?qū)@些二進制的解析結果。

作為程序員,我們應該有一個編輯器,能查看文件的二進制形式, 比如UltraEdit,它支持以十六進制進行查看和編輯。比如,一個文本文 件,看到的內(nèi)容為:

在這里插入圖片描述

打開十六進制編輯,看到的內(nèi)容如圖所示。

在這里插入圖片描述

左邊的部分就是其對應的十六進制,“hello"對應的十六進制 是"68656C 6C 6F”,對應ASCII碼編號"104101108108111",“馬"對應的 十六進制是"E9A9AC”,這是"馬"的UTF-8編碼。

1.2 文件類型

雖然所有數(shù)據(jù)都是以二進制形式保存的,但為了方便處理數(shù)據(jù),高 級語言引入了數(shù)據(jù)類型的概念。文件處理也類似,所有文件都是以二進 制形式保存的,但為了便于理解和處理文件,文件也有文件類型的概 念。

文件類型通常以擴展名的形式體現(xiàn),比如,PDF文件類型的擴展名 是.pdf,圖片文件的一種常見擴展名是.jpg,壓縮文件的一種常見擴展名 是.zip。每種文件類型都有一定的格式,代表著文件含義和二進制之間的映射關系。比如一個Word文件,其中有文本、圖片、表格,文本可 能有顏色、字體、字號等,doc文件類型就定義了這些內(nèi)容和二進制表 示之間的映射關系。有的文件類型的格式是公開的,有的可能是私有 的,我們也可以定義自己私有的文件格式。

對于一種文件類型,往往有一種或多種應用程序可以解讀它,進行 查看和編輯,一個應用程序往往可以解讀一種或多種文件類型。在操作 系統(tǒng)中,一種擴展名往往關聯(lián)一個應用程序,比如.doc后綴關聯(lián)Word應 用。用戶通過雙擊試圖打開某擴展名的文件時,操作系統(tǒng)查找關聯(lián)的應 用程序,啟動該程序,傳遞該文件路徑給它,程序再打開該文件。

需要說明的是,給文件加正確的擴展名是一種慣例,但并不是強制 的,如果擴展名和文件類型不匹配,應用程序試圖打開該文件時可能會 報錯。另外,一個文件可以選擇使用多種應用程序進行解讀,在操作系 統(tǒng)中,一般通過右鍵單擊文件,選擇打開方式即可。

文件類型可以粗略分為兩類:一類是文本文件;另一類是二進制文件。文本文件的例子有普通的文本文件(.txt),程序源代碼文件 (.java)、HTML文件(.html)等;二進制文件的例子有壓縮文件 (.zip)、PDF文件(.pdf)、MP3文件(.mp3)、Excel文件(.xlsx) 等。

基本上,文本文件里的每個二進制字節(jié)都是某個可打印字符的一部分,都可以用最基本的文本編輯器進行查看和編輯,如Windows上的notepad、Linux上的vi。二進制文件中,每個字節(jié)就不一定表示字符, 可能表示顏色、字體、聲音大小等,如果用基本的文本編輯器打開,一 般都是滿屏的亂碼,需要專門的應用程序進行查看和編輯。

1.3 文本文件的編碼

對于文本文件,我們還必須注意文件的編碼方式。文本文件中包含 的基本都是可打印字符,但字符到二進制的映射(即編碼)卻有多種方 式,如GB18030、UTF-8,我們在第2章詳細介紹過各種編碼,這里就不 贅述了。

對于一個給定的文本文件,它采用的是什么編碼方式呢?一般而言,我們是不知道的。那應用程序用什么編碼方式進行解讀呢?一般使 用某種默認的編碼方式,可能是應用程序默認的,也可能是操作系統(tǒng)默 認的,當然也可能采用一些比較智能的算法自動推斷編碼方式。

對于UTF-8編碼的文件,我們需要特別說明。有一種方式,可以標 記該文件是UTF-8編碼的,那就是在文件最開頭加入三個特殊字節(jié) (0xEF 0xBB 0xBF),這三個特殊字節(jié)被稱為BOM頭,BOM是Byte Order Mark(即字節(jié)序標記) 的縮寫。比如,對前面的hello.txt文件,帶 BOM頭的UTF-8編碼的十六進制形式如圖13-2所示。

在這里插入圖片描述

圖13-1和圖13-2所示都是UTF-8編碼,看到的字符內(nèi)容也一樣,但 二進制內(nèi)容不一樣,一個帶BOM頭,一個不帶BOM頭

需要注意的是,不是所有應用程序都支持帶BOM頭的UTF-8編碼文件,比如PHP就不支持BOM,如果PHP源代碼文件帶BOM頭,PHP運行 就會出錯。碰到這種問題時,前面介紹的二進制思維就特別重要,不要只看文件的顯示,還要看文件背后的二進制。

另外,我們需要說明下文本文件的換行符。在Windows系統(tǒng)中,換 行符一般是兩個字符"\r\n",即ASCII碼的13('\r')和10('\n'),在 Linux系統(tǒng)中,換行符一般是一個字符"\n"。

1.4 文件系統(tǒng)

文件一般是放在硬盤上的,一個機器上可能有多個硬盤,但各種操作系統(tǒng)都會隱藏物理硬盤概念,提供一個邏輯上的統(tǒng)一結構。在 Windows中,可以有多個邏輯盤,如C、D、E等,每個盤可以被格式化 為一種不同的文件系統(tǒng),常見的文件系統(tǒng)有FAT32和NTFS。在Linux 中,只有一個邏輯的根目錄,用斜線/表示。Linux支持多種不同的文件 系統(tǒng),如Ext2/Ext3/Ext4等。不同的文件系統(tǒng)有不同的文件組織方式、 結構和特點,不過,一般編程時,語言和類庫為我們提供了統(tǒng)一的 API,我們并不需要關心其細節(jié)。

在邏輯上,Windows中有多個根目錄,Linux中有一個根目錄,每 個根目錄下有一棵子目錄和文件構成的樹。每個文件都有文件路徑 的概念,路徑有兩種形式:一種是絕對路徑 ,另一種是相對路徑 。

所謂絕對路徑,是從根目錄開始到當前文件的完整路徑,在 Windows中,目錄之間用反斜線分隔,如C:\code\hello.java,在Linux 中,目錄之間用斜線分隔,如/Users/laoma/Desktop/code/hello.java。在 Java中,java.io.File類定義了一個靜態(tài)變量File.separator,表示路徑分隔 符,編程時應使用該變量而避免硬編碼。

所謂相對路徑,是相對于當前目錄 而言的。在命令行終端上,通 過cd命令進入的目錄就是當前目錄;在Java中,通過 System.getProperty(“user.dir”)可以得到運行Java程序的當前目錄。相對路徑不以根目錄開頭,比如在Windows上,當前目錄為D:\laoma, 相對路徑為code\hello.java,則完整路徑為D:\laoma\code\hello.java。

每個文件除了有具體內(nèi)容,還有元數(shù)據(jù)信息 ,如文件名、創(chuàng)建時 間、修改時間、文件大小等。文件還有一個是否隱藏 的性質(zhì)。在Linux 系統(tǒng)中,如果文件名以.開頭,則為隱藏文件;在Windows系統(tǒng)中,隱藏 是文件的一個屬性,可以進行設置。

大部分文件系統(tǒng)的文件和目錄具有訪問權限 的概念,對所有者、 用戶組可以有不同的權限,具體權限包括讀、寫、執(zhí)行。

文件名有大小寫是否敏感 的概念。在Windows系統(tǒng)中,一般是大小 寫不敏感的,而Linux則一般是大小寫敏感的。也就是說,同一個目錄下,abc.txt和ABC.txt在Windows中被視為同一個文件,而在Linux中則 被視為不同的文件。

操作系統(tǒng)中有一個臨時文件 的概念。臨時文件位于一個特定目 錄,比如Windows 7中,臨時文件一般位于“C:\Users\用戶名 \AppData\Local\Temp”;Linux系統(tǒng)中,臨時文件位于/tmp。操作系統(tǒng)會有一定的策略自動清理不用的臨時文件。臨時文件一般不是用戶手工創(chuàng)建的,而是應用程序產(chǎn)生的,用于臨時目的。

1.5 文件讀寫

文件是放在硬盤上的,程序處理文件需要將文件讀入內(nèi)存,修改后,需要寫回硬盤。操作系統(tǒng)提供了對文件讀寫的基本API,不同操作 系統(tǒng)的接口和實現(xiàn)是不一樣的,不過,有一些共同的概念。Java封裝了 操作系統(tǒng)的功能,提供了統(tǒng)一的API。

一個基本常識是:硬盤的訪問延時,相比內(nèi)存,是很慢的 。操作系統(tǒng)和硬盤一般是按塊批量傳輸,而不是按字節(jié),以攤銷延時開銷,塊 大小一般至少為512字節(jié),即使應用程序只需要文件的一個字節(jié),操作 系統(tǒng)也會至少將一個塊讀進來。一般而言,應盡量減少接觸硬盤,接觸 一次,就一次多做一些事情。對于網(wǎng)絡請求和其他輸入輸出設備,原則 都是類似的。

另一個基本常識是:一般讀寫文件需要兩次數(shù)據(jù)復制 ,比如讀文件,需要先從硬盤復制到操作系統(tǒng)內(nèi)核,再從內(nèi)核復制到應用程序分配的內(nèi)存中。操作系統(tǒng)運行所在的環(huán)境和應用程序是不一樣的,操作系統(tǒng)所在的環(huán)境是內(nèi)核態(tài),應用程序是用戶態(tài),應用程序調(diào)用操作系統(tǒng)的功能,需要兩次環(huán)境的切換,先從用戶態(tài)切到內(nèi)核態(tài),再從內(nèi)核態(tài)切到用 戶態(tài)。這種用戶態(tài)/內(nèi)核態(tài)的切換是有開銷的,應盡量減少這種切換。

為了提升文件操作的效率,應用程序經(jīng)常使用一種常見的策略,即使用緩沖區(qū) 。讀文件時,即使目前只需要少量內(nèi)容,但預知還會接著讀取,就一次讀取比較多的內(nèi)容,放到讀緩沖區(qū),下次讀取時,如果緩 沖區(qū)有,就直接從緩沖區(qū)讀,減少訪問操作系統(tǒng)和硬盤。寫文件時,先 寫到寫緩沖區(qū),寫緩沖區(qū)滿了之后,再一次性調(diào)用操作系統(tǒng)寫到硬盤。 不過,需要注意的是,在寫結束的時候,要記住將緩沖區(qū)的剩余內(nèi)容同步到硬盤。操作系統(tǒng)自身也會使用緩沖區(qū),不過,應用程序更了解讀寫模式,恰當使用往往可以有更高的效率。

操作系統(tǒng)操作文件一般有打開和關閉的概念 。打開文件會在操作系統(tǒng)內(nèi)核建立一個有關該文件的內(nèi)存結構,這個結構一般通過一個整數(shù)索引來引用,這個索引一般稱為文件描述符 。這個結構是消耗內(nèi)存 的,操作系統(tǒng)能同時打開的文件一般也是有限的,在不用文件的時候, 應該記住關閉文件 。關閉文件一般會同步緩沖區(qū)內(nèi)容到硬盤,并釋放占據(jù)的內(nèi)存結構。

操作系統(tǒng)一般支持一種稱為內(nèi)存映射文件 的高效的隨機讀寫大文 件的方法,將文件直接映射到內(nèi)存,操作內(nèi)存就是操作文件。在內(nèi)存映 射文件中,只有訪問到的數(shù)據(jù)才會被實際復制到內(nèi)存,且數(shù)據(jù)只會復制 一次,被操作系統(tǒng)以及多個應用程序共享。

二、Java文件概述

在Java中處理文件有一些基本概念和類,包括流、裝飾器設計模 式、Reader/Writer、隨機讀寫文件、File、NIO、序列化和反序列化,下 面分別介紹。

2.1 流

在Java中(很多其他語言也類似),文件一般不是單獨處理的,而是視為輸入輸出(Input/Output,IO)設備的一種。Java使用基本統(tǒng)一的 概念處理所有的IO,包括鍵盤、顯示終端、網(wǎng)絡等。

這個統(tǒng)一的概念是流 ,流有輸入流 和輸出流之分。輸入流就是可以從中獲取數(shù)據(jù),輸入流的實際提供者可以是鍵盤、文件、網(wǎng)絡等;輸出流就是可以向其中寫入數(shù)據(jù),輸出流的實際目的地可以是顯示終端、 文件、網(wǎng)絡等。

Java IO的基本類大多位于包java.io中。類InputStream表示輸入流, OutputStream表示輸出流,而FileInputStream表示文件輸入流, FileOutputStream表示文件輸出流。

有了流的概念,就有了很多面向流的代碼,比如對流做加密、壓縮、計算信息摘要、計算檢驗和等,這些代碼接受的參數(shù)和返回結果都 是抽象的流,它們構成了一個協(xié)作體系,這類似于之前介紹的接口概 念、面向接口的編程,以及容器類協(xié)作體系。 一些實際上不是IO的數(shù)據(jù)源和目的地也轉換為了流,以方便參與這種協(xié)作,比如字節(jié)數(shù)組,也包裝為了流ByteArrayInputStream和ByteArrayOutputStream。

2.2 裝飾器設計模式

基本的流按字節(jié)讀寫,沒有緩沖區(qū),這不方便使用。Java解決這個 問題的方法是使用裝飾器設計模式,引入了很多裝飾類,對基本的流增 加功能,以方便使用。一般一個類只關注一個方面,實際使用時,經(jīng)常會需要多個裝飾類。

Java中有很多裝飾類,有兩個基類:過濾器輸入流FilterInputStream 和過濾器輸出流FilterOutputStream。過濾類似于自來水管道,流入的是 水,流出的也是水,功能不變,或者只是增加功能。它有很多子類,這 里列舉一些:

1)對流起緩沖裝飾的子類是BufferedInputStream和 BufferedOutputStream。

2)可以按8種基本類型和字符串對流進行讀寫的子類是 DataInputStream和DataOutput-Stream。

3)可以對流進行壓縮和解壓縮的子類有GZIPInputStream、 ZipInputStream、GZIPOutput-Stream和ZipOutputStream。

4)可以將基本類型、對象輸出為其字符串表示的子類有 PrintStream。

眾多的裝飾類使得整個類結構變得比較復雜,完成基本的操作也需 要比較多的代碼;其優(yōu)點是非常靈活,在解決某些問題時也很優(yōu)雅。

2.3 Reader/Writer

以InputStream/OutputStream為基類的流基本都是以二進制形式處理 數(shù)據(jù)的,不能夠方便地處理文本文件,沒有編碼的概念,能夠方便地按字符處理文本數(shù)據(jù)的基類是Reader和Writer,它也有很多子類:

1)讀寫文件的子類是FileReader和FileWriter。

2)起緩沖裝飾的子類是BufferedReader和BufferedWriter。

3)將字符數(shù)組包裝為Reader/Writer的子類是CharArrayReader和 CharArrayWriter。

4)將字符串包裝為Reader/Writer的子類是StringReader和 StringWriter。

5)將InputStream/OutputStream轉換為Reader/Writer的子類是 InputStreamReader和OutputStreamWriter。

6)將基本類型、對象輸出為其字符串表示的子類是PrintWriter。

2.4 隨機讀寫文件

大部分情況下,使用流或Reader/Writer讀寫文件內(nèi)容,但Java提供 了一個獨立的可以隨機讀寫文件的類RandomAccessFile,適用于大小已 知的記錄組成的文件。該類在日常應用開發(fā)中用得比較少,但在一些系 統(tǒng)程序中用得比較多。

2.5 File

上面介紹的都是操作數(shù)據(jù)本身,而關于文件路徑、文件元數(shù)據(jù)、文 件目錄、臨時文件、訪問權限管理等,Java使用File這個類來表示。

2.6 NIO

以上介紹的類基本都位于包java.io下,Java還有一個關于IO操作的 包java.nio,nio表示New IO,這個包下同樣包含大量的類。

NIO代表一種不同的看待IO的方式,它有緩沖區(qū)和通道的概念。 利 用緩沖區(qū)和通道往往可以達成和流類似的目的,不過,它們更接近操作系統(tǒng)的概念,某些操作的性能也更高。比如,復制文件到網(wǎng)絡,通道可 以利用操作系統(tǒng)和硬件提供的DMA機制(Direct Memory Access,直接 內(nèi)存存?。挥肅PU和應用程序參與,直接將數(shù)據(jù)從硬盤復制到網(wǎng)卡。

除了看待方式不同,NIO還支持一些比較底層的功能,如內(nèi)存映射 文件、文件加鎖、自定義文件系統(tǒng)、非阻塞式IO、異步IO等。

不過,這些功能要么是比較底層,普通應用程序用到得比較少,要 么主要適用于網(wǎng)絡IO操作,我們大多不會介紹,只會介紹內(nèi)存映射文 件。

2.7 序列化和反序列化

簡單來說,序列化就是將內(nèi)存中的Java對象持久保存到一個流中, 反序列化就是從流中恢復Java對象到內(nèi)存。序列化和反序列化主要有兩個用處:一是對象狀態(tài)持久化,二是網(wǎng)絡遠程調(diào)用,用于傳遞和返回對象。

Java主要通過接口Serializable和類 ObjectInputStream/ObjectOutputStream提供對序列化的支持,基本的使用 是比較簡單的,但也有一些復雜的地方。不過,Java的默認序列化有一 些缺點,比如,序列化后的形式比較大、浪費空間,序列化/反序列化 的性能也比較低,更重要的問題是,它是Java特有的技術,不能與其他 語言交互。

XML是前幾年最為流行的描述結構性數(shù)據(jù)的語言和格式,Java對象也可以序列化為XML格式。XML容易閱讀和編輯,且可以方便地與其 他語言進行交互。XML強調(diào)格式化但比較“笨重”,JSON是近幾年來逐 漸流行的輕量級的數(shù)據(jù)交換格式,在很多場合替代了XML,也非常容 易閱讀和編輯。Java對象也可以序列化為JSON格式,且與其他語言進行交互。

XML和JSON都是文本格式,人容易閱讀,但占用的空間相對大一 些,在只用于網(wǎng)絡遠程調(diào)用的情況下,有很多流行的、跨語言的、精簡 且高效的對象序列化機制,如ProtoBuf、Thrift、MessagePack等。其 中,MessagePack是二進制形式的JSON,更小更快。

文件看起來是一件非常簡單的事情,但實際卻沒有那么簡單,Java 的設計也不是太完美,包含了大量的類,這使得對于文件的理解變得困 難。為便于理解,我們將采用以下思路在接下來的章節(jié)中進行探討。

首先,我們介紹如何處理二進制文件,或者將所有文件看作二進制,介紹如何操作,對于常見操作,我們會封裝,提供一些簡單易用的方法。下一步,我們介紹如何處理文本文件,我們會考慮編碼、按行處 理等,同樣,對于常見操作,我們會封裝,提供簡單易用的方法。接下 來,我們介紹文件本身和目錄操作File類,我們也會封裝常見操作。以 上這些內(nèi)容是文件處理的基本技術,我們會在本章進行討論。

在日常編程中,我們經(jīng)常會需要處理一些具體類型的文件,如屬性 文件、CSV文件、Excel文件、HTML文件和壓縮文件,直接使用字節(jié) 流/字符流來處理一般是很不方便的,往往有一些更為高層的API,關于 這些,我們下章介紹。此外,下章還會介紹比較底層的對文件的操作 RandomAccessFile類、內(nèi)存映射文件,以及序列化。文件看上去應該很 簡單,但實際卻包含很多內(nèi)容,讓我們耐住性子,下一節(jié),先從二進制 開始。

到此這篇關于Java基礎之文件概述的文章就介紹到這了,更多相關Java文件概述內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • java代碼審計之目錄遍歷的解決

    java代碼審計之目錄遍歷的解決

    目錄穿越漏洞,也叫做目錄遍歷/路徑遍歷漏洞,本文主要介紹了java代碼審計之目錄遍歷的解決,文中通過案例介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-06-06
  • swagger配置正式環(huán)境中不可訪問的問題

    swagger配置正式環(huán)境中不可訪問的問題

    這篇文章主要介紹了swagger配置正式環(huán)境中不可訪問的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • MyBatis中使用foreach循環(huán)的坑及解決

    MyBatis中使用foreach循環(huán)的坑及解決

    這篇文章主要介紹了MyBatis中使用foreach循環(huán)的坑及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • @MapperScan注解與@Mapper注解的使用

    @MapperScan注解與@Mapper注解的使用

    這篇文章主要介紹了@MapperScan注解與@Mapper注解的使用,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • springboot aop添加日志方式

    springboot aop添加日志方式

    這篇文章主要介紹了springboot aop添加日志方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • SpringBoot使用前綴樹實現(xiàn)敏感詞過濾示例

    SpringBoot使用前綴樹實現(xiàn)敏感詞過濾示例

    最近項目用到了敏感詞過濾,本文主要就來介紹一下SpringBoot使用前綴樹實現(xiàn)敏感詞過濾示例,具有一定的參考價值,感興趣的可以了解一下
    2023-10-10
  • java設計模式學習之工廠方法模式

    java設計模式學習之工廠方法模式

    這篇文章主要介紹了java設計模式學習之工廠方法模式,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • Java代碼的三根頂梁柱:循環(huán)結構

    Java代碼的三根頂梁柱:循環(huán)結構

    這篇文章主要介紹了JAVA 循環(huán)結構的相關資料,文中講解的非常細致,示例代碼幫助大家更好的理解和學習,感興趣的朋友可以了解下
    2021-08-08
  • Java實現(xiàn)的RSA加密解密算法示例

    Java實現(xiàn)的RSA加密解密算法示例

    這篇文章主要介紹了Java實現(xiàn)的RSA加密解密算法,結合實例形式分析了java RAS加密解密算法的相關實現(xiàn)技巧,需要的朋友可以參考下
    2018-01-01
  • SpringBoot整合RabbitMQ示例詳解

    SpringBoot整合RabbitMQ示例詳解

    這篇文章主要介紹了SpringBoot整合RabbitMQ示例詳解,RabbitMQ是一個實現(xiàn)了AMQP高級消息隊列協(xié)議的消息隊列服務,用Erlang語言。是面向消息的中間件,需要的朋友可以參考下
    2023-07-07

最新評論