文件操作和IO流

??前言👀~

上一章我們介紹了多線程進階的相關內容,今天來介紹使用java代碼對文件的一些操作

文件(file)

文件路徑(Path)

文件類型

文件操作

文件系統操作(File類)

文件內容的讀寫( 流對象)

字符流(文本文件)

Reader類

Writer類

字節流(二進制文件)

InputStream類

outputStream類

字節流轉為字符流

緩沖區(buffer)


如果各位對文章的內容感興趣的話,請點點小贊,關注一手不迷路,講解的內容我會搭配我的理解用我自己的話去解釋如果有什么問題的話,歡迎各位評論糾正 🤞🤞🤞

12b46cd836b7495695ce3560ea45749c.jpeg

個人主頁:N_0050-CSDN博客

相關專欄:java SE_N_0050的博客-CSDN博客??java數據結構_N_0050的博客-CSDN博客??java EE_N_0050的博客-CSDN博客


文件(file)

操作系統會將很多的硬件設備以及軟件資源抽象成"文件"統一進行管理,但是大部分情況"文件"指的是硬盤上的文件,也就是對硬盤的一種抽象。硬盤有機械硬盤(HDD)和固態硬盤(SSD),固態硬盤的效率比機械硬盤高,里面都是集成程度很高的芯片(類似cpu,內存),我們的電腦一般自帶的都是固態硬盤,想放更多資料可以加個機械硬盤


文件路徑(Path)

編程的時候我們通過文件的方式操作硬盤,如上面所說把硬盤抽象出來進行操作。計算機中有很多文件,我們通過"文件系統"(操作系統提供的模塊)進行組織和管理,操作系統中使用目錄(文件)這樣的結構來組件文件,采用樹形結構,想想也好理解樹有根結點理解為硬盤,點進去就是目錄/文件,也就是根節點的子結點以此類推。用目錄的層次結構來描述文件所在的位置稱為"路徑",C:\Windows\System32,類似這樣的字符串,可以看出當前文件在哪個目錄下

1.絕對路徑:就是上面這個以你的盤開頭的C:\Windows\System32

2.相對路徑:前提是指定了一個目錄,作為基準目錄,從基準目錄出發沿著路線找你指定的文件,以 .(當前目錄)或者 ..(當前目錄的上一級目錄)開頭,.后面跟的路徑代表咋們是在同一個文件下的,..后面跟的路徑,..代表是后面路徑的爹

文件類型

文件,根據其保存數據的不同,也經常被分為不同的類型,在編程角度,我們一般劃分為文本文件和二進制文件,不管屬于哪個在計算機中這些數據都是以二進制進行存儲的

1.文本類型:文件中保存的數據,都是字符串,保存的內容都屬于合法的字符

2.二進制類型文件中保存的數據,都是二進制,保存的內容不一定是合法的字符

首先說什么是字符,字符就是字母、數字、符號等書面語言,不合法的字符指的是在某種字符編碼下無法正確顯示的字符(通常會顯示為亂碼)字符集則是字符的集合,它會給每一個字符分配一個唯一的編號,例如ASCALL碼和Unicode就是字符集,Unicode字符集包含幾乎所有已知的文字和符號,字符編碼就是將字符轉換為計算機能處理的數據,字符編碼方式有UTF-8、UTF-16等。所以如果你的文件是通過utf8進行編碼的話,此時保存的數據都是utf8編碼中合法的字符,那就是文本文件,如果出現不是utf8編碼的字符,那就是二進制了

其實判斷文件什么類型很簡單,打開是亂碼就算二進制類型,否則就是文本類型。可以使用記事本去測試,把文件往里丟,看里面的字符你認識不,認識的話一般就是文本類型了,不是的話就是二進制類型。文本文件和二進制文件的代碼編寫方式不同,要注意區分。下面演示一下亂碼


文件操作

分為兩類,文件系統的操作,例如創建文件、刪除文件、重命名等,也就是你右擊文件能干的事,在java中我們可以使用File類也能完成這些操作文件內容的操作,流對象。這里的操作例如讀文件、寫文件。可以使用例如InputStream和OutPutStream后面進行詳細講解


文件系統操作(File類)


屬性:

pathSeparator,表示路徑的分隔符就是這個" \ ",windows這個" \ "和" / "都行,Mac和Linux上只能使用 / "作為分隔符。這個屬性可以根據當前系統自動變化,又體現了跨平臺性

構造方法:

一個File對象,就對應硬盤上的文件,構造對象的時候把文件路徑(絕對路徑或者相對路徑)以及文件擴展名,就是你要操作哪個文件,你把路徑丟到file的構造方法即可

方法:

下面是file的方法,后面會進行演示

前五個路徑方法演示:

public class Test {public static void main(String[] args) throws IOException {File file = new File("E:/test.txt");System.out.println(file.getParent());//獲取父目錄路徑System.out.println(file.getName());//獲取文件名System.out.println(file.getPath());//獲取文件路徑System.out.println(file.getAbsolutePath());//獲取絕對路徑System.out.println(file.getCanonicalFile());//獲取修飾過的絕對路徑}
}

輸出結果

可以發現即使這個文件我沒有也沒事

getCanonicalFile方法和get Absolute Path方法的區別可以看如下代碼

public class Test {public static void main(String[] args) throws IOException {File file = new File("./test.txt");System.out.println(file.getParent());//獲取父目錄路徑System.out.println(file.getName());//獲取文件名System.out.println(file.getPath());//獲取文件路徑System.out.println(file.getAbsolutePath());//獲取絕對路徑System.out.println(file.getCanonicalFile());//獲取修飾過的絕對路徑}
}

輸出結果,我把文件路徑改成相對路徑的時候就有區別了

三個判斷文件類型以及文件是否存在方法演示:

public class Test {public static void main(String[] args) throws IOException {File file = new File("E:/IO");System.out.println(file.exists());//判斷文件是否存在System.out.println(file.isDirectory());//判斷文件類型 是否是一個目錄System.out.println(file.isFile());//判斷文件類型 是不是普通文件}
}

輸出結果

createNewFile()創建文件的方法演示

public class Test {public static void main(String[] args) throws IOException {File file = new File("E:/IO/text.txt");System.out.println(file.createNewFile());}
}

輸出結果

?delete()和deleteOnExit()方法刪除文件的方法有兩個并且有區別下面進行演示

public class Test {public static void main(String[] args) throws IOException {File file = new File("E:/IO/text.txt");System.out.println(file.delete());}
}

輸出結果

public class Test {public static void main(String[] args) throws IOException, InterruptedException {File file = new File("E:/IO/text.txt");Thread.sleep(3000);file.deleteOnExit();//等JVM運行結束了再去刪除文件}
}

輸出結果


listFiles()方法獲取當前目錄下所有文件

public class Test {public static void main(String[] args) throws IOException, InterruptedException {File file = new File("E:/");File[] f = file.listFiles();//獲取當前目錄下所有文件for (File wow : f) {System.out.print(wow + " ");}}
}

輸出結果

mkdir()方法在當前目錄下創建文件

public class Test {public static void main(String[] args) throws IOException, InterruptedException {File file = new File("E:/IO/text");System.out.println(file.mkdir());//當前目錄下接著創建目錄(文件)}
}

輸出結果

mkdirs()方法和mkdir()方法的區別,在當前目錄下創建文件并且還可以接著創建

public class Test {public static void main(String[] args) throws IOException, InterruptedException {File file = new File("E:/IO/text/text2/text3");System.out.println(file.mkdirs());}
}

輸出結果


文件內容的讀寫( 流對象)

標準庫中,提供讀寫文件的流對象有很多,但是歸納為兩個大類,其他流都繼承這個兩個大類

什么叫輸入?什么叫輸出?輸入=>讀,輸出=>寫

要站在cpu的角度考慮,一個數據保存到硬盤,對于cpu即是輸出,一個數據從硬盤讀到cpu,對于cpu即是輸入

字符流(文本文件)

本質針對字節流進一步封裝字符流能幫我們把文件中 幾個相鄰的字節 轉換成 一個字符。相當于完成了一個自動查字符集表,每次讀/寫最小單位為"字符"(1個字符對應多個字節),1個字符范圍是0-65535至于1個字符對應幾個字節,看字符集是哪種,例如GBK一個中文字符對應兩個字節,UTF8一個中文字符對應三個字節,提供了兩個父類,Reader和Writer,接下來演示使用

Reader類

創建Reader對象的過程,就相當于打開文件的過程

read方法有三個參數的版本和無參的版本,并且返回值為int類型

為什么read方法返回類型為int?

0-65535這個范圍是一個無符號char能表示的范圍,一個字符對應兩個字節。在java中如果是使用char類型的時候,使用Unicode進行編碼的。使用String類型的時候則自動的把每個字符從Unicode編碼轉為UTF8編碼。例如一個char[ ] c數組包含的每個字符固定使用Unicode進行編碼。但是使用字符數組構造成String,例如String[ ] s=new String(c),此時自動的把每個字符轉成UTF8編碼,使用s.charAt(c),又會把UTF8編碼的數據轉換成Unicode。一個漢字,Unicode表示2個字節,UTF8表示3個字節。多個Unicode放到一起,難以區分哪到哪是一個完整的字符,UTF8可以做到就是針對連續多個字符傳輸的時候一種改進

總結按字節處理的時候采用Unicode編碼,按字符串處理的時候采用UTF8編碼

read()方法無參數,一次讀取一個字符

public class Test {public static void main(String[] args) throws IOException, InterruptedException {try (Reader reader = new FileReader("E:/IO/text.txt")) {int read = reader.read();if (read == -1) {return;}char c = (char) read;System.out.print(c);}}
}

輸出結果


read方法有參數一個字符數組,這個數組是空的字符數組,你把這個數組交給read方法,它把讀到的填入這個數組里去,然后交給你。這個能一次讀取多個字符

public class Test {public static void main(String[] args) throws IOException, InterruptedException {try (Reader reader = new FileReader("E:/IO/text.txt")) {char[] ch = new char[11];int read = reader.read(ch);System.out.println("讀到的個數:" + read);while (true) {for (char c : ch) {System.out.print(c);}break;}}}
}

輸出結果,有個注意點我這邊使用了try-Source關閉字符流防止文件資源泄露!!!

Writer類

和上面的差不多一個是讀文件,一個則是寫文件,有些注意的地方下面講解

writer方法,把你要寫的內容寫入文件中,注意一下會把原先的內容覆蓋掉,要是不想的話需要在構造方法中手動設置true這樣就不會了

public class Test {public static void main(String[] args) {try (Writer writer = new FileWriter("E:/IO/text.txt")) {writer.write("我是字符流的Writer");} catch (IOException e) {throw new RuntimeException(e);}}
}

基本流程:

1.先打開文件(構造方法)

2.讀文件(Read)/寫文件(Writer)

3.關閉文件(close)!!!


字節流(二進制文件)

每次讀/寫最小單位為"字節"(8bit)最少1字節,提供了兩個父類,InputStream和OuputStream

InputStream類

和字符流的Reader差不多,只是這里是字節表示,1個字節范圍是0-255,一般字節我們習慣使用16進制表示1個字節表示8個比特位,也就是兩個16進制數字,bit就是位,也叫比特位,是計算機表示數據最小的單位。1個字節8bit,1byte=8bit。1byte就是1B,位就是bit也是b,1B=8b

public class Test {public static void main(String[] args) {try (InputStream inputStream = new FileInputStream("E:/IO/text.txt")) {byte[] s = new byte[6];int read = inputStream.read(s);System.out.println("讀取到的個數:" + read);for (int i = 0; i < s.length; i++) {System.out.printf("%x\n", s[i]);}} catch (IOException e) {throw new RuntimeException(e);}}
}

輸出結果,使用16進制輸出

去確認一下對不對

outputStream類

和字符流的Writer差不多,構造方法不設置true會覆蓋掉原來的內容

下面是代碼演示,注意一下我們這里將字符串轉為字節寫入,因為我們使用的是字節流

public class Test {public static void main(String[] args) {try (OutputStream outputStream = new FileOutputStream("E:/IO/text.txt")) {String s = "java之父";outputStream.write(s.getBytes());} catch (IOException e) {throw new RuntimeException(e);}}
}

輸出結果

字節流轉為字符流

有下面這幾種方法:

1.使用scanner搭配InputStream可以從文件中讀取數據了

public class Test {public static void main(String[] args) {try (InputStream inputStream = new FileInputStream("E:/IO/text.txt");) {Scanner scanner = new Scanner(inputStream);String s = scanner.next();System.out.println(s);} catch (IOException e) {throw new RuntimeException(e);}}
}

輸出結果

2.使用PrintWriter類把字節流轉字符流,把內容寫入指定路徑文件中

public class Test {public static void main(String[] args) {try (OutputStream outputStream = new FileOutputStream("E:/IO/text.txt")) {PrintWriter printWriter = new PrintWriter(outputStream);printWriter.printf("高斯林");} catch (IOException e) {throw new RuntimeException(e);}}
}

輸出結果,會發現寫入高斯林,沒有內容顯示

緩沖區(buffer)

"緩沖區"是內存空間的一部分,PrintWriter這樣的類,進行寫數據的時候,不一定直接寫入硬盤,而是先把數據寫到一個內存構成的"緩沖區",引入緩沖區也是為了提高效率,因為我們知道把數據寫到內存中比寫到硬盤中速度要快很多,所以我們先把數據寫到內存中,等內存中存的差不多了再寫到硬盤中,這樣能提供效率的同時減少讀寫硬盤的次數

但是要注意如果還沒來得及把緩沖區的數據寫入到硬盤中,此時進程結束了,數據就會丟失,所以為了確保數據能寫入硬盤中,在合適的時機使用flush方法,手動刷新緩沖區,這樣就可以確保數據寫入到硬盤中。在剛才的代碼加入flush方法,這樣就能確保數據從緩沖區寫到硬盤中了

public class Test {public static void main(String[] args) {try (OutputStream outputStream = new FileOutputStream("E:/IO/text.txt")) {PrintWriter printWriter = new PrintWriter(outputStream);printWriter.printf("高斯林");printWriter.flush();} catch (IOException e) {throw new RuntimeException(e);}}
}

以上便是關于如何使用java代碼去操作文件的內容,多用用就能掌握,我們下一章再見💕

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/44095.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/44095.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/44095.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

leetcode--恢復二叉搜索樹

leetcode地址&#xff1a;恢復二叉搜索樹 給你二叉搜索樹的根節點 root &#xff0c;該樹中的 恰好 兩個節點的值被錯誤地交換。請在不改變其結構的情況下&#xff0c;恢復這棵樹 。 示例 1&#xff1a; 輸入&#xff1a;root [1,3,null,null,2] 輸出&#xff1a;[3,1,null…

AirPods Pro新功能前瞻:iOS 18的五大創新亮點

隨著科技的不斷進步&#xff0c;蘋果公司一直在探索如何通過創新提升用戶體驗。iOS 18的推出&#xff0c;不僅僅是iPhone的一次系統更新&#xff0c;更是蘋果生態鏈中重要一環——AirPods Pro的一次重大升級。 據悉&#xff0c;iOS 18將為AirPods Pro帶來五項新功能&#xff0…

設計模式探索:觀察者模式

1. 觀察者模式 1.1 什么是觀察者模式 觀察者模式用于建立一種對象與對象之間的依賴關系&#xff0c;當一個對象發生改變時將自動通知其他對象&#xff0c;其他對象會相應地作出反應。 在觀察者模式中有如下角色&#xff1a; Subject&#xff08;抽象主題/被觀察者&#xf…

【大模型】大規模部署LLM:挑戰與對策

大規模部署LLM&#xff1a;挑戰與對策 引言一、計算資源的挑戰1.1 計算成本1.2 能源消耗與碳足跡 二、維護與更新的挑戰2.1 模型更新與版本控制2.2 知識時效性 三、數據隱私與倫理考量3.1 數據隱私保護3.2 倫理與偏見 四、可擴展性與靈活性4.1 系統架構設計4.2 多語言與地域適應…

詳細分析@FunctionalInterface的基本知識(附Demo)

目錄 前言1. 基本知識2. Demo 前言 Java的基本知識推薦閱讀&#xff1a; java框架 零基礎從入門到精通的學習路線 附開源項目面經等&#xff08;超全&#xff09;Spring框架從入門到學精&#xff08;全&#xff09; 1. 基本知識 FunctionalInterface 是 Java 8 引入的一個注…

外賣商城平臺小程序的設計

管理員賬戶功能包括&#xff1a;系統首頁&#xff0c;個人中心&#xff0c;用戶管理&#xff0c;商家管理&#xff0c;騎手管理&#xff0c;商品類型管理&#xff0c;商品信息管理&#xff0c;訂單信息管理 微信端賬號功能包括&#xff1a;系統首頁&#xff0c;商品信息&#…

【AI資訊早報】AI科技前沿資訊概覽:2024年7月10日早報

AI科技前沿資訊概覽&#xff0c;涵蓋了行業大會、技術創新、應用場景、行業動態等多個方面&#xff0c;全面展現了AI領域的最新發展動態和未來趨勢。 一、人工智能大模型引領新業態 在2024年&#xff08;第二十三屆&#xff09;中國互聯網大會上&#xff0c;中國工程院院士鄔賀…

模板初階詳解

目錄 泛型編程函數模板函數模板概念函數模板格式函數模板的原理函數模板的實例化隱式實例化強制類型轉換的疑惑 顯式實例化 模板參數的匹配原則 類模板類模板的定義格式類模板的實例化 感謝各位大佬對我的支持,如果我的文章對你有用,歡迎點擊以下鏈接 &#x1f412;&#x1f41…

微信小程序接口wx.getLocation違規導致封禁解決辦法

1、找到站內信的這個封禁的通知&#xff08;功能封禁的通知&#xff0c;而不是處理警告的通知&#xff09; 2、點擊通知會有申訴鏈接&#xff0c;點開申訴鏈接 申訴原因可參考下面的內容&#xff1a; 1.小程序哪些板塊已除去收集地理位置、2.哪些板塊需要收集地理位置、3.詳細…

寶塔內 計劃任務更新遠程主機的時間

很多情況下一些主機無法上網,長此以往有可能讓系統內的時間混亂 ,這是一個很愁人的事情 這里我們找了一個可以通過寶塔的計劃任務或 cron 不斷將本地時間通過ssh登錄,并在登錄狀態下設置時間的方法.找了很多方案都不行 .最終采用了私鑰登錄的方案 1 使用寶塔的計劃任務(可選): …

WindowsMac共享文件夾設置

共享文件夾設置 共享文件夾設置Windows系統設置步驟一&#xff1a;設置共享文件夾步驟二: 訪問共享文件夾 Mac系統中設置共享文件夾步驟一&#xff1a;設置共享文件夾步驟二&#xff1a;訪問共享文件夾 小貼士結論 共享文件夾設置 有時需要在多臺電腦之間共享文件夾&#xff0…

4.MkDocs樣式

學習 Admonitions(警告) - Material for MkDocs (wdk-docs.github.io) 提示 - Material for MkDocs 中文文檔 (llango.com) Buttons(按鈕) - Material for MkDocs (wdk-docs.github.io) 建議去看這些網站&#xff0c;更為詳細。 常用功能 便利貼 ?? 開啟 markdown_ex…

Linux筆記之iftop查看特定IP地址吞吐量

Linux筆記之iftop查看特定IP地址吞吐量 code review! 文章目錄 Linux筆記之iftop查看特定IP地址吞吐量一.iftop安裝與監控二.iftop 界面簡單介紹如何查看單位實時流量的顯示形式控制單位顯示示例 三.數據存儲和傳輸的單位&#xff1a;比特&#xff08;bit&#xff09;和字節&…

Gemma2——Google 新開源大型語言模型完整應用指南

0.引言 Gemma 2以前代產品為基礎&#xff0c;提供增強的性能和效率&#xff0c;以及一系列創新功能&#xff0c;使其在研究和實際應用中都具有特別的吸引力。Gemma 2 的與眾不同之處在于&#xff0c;它能夠提供與更大的專有模型相當的性能&#xff0c;但其軟件包專為更廣泛的可…

hdfs大規模數據存儲底層原理詳解(第31天)

系列文章目錄 一、HDFS設計原理 二、HDFS系統架構 三、HDFS關鍵技術 四、HDFS應用實例 五、解決HDFS不能處理小文件詳解問題 文章目錄 系列文章目錄前言一、設計原理二、系統架構三、關鍵技術四、應用實例五、解決HDFS不能處理小文件詳解問題1. 合并小文件2. 優化Hive配置3. 使…

DDR3 SO-DIMM 內存條硬件總結(一)

最近在使用fpga讀寫DDR3&#xff0c;板子上的DDR3有兩種形式與fpga相連&#xff0c;一種是直接用ddr3內存顆粒&#xff0c;另一種是通過內存條的形式與fpga相連。這里我們正好記錄下和ddr3相關的知識&#xff0c;先從DDR3 SO-DIMM 內存條開始。 1.先看內存條的版本 從JEDEC下載…

Mysql練習題目【7月10日更新】

七、Mysql練習題目 https://zhuanlan.zhihu.com/p/38354000 1. 創建表 創建學生表 mysql> create table if not exists student(-> student_id varchar(255) not null,-> student_name varchar(255) not null,-> birthday date not null,-> gender varchar(…

前端面試題33(實時消息傳輸)

前端實時傳輸協議主要用于實現實時數據交換&#xff0c;特別是在Web應用中&#xff0c;它們讓開發者能夠構建具有實時功能的應用&#xff0c;如聊天、在線協作、游戲等。以下是幾種常見的前端實時傳輸協議的講解&#xff1a; 1. Short Polling (短輪詢) 原理&#xff1a;客戶…

【1】A-Frame整體介紹

1.A-Frame是什么&#xff1f; A-Frame 是一個用于構建虛擬現實 (VR) 體驗的 Web 框架。 A-Frame 基于 HTML 之上&#xff0c;因此上手簡單。但 A-Frame 不僅僅是 3D 場景圖或標記語言&#xff1b;它還是一種標記語言。其核心是一個強大的實體組件框架&#xff0c;為 Three.js …

Golang | Leetcode Golang題解之第226題翻轉二叉樹

題目&#xff1a; 題解&#xff1a; func invertTree(root *TreeNode) *TreeNode {if root nil {return nil}left : invertTree(root.Left)right : invertTree(root.Right)root.Left rightroot.Right leftreturn root }