一篇文章帶你深入了解javaIO基礎(chǔ)
一.認(rèn)識(shí)IO
1.IO的分類
(1)BIO:同步阻塞IO
(2)NIO:同步非阻塞IO
(3)AIO:異步阻塞IO
注意: 這里主要介紹BIO
2.IO的方式
IO本質(zhì)就是對(duì)數(shù)據(jù)的操作
(1)網(wǎng)絡(luò)IO
(2)本地IO
3.IO讀寫的方式

4.IO的特性
(1)本質(zhì)上屬于數(shù)據(jù)傳輸
(2)涉及兩個(gè)設(shè)備間的傳輸方向(一般,自己寫java程序的時(shí)候,只關(guān)注自己程序的一方)
(3)數(shù)據(jù)流

(4)java進(jìn)程的IO操作,對(duì)進(jìn)程的影響:
- 1.阻塞IO 會(huì)導(dǎo)致進(jìn)程在運(yùn)行態(tài)和阻塞態(tài)之間轉(zhuǎn)變,由操作系統(tǒng)完成后序的IO操作
- 2.java進(jìn)程,在內(nèi)核態(tài)和用戶態(tài)之間切換:性能會(huì)收到影響(下降)
(5)IO緩沖流

不使用緩沖流:java程序每次都從主機(jī)內(nèi)存讀寫數(shù)據(jù),每次都直接讀取數(shù)據(jù)/發(fā)送數(shù)據(jù)。write()/read()
使用/不使用緩沖區(qū)的區(qū)別:
例如:循環(huán)10000次,每次write1個(gè)字節(jié)數(shù)據(jù)到本地文件
不使用緩沖區(qū):每次循環(huán)都是IO操作,都涉及進(jìn)程狀態(tài)由運(yùn)行態(tài)變?yōu)樽枞麘B(tài),由用戶態(tài)變?yōu)閮?nèi)核態(tài)(10000次影響)
使用緩沖區(qū):每次write復(fù)制數(shù)據(jù)到緩沖區(qū),flush才算IO操作(一定要記得)(一次影響)性能更好
二.文件操作
1.文件的構(gòu)成
(1)文件的頭信息(Metadata)
(2)文件的內(nèi)容
注意: java.io.File 不是對(duì)文件的內(nèi)容操作,知識(shí)對(duì)文件本身或者頭信息操作
2.文件的創(chuàng)建

new操作時(shí)的注意事項(xiàng):
- 1.既可以指定文件,也可以指定文件夾
- 2.通過(guò)路徑創(chuàng)建File:可以使用絕對(duì)路徑/相對(duì)路徑
- 3.不管路徑上是否存在這個(gè)文件/文件夾,java都可以創(chuàng)建得到一個(gè)File對(duì)象(但是對(duì)這個(gè)File操作時(shí),可能會(huì)拋出異常)
3.文件操作的API使用

文件操作示例:遍歷某個(gè)目錄下,所有的子文件/子文件夾
public static void main(String[] args) {
File file=new File("C:\\Users\\26905\\Desktop\\javaCode");
List<File> list=listDir(file);
// for (int i = 0; i <list.size() ; i++) {
// System.out.println(list.get(i));
// }
//jdk1.8集合框架使用Stream操作,可以使用lambda表達(dá)式打印
list.stream().forEach(System.out::println);
}
方法一: 效率不高
public static List<File> listDir(File dir){
List<File> list=new ArrayList<>();
if(dir.isFile()){
list.add(dir);//效率不太好的地方,如果是文件,返回的list只存放一個(gè)元素
}else {
File[] children=dir.listFiles();
for(File file:children){
List<File> files=listDir(file);
list.addAll(files);
}
}
return list;
}
方法二: 效率較高
public static List<File> listDir2(File dir){
List<File> list=new ArrayList<>();
if(dir.isDirectory()){
//獲取目錄下一級(jí)的子文件和子文件夾
File[] children=dir.listFiles();
if(children!=null){
for(File file:children){
if(file.isDirectory()){
//如果子文件還是文件夾,遞歸調(diào)用
list.addAll(listDir2(file));
}else{
list.add(file);
}
}
}
}
return list;
}
三.IO流
1.流的分類



2.流的創(chuàng)建

3.流的使用

<1>輸入流
import java.io.*;
public class FileInput {
/**
* 字節(jié)文件:C:\Users\26905\Desktop\畫圖筆記\JavaWeb\JSON和ajax簡(jiǎn)單介紹.png
* 字符文件:C:\Users\26905\Desktop\論文,ppt,作業(yè),筆記,圖片等\java筆記.txt
* @param args
*/
public static void main(String[] args) throws IOException {
//圖片文件,以二進(jìn)制的方式操作
File file1=new File("C:\\Users\\26905\\Desktop\\畫圖筆記\\JavaWeb\\JSON和ajax簡(jiǎn)單介紹");
File file =new File("C:\\Users\\26905\\Desktop\\論文,ppt,作業(yè),筆記,圖片等\\比特草稿本.txt");
//1.文件輸入字節(jié)流
FileInputStream fis=new FileInputStream(file);
//不知道文件有多 大,先定義一個(gè)一定大小的字節(jié)數(shù)組,然后不停讀入,每次刷新以下就好
byte[] bytes=new byte[1024*8];
//輸入流讀取的固定寫法:讀取到一個(gè)字節(jié)/字符數(shù)組,定義read的返回值變量,while
int len=0;
//len表示讀入字節(jié)的長(zhǎng)度
//如果不等于-1,說(shuō)明讀取未結(jié)束
while ((len=fis.read(bytes)) !=-1){
//讀取到的長(zhǎng)度,數(shù)組可能讀滿,也可能沒(méi)有讀滿
//當(dāng)次讀取,一般使用數(shù)組[0,len]表示讀取內(nèi)容
//字節(jié)數(shù)組轉(zhuǎn)字符串
String str=new String(bytes,0,len);
// System.out.println(str);
}
//一般來(lái)說(shuō),輸入輸出流使用完,一定要關(guān)閉,關(guān)閉的關(guān)系是反向關(guān)系
//例如:創(chuàng)建的時(shí)候是從里往外創(chuàng)建,則關(guān)閉的時(shí)候就是從外往內(nèi)關(guān)閉
fis.close();
//2.文件的字符輸入流
FileReader fr=new FileReader(file);
char []chars=new char[1024];
int lenFr=0;
while ((lenFr=fr.read(chars))!=-1){
String strFr=new String(chars,0,lenFr);
//System.out.println(strFr);
}
fr.close();
//3.緩沖流:緩沖字節(jié)輸入,緩沖字符輸入
FileInputStream FIS=new FileInputStream(file);//文件字節(jié)輸入流
//字節(jié)流轉(zhuǎn)字符流一定要經(jīng)過(guò)字節(jié)字符轉(zhuǎn)換流來(lái)轉(zhuǎn)換,并且還可以指定編碼
InputStreamReader isr=new InputStreamReader(FIS);
//緩沖流
BufferedReader br=new BufferedReader(isr);
String str;
//讀取,當(dāng)字符串為空時(shí),結(jié)束
while ((str=br.readLine()) !=null){
System.out.println(str);
}
br.close();
isr.close();
FIS.close();
}
}
<2>輸出流
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
public class FileOutput {
public static void main(String[] args) throws IOException {
/**
* D:\java代碼\1.txt
*/
//路徑上沒(méi)有該文件,new File不會(huì)報(bào)錯(cuò),但是在操作輸出流會(huì)拋出FileNotFoundException
File file2=new File("D:\\java代碼\\1.txt");
//把a(bǔ)-z換行輸出到某個(gè)文件,需要考慮文件是否存在的問(wèn)題
if(!file2.exists()){
file2.createNewFile();
}
//new FileWriter() 文件的不帶緩沖的字符輸出
//new FileWriter() 文件的不帶緩沖的字節(jié)輸出
//new BufferedWriter() 帶緩沖的字符輸出
//new PrintWriter() 打印輸出流
//緩沖的字符輸出
// BufferedWriter bw=new BufferedWriter(new FileWriter(file2));
// bw.write("\n");
//打印輸出流
//PrintWriter pw=new PrintWriter(new FileWriter(file));
PrintWriter pw =new PrintWriter(new FileOutputStream(file2));
//快速打印a-z
for (int i = 'a'; i <='z' ; i++) {
pw.println((char)i);
}
pw.flush();
}
}
<3>實(shí)例:文件的復(fù)制
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileCopy {
public static void main(String[] args) throws IOException {
//文件復(fù)制
File input=new File("D:\\java代碼\\1.txt");
File output=new File("D:\\java代碼\\2.txt");
if(!output.exists()){
output.createNewFile();
}
//定義輸入輸出流
//輸入流
FileInputStream fis=new FileInputStream(input);
// 輸出流
FileOutputStream fos=new FileOutputStream(output);
byte[]bytes=new byte[1024*8];
int len;
while ((len=fis.read(bytes))!=-1){//每次從輸入流讀取到byte[]的內(nèi)容,直接輸出到某個(gè)文件,就是復(fù)制
//bytes可能沒(méi)存滿,需要指定長(zhǎng)度
fos.write(bytes,0,len);
}
fis.close();
fos.close();
}
}
總結(jié)
本篇文章就到這里了,希望能給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
springmvc Controller方法沒(méi)有加@ResponseBody導(dǎo)致api訪問(wèn)404問(wèn)題
這篇文章主要介紹了springmvc Controller方法沒(méi)有加@ResponseBody導(dǎo)致api訪問(wèn)404問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-01-01
AsyncHttpClient?ClientStats源碼流程解讀
這篇文章主要為大家介紹了AsyncHttpClient?ClientStats源碼流程解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12
Java數(shù)組傳遞及可變參數(shù)操作實(shí)例詳解
這篇文章主要介紹了Java數(shù)組傳遞及可變參數(shù)操作,結(jié)合實(shí)例形式詳細(xì)分析了java數(shù)組參數(shù)傳遞與可變參數(shù)相關(guān)使用技巧,需要的朋友可以參考下2019-09-09

