前言
Java中使用IO(輸入輸出)來讀取和寫入,讀寫設(shè)備上的數(shù)據(jù)眨唬、硬盤文件会前、內(nèi)存、網(wǎng)絡(luò)......匾竿,根據(jù)數(shù)據(jù)的走向可分為輸入流和輸出流瓦宜,這個走向是以內(nèi)存為基準(zhǔn)的,即往內(nèi)存讀外面的數(shù)據(jù)是輸入流岭妖,從內(nèi)存中往外寫是輸出流临庇。
IO總結(jié)
字節(jié)流和字符流-1
字節(jié)流和字符流-2
根據(jù)處理的數(shù)據(jù)類型可分為字節(jié)流和字符流。
- 字節(jié)流可以處理所有數(shù)據(jù)類型的數(shù)據(jù)昵慌,在java中以Stream結(jié)尾苔巨。
- 字符流處理文本數(shù)據(jù),在java中以Reader和Writer結(jié)尾废离。
在程序中所有的數(shù)據(jù)都是以流的方式進(jìn)行傳輸或保存的侄泽,程序需要數(shù)據(jù)的時(shí)候要使用輸入流讀取數(shù)據(jù),而當(dāng)程序需要將一些數(shù)據(jù)保存起來的時(shí)候蜻韭,就要使用輸出流完成悼尾。程序中的輸入輸出都是以流的形式保存的,流中保存的實(shí)際上全都是字節(jié)文件肖方。字符流處理的單元為2個字節(jié)的Unicode字符闺魏,分別操作字符、字符數(shù)組或字符串俯画,而字節(jié)流處理單元為1個字節(jié)析桥,操作字節(jié)和字節(jié)數(shù)組。所以字符流是由Java虛擬機(jī)將字節(jié)轉(zhuǎn)化為2個字節(jié)的Unicode字符為單位的字符而成的,所以它對多國語言支持性比較好泡仗!如果是音頻文件埋虹、圖片、歌曲娩怎,就用字節(jié)流好點(diǎn)搔课,如果是關(guān)系到中文(文本)的,用字符流好點(diǎn)截亦。所有文件的儲存是都是字節(jié)(byte)的儲存爬泥,在磁盤上保留的并不是文件的字符而是先把字符編碼成字節(jié),再儲存這些字節(jié)到磁盤崩瓤。在讀取文件(特別是文本文件)時(shí)袍啡,也是一個字節(jié)一個字節(jié)地讀取以形成字節(jié)序列。字節(jié)流可用于任何類型的對象却桶,包括二進(jìn)制對象葬馋,而字符流只能處理字符或者字符串;字節(jié)流提供了處理任何類型的IO操作的功能肾扰,但它不能直接處理Unicode字符畴嘶,而字符流就可以。字節(jié)流是最基本的集晚,所有的InputStrem和OutputStream的子類都是窗悯,主要用在處理二進(jìn)制數(shù)據(jù),它是按字節(jié)來處理的偷拔,但實(shí)際中很多的數(shù)據(jù)是文本蒋院,又提出了字符流的概念,它是按虛擬機(jī)的encode來處理莲绰,也就是要進(jìn)行字符集的轉(zhuǎn)化 這兩個之間通過InputStreamReader欺旧,OutputStreamWriter來關(guān)聯(lián),實(shí)際上是通過byte[]和String來關(guān)聯(lián) 在實(shí)際開發(fā)中出現(xiàn)的漢字問題實(shí)際上都是在字符流和字節(jié)流之間轉(zhuǎn)化不統(tǒng)一而造成的 蛤签。我們還可以看到:Reader類的read()方法返回類型為int :作為整數(shù)讀取的字符(占兩個字節(jié)共16位)辞友,范圍在 0 到 65535 之間 (0x00-0xffff),如果已到達(dá)流的末尾震肮,則返回 -1称龙;InputStream的read()雖然也返回int,但由于此類是面向字節(jié)流的戳晌,一個字節(jié)占8個位鲫尊,所以返回 0 到 255 范圍內(nèi)的 int 字節(jié)值。如果因?yàn)橐呀?jīng)到達(dá)流末尾而沒有可用的字節(jié)沦偎,則返回值 -1疫向。因此對于不能用0-255來表示的值就得用字符流來讀瓤任怠!比如說漢字搔驼。
不同平臺的符號
符號 | Linux | Windows |
---|---|---|
換行符谈火,可以使用System.getProperty("line.separator")
|
\n |
\r\n |
路徑分隔符,可以使用File.separator
|
/ |
\ |
多個路徑分隔符匙奴,可以使用File.pathSeparator
|
: |
; |
字節(jié)流和字符流的區(qū)別
字符流使用了緩存區(qū)(內(nèi)存),執(zhí)行了write()
妄荔,文件中不會立刻有內(nèi)容(除非緩沖區(qū)滿了或者主動刷新緩沖區(qū))泼菌,需要等輸出流對象關(guān)閉了,文件中才會有內(nèi)容啦租;字節(jié)流不使用緩沖區(qū)哗伯,執(zhí)行了wirite()
,文件中立刻就有內(nèi)容了篷角。
import java.util.*;
import java.io.*;
public class WriterTest {
public static void main(String[] args) {
File file = new File("1.txt");
Scanner in = null;
Writer out = null;
try{
in = new Scanner(System.in);
out = new FileWriter(file);//需要定義在try代碼塊外面焊刹,定義在try代碼塊里面的話,finally中訪問不了
String data = null;
while(in.hasNext()){
data = in.nextLine();
if(data == null){
data = "";
}
out.write(data);
//out.flush();刷新緩沖區(qū)恳蹲,將緩沖區(qū)的內(nèi)容輸出
}
}catch(Exception e) {
e.printStackTrace();
}
finally{
try{
in.close();
out.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
}
import java.util.*;
import java.io.*;
public class OutputStreamTest {
public static void main(String[] args) {
File file = new File("2.txt");
Scanner in = null;
FileOutputStream out = null;
try{
in = new Scanner(System.in);
//覆蓋式虐块,追加式多一個true參數(shù)
out = new FileOutputStream(file);
String data = null;
byte[] bytes = null;
while(in.hasNext()){
data = in.nextLine();
if(data != null){
bytes = data.getBytes();
}else{
bytes = "".getBytes();
}
out.write(bytes);
}
}catch(Exception e) {
e.printStackTrace();
}finally{
try{
in.close();
out.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
}
字節(jié)數(shù)組和字符串的轉(zhuǎn)換
- public String(byte[] bytes, String charsetName)
- String(byte[] bytes, int off, int length)
- byte[] getBytes(String charsetName)
File
File類用于操作文件或目錄本身
- File類有四個靜態(tài)變量
變量名 | 作用 |
---|---|
File.pathSeparator | 系統(tǒng)相關(guān)的多個路徑的分隔符,字符串類型嘉蕾,windows為; Unix為:
|
File.pathSeparatorChar | pathSeparator的第一個字符贺奠,為字符型 |
File.separator | 系統(tǒng)相關(guān)的路徑分隔符,字符串類型错忱,Unix類為/ 儡率,windows為\\ (轉(zhuǎn)義) |
File.separatorChar | separator的第一個字符,為字符型 |
-
構(gòu)造函數(shù)
constructors.png - 方法
Java SE 8 API
Path
Java SE 8 API
java.nio.file包中的接口以清。Path描述的是一種層級結(jié)構(gòu)的路徑(目錄和文件)儿普,一個Path是由多個被分隔符分隔的name element組成(比如c/src/1.txt
就是3個),可以和File掷倔,URI對象互相轉(zhuǎn)化眉孩;Path接口的實(shí)現(xiàn)者是不可變的,線程安全的勒葱。官方文檔描述(節(jié)選):
An object that may be used to locate a file in a file system. It will typically represent a system dependent file path. A Path represents a path that is hierarchical and composed of a sequence of directory and file name elements separated by a special separator or delimiter.Paths associated with the default
provider
are generally interoperable with thejava.io.File
class. Paths created by other providers are unlikely to be interoperable with the abstract path names represented byjava.io.File
. ThetoPath
method may be used to obtain aPath
from the abstract path name represented by ajava.io.File
object. The resultingPath
can be used to operate on the same file as thejava.io.File
object. In addition, thetoFile
method is useful to construct aFile
from theString
representation of aPath
. Implementations of this interface are immutable and safe for use by multiple concurrent threads.
Paths
java.nio.file包中的final類勺像,作用是獲取Path
另外獲取Path的方法是FileSystems.getDefault().getPath(str)和file.toPath()
URI
可以和File,Path轉(zhuǎn)化
Files
Java SE 8 API
Files使用
java.nio.file包中的類错森,該工具類非常強(qiáng)大吟宦,可以操作文件(File的功能全有),讀寫文件涩维,讀取文件屬性殃姓,讀取和設(shè)置文件權(quán)限袁波,遍歷單個目錄和整個目錄(即遞歸遍歷)蜗侈,復(fù)制文件(Path-Path夭苗,Path-輸出流,輸入流-Path);參數(shù)是Path(不是File)瞧挤;獲取文件大小直接有size
方法獲取文件的空間使用情況要先獲取FileStore對象,再通過FileStore對象來獲取
Closeable接口和AutoCloneable接口
前者extends了后者远荠,實(shí)現(xiàn)了后者的類都可以使用帶資源的try守伸,而且可以拋出任何類型的異常惠赫;前者只能拋出IOException
String,StringBuilder怠缸,StringBuffer
三者之所以有l(wèi)ength方法是因?yàn)樗鼈儗?shí)現(xiàn)了CharSequence接口
DataInput和DataOutput接口
可以將各種類型的數(shù)據(jù)寫入或讀取诗轻,對于int完整的寫入其4個字節(jié),對于double寫入其8個字節(jié)揭北,其他類型也一樣扳炬,占用多少字節(jié)就寫入多少字節(jié),不像OutputStream的write方法(參數(shù)為int型的那個)只寫入一個字節(jié)搔体,如果要寫入的數(shù)據(jù)類型是多個字節(jié)的則會截?cái)嗪拚粒粚懙臀坏淖止?jié)。DataInputStream和DataOutputStream分別實(shí)現(xiàn)了這兩個接口疚俱,RandomAccessFile則同時(shí)實(shí)現(xiàn)了這兩個接口
OutputStream
OutputStream是所有字節(jié)輸出流的祖先劝术,是抽象類
- 方法
Java SE 8 API
需要注意的是最后一個write(int b)
方法,參數(shù)為int型呆奕,但實(shí)際只輸出低八位养晋,高24位忽略,比如write(258)
梁钾,int型的258的二進(jìn)制形式為00000000 00000000 00000001 00000010
共4個字節(jié)绳泉,但是只保存最低位置的那個字節(jié)到硬盤中,所以取出來的時(shí)候值為2
OutputStream.png
InputStream
InputStream是所有字節(jié)輸入流的祖先姆泻,是抽象類圈纺,雖然是阻塞IO秦忿,但是InputStream有一個available方法用于返回流當(dāng)前可以返回的字節(jié)數(shù),如果流當(dāng)前不能讀蛾娶,就返回0灯谣,我們可以在讀取流之前使用這個方法判斷,這樣就可以避免造成當(dāng)前線程的阻塞
- 方法
Java SE 8 API
注意特殊的mark
蛔琅、reset
胎许、skip
方法
- 讀取單個字節(jié):public int read() throws IOException;
每次使用read()操作將讀取一個字節(jié)數(shù)據(jù),此時(shí)返回的是數(shù)據(jù)(注意是int類型)罗售,如果數(shù)據(jù)已讀完辜窑,則int返回-1 - 讀取內(nèi)容到字節(jié)數(shù)組:public int read(byte [] b) throws IOException();
將內(nèi)容讀取到字節(jié)數(shù)組中,返回讀取的個數(shù)寨躁,如果讀取完畢穆碎,則返回-1 -
讀取內(nèi)容到部分字節(jié)數(shù)組:public int read(byte [] b,int off,int len) throws IOException();
將指定長度的內(nèi)容讀取到字節(jié)數(shù)組中,返回讀取個數(shù)职恳,如果讀取完畢所禀,則返回-1
InputStream.png
- 對于
read(byte[] b)
的一點(diǎn)解釋
該方法的功能說明讓我疑惑的是,讀完了到底返回字節(jié)數(shù)還是-1放钦?
import java.io.File;
import java.io.FileInputStream;
public class Test {
public static void main(String[] args) {
File file = new File("1.txt");
byte[] bytes = new byte[200];
int len = 0;
try(FileInputStream in = new FileInputStream(file)) {
while((len = in.read(bytes)) != -1) {
System.out.println(len);
System.out.println(new String(bytes,0,len,"utf-8"));
}
}catch(Exception e) {
e.printStackTrace();
}
}
}
對于這段代碼中的循環(huán)色徘,其實(shí)執(zhí)行了兩次循環(huán),第一次循環(huán)讀取完返回文件字節(jié)數(shù)操禀,并打印出來褂策;第二次循環(huán)返回-1,結(jié)束循環(huán)颓屑。
Writer
Writer是所有字符輸出流的祖先斤寂,是抽象類
- 方法
Java SE 8 API
FileWriter不是Writer的直接子類,是Writer的直接子類OutputStreamWriter的直接子類
Writer.png
Reader
Reader是所有字符輸入流的祖先揪惦,是抽象類
- 方法
Java SE 8 API
FileReader不是Reader的直接子類遍搞,是Reader的直接子類InputStreamReader的直接子類
Reader
字節(jié)流和字符流的轉(zhuǎn)換
主要使用兩個類:OutputStreamWriter、 InputStreamReader
OutputStreamWriter是Writer的子類丹擎,所以O(shè)utputStreamWriter類對象可以自動轉(zhuǎn)型為Writer類實(shí)例尾抑,以O(shè)utputStream的對象作為構(gòu)造器參數(shù)。
InputStreamReader是Reader的子類蒂培,所以InputStreamReader類對象可以自動轉(zhuǎn)型為Reader類實(shí)例再愈,以InputStream的對象作為構(gòu)造器參數(shù)。
OutputStreamWriter
直接子類FileWriter
-
構(gòu)造方法
OutputStreamWriter.png -
方法
多數(shù)都是繼承來的护戳,下面這個方法是自己的
image.png
InputStreamReader
直接子類FileReader
-
構(gòu)造方法
InputStreamReader.png -
方法
多數(shù)都是繼承來的翎冲,下面這個方法是自己的
image.png
PrintWriter、BufferedWriter以及BufferredReader
PrintWriter媳荒、BufferedWriter以及BufferredReader
PrintWriter是具有自動行刷新的緩沖字符輸出流抗悍,這是一個高級流驹饺。所謂的自動行刷新,意思就是說:在構(gòu)造函數(shù)中指定autoFlush的值為true時(shí)缴渊,則 println()赏壹、printf() 或 format() 方法將自動刷新輸出緩沖區(qū)(自動調(diào)用flush()方法),但是自動行刷新無疑會增加寫出次數(shù)而降低寫出效率衔沼。從PrintWeiter的構(gòu)造方法中我們就可以知道蝌借,該高級流很靈活,接下來我們會介紹BufferedWriter/BufferedReader這一對字符緩沖流指蚁,但是菩佑,由于BufferedWriter沒有PrintWriter使用靈活,所以在實(shí)際的操作中凝化,我們往往會使用PrinterWriter/BufferedReader這種組合稍坯。
對象和字節(jié)數(shù)組的轉(zhuǎn)換
- io.netty.buffer.ByteBuf,適用于對象的數(shù)據(jù)少
- 借助Json作為中間人搓劫,缺點(diǎn)是會獲得的字節(jié)數(shù)組會帶有JSon的格式化符號
{}
- 反射瞧哟,適用于對象的數(shù)據(jù)多
StringWriter和StringReader
-
StringWriter
Writer的直接子類,將流的內(nèi)容寫入一個StringBuffer糟把,可以調(diào)用getBuffer()方法獲取這個StringBuffer
image.png
-
StringReader
Reader的直接子類绢涡,流從一個給定的字符串獲取內(nèi)容
image.png
DataInputStream和DataOutputStream
用于數(shù)值型的數(shù)據(jù)
PushbackInputStream
可預(yù)覽的輸入流牲剃,即可以先調(diào)用read方法讀出來遣疯,如果不是自己想要的,就調(diào)用unread方法退回去
組合流過濾器
不同的流具有不同的功能凿傅,如果想同時(shí)具備這些功能缠犀,就可以使用組合流過濾器的方式,將一個類型的流傳給另一個類型的流的構(gòu)造器聪舒,從而兼具兩種流的特性辨液。比如想要兼具有預(yù)覽功能,使用緩存機(jī)制箱残,從文件讀取數(shù)值類型的流滔迈,則可以
DataInputStream din = new DataInputStream(
new PushbackInputStream (
new BufferdInputStream(
new FileInputStream(...))));
IO家族
常用的流
包裝流:PrintStream/PrintWriter/Scanner
PrintStream可以封裝(包裝)直接與文件交互的流對象OutputStream,使得編程人員可以忽略設(shè)備底層的差異被辑,進(jìn)行一致的IO操作燎悍。因此這種流也稱為處理流或者包裝流。PrintWriter除了可以包裝字節(jié)流OutputStream之外盼理,還能包裝字符流Writer谈山。Scanner可以包裝鍵盤輸入(System.in),方便地將鍵盤輸入的內(nèi)容轉(zhuǎn)換成我們想要的數(shù)據(jù)類型宏怔。字符串流:StringReader/StringWriter
這兩個操作的是專門操作String字符串的流奏路,其中StringReader能從String中方便地讀取數(shù)據(jù)并保存到char數(shù)組畴椰,而StringWriter則將字符串類型的數(shù)據(jù)寫入到StringBuffer中(因?yàn)镾tring不可寫)。轉(zhuǎn)換流:InputStreamReader/OutputStreamReader
這兩個類可以將字節(jié)流轉(zhuǎn)換成字符流鸽粉,被稱為字節(jié)流與字符流之間的橋梁斜脂。我們經(jīng)常在讀取鍵盤輸入(System.in)或網(wǎng)絡(luò)通信的時(shí)候,需要使用這兩個類緩沖流:BufferedReader/BufferedWriter触机,BufferedInputStream/BufferedOutputStream
Oracle官方的描述:
Most of the examples we've seen so far use unbuffered I/O. This means each read or write request is handled directly by the underlying OS. This can make a program much less efficient.
Buffered input streams read data from a memory area known as a buffer; the native input API is called only when the buffer is empty. Similarly, buffered output streams write data to a buffer, and the native output API is called only when the buffer is full.
即:沒有經(jīng)過Buffered處理的IO秽褒, 意味著每一次讀和寫的請求都會由OS底層直接處理,這會導(dǎo)致非常低效的問題威兜。經(jīng)過Buffered處理過的輸入流將會從一個buffer內(nèi)存區(qū)域讀取數(shù)據(jù)销斟,本地API只會在buffer空了之后才會被調(diào)用(可能一次調(diào)用會填充很多數(shù)據(jù)進(jìn)buffer)。經(jīng)過Buffered處理過的輸出流將會把數(shù)據(jù)寫入到buffer中椒舵,本地API只會在buffer滿了之后才會被調(diào)用蚂踊。
BufferedReader/BufferedWriter可以將字符流(Reader/Writer)包裝成緩沖流,這是最常見用的做法笔宿。另外犁钟,BufferedReader提供一個readLine()可以方便地讀取一行,而FileInputStream和FileReader只能讀取一個字節(jié)或者一個字符泼橘,因此BufferedReader也被稱為行讀取器
總結(jié)上面幾種流的應(yīng)用場景:
- FileInputStream/FileOutputStream 需要逐個字節(jié)處理原始二進(jìn)制流的時(shí)候使用涝动,效率低下
- FileReader/FileWriter 需要逐個字符處理的時(shí)候使用
- StringReader/StringWriter 需要處理字符串的時(shí)候,可以將字符串保存為字符數(shù)組
- PrintStream/PrintWriter 用來包裝FileOutputStream 對象炬灭,方便直接將String字符串寫入文件 醋粟;Scanner用來包裝System.in流,很方便地將輸入的String字符串轉(zhuǎn)換成需要的數(shù)據(jù)類型
- InputStreamReader/OutputStreamReader , 字節(jié)和字符的轉(zhuǎn)換橋梁重归,在網(wǎng)絡(luò)通信或者處理鍵盤輸入的時(shí)候用
- BufferedReader/BufferedWriter 米愿, BufferedInputStream/BufferedOutputStream , 緩沖流用來包裝字節(jié)流后者字符流鼻吮,提升IO性能育苟,BufferedReader還可以方便地讀取一行,簡化編程椎木。
RandomAccessFile
注意這是個流违柏,不是File。從截圖來看香椎,這個流直接繼承Object漱竖,跟字符流和字節(jié)流不是一個系列的。并且實(shí)現(xiàn)了DataOutput和DataInput士鸥,所以可以讀闲孤,也可以寫。
- 存在的意義
是JAVA I/O流體系中功能最豐富的文件內(nèi)容訪問類,它提供了眾多方法來訪問文件內(nèi)容讼积。
由于可以自由訪問文件的任意位置肥照,所以如果需要訪問文件的部分內(nèi)容,RandomAccessFile將是更好的選擇勤众。
可以用來訪問保存數(shù)據(jù)記錄的文件舆绎,文件的記錄的大小不必相同,但是其大小和位置必須是可知的们颜。
這個類在很多資料上翻譯成中文都是:隨機(jī)訪問文件吕朵,在中文里,隨機(jī)是具有不確定的含義窥突,指一會訪問這里努溃,一會訪問那里的意思。如果以這種語義來解釋的話阻问,就會感到很困惑梧税。其實(shí),Random在英文中不僅僅有隨機(jī)称近,還有任意的意思第队。如果中文名為任意訪問文件是不是就會更好的理解。任意表示我們可以指定文件中任何一個位置去操作一個文件刨秆。
Charset字符集類
對于無法表示的字符凳谦,全用\ufffd
,即顯示?
utf-16BE(big-endian)遵從高位在前衡未,utf-16LE(little-endian)遵從低位在前
方法 | 描述 |
---|---|
availableCharsets | 靜態(tài)方法尸执,返回虛擬機(jī)可用的字符集的map,鍵為字符集名稱眠屎,值為字符集對象 |
forName | 靜態(tài)方法剔交,根據(jù)字符集名稱獲取字符集對象 |
name | 返回字符集名稱 |
aliases | 返回該字符集的別名集合 |
ByteBuffer encode(String str) | 將字符串編碼成字節(jié)序列 |
CharBuffer decode(ByteBuffer buffer) | 解碼給定的字節(jié)序列肆饶,返回字符序列 |
- ByteBuffer
方法 | 描述 |
---|---|
byte[] array() | 返回該字節(jié)序列的字節(jié)數(shù)組 |
static ByteBuffer wrap(byte[] bytes) | 將字節(jié)數(shù)組包裝成字節(jié)緩沖區(qū)(字節(jié)序列) |
- CharBuffer
方法 | 描述 |
---|---|
char[] array() | 返回該字符緩沖區(qū)的字符數(shù)組 |
char charAt(int index) | 返回指定索引的代碼單元 |
對象序列化
要序列化的類需要實(shí)現(xiàn)Serializable接口改衩,該接口沒有方法,屬于標(biāo)記接口
ObjectInputStream和ObjectOutputStream驯镊,readObject方法和writeObject方法葫督。序列化使用序列號機(jī)制,給每個序列化的對象分配一個唯一的序列號板惑,所以在保存一個序列化對象到文件中時(shí)橄镜,如果之前已經(jīng)保留存了,后面保存則會引用前面保存的冯乘,讀取也是一樣的道理
NIO
- Path路徑洽胶,路徑解析(resolve,resolveSibling裆馒,relativize姊氓,normalize丐怯,toAbsolutePath,getParent翔横,getRoot读跷,getFileName,toFile)
- Paths默認(rèn)的文件系統(tǒng)禾唁,獲取Path(get方法)
- Files文件操作(創(chuàng)建/刪除文件/目錄效览,復(fù)制/移動),讀取文件內(nèi)容(readAllBytes荡短,readAllLines等等)丐枉,創(chuàng)建輸入輸出流(newInputStream,newOutputStream掘托,newBufferReader等等)矛洞,獲取文件信息,遍歷目錄(不包括子目錄)烫映,遍歷目錄數(shù)(walkFileTree方法沼本,遞歸遍歷)
- FileStore文件存儲空間情況
- FileVisitor文件訪問者接口(訪問前,訪問锭沟,訪問后抽兆,訪問失敗4個方法)
- SimpleFileVisitor文件訪問接口的實(shí)現(xiàn)類
- DirectoryStream用來迭代要遍歷的目錄(Files的非遞歸遍歷中使用)
- FileSystem文件系統(tǒng),獲取Path(getPath方法)
- FileSystems文件系統(tǒng)工具族淮,可以創(chuàng)建新的文件系統(tǒng)(newFileSystem方法)辫红,獲取默認(rèn)的文件系統(tǒng)(getDefault方法)
- FileSystemProvider文件系統(tǒng)提供者
- Buffer緩沖區(qū)抽象類,是一種特殊的內(nèi)存(0<=mark<=position<=limit<=capacity)祝辣,clear贴妻,flip,mark蝙斜,reset名惩,compact,rewind孕荠,hasRemaining娩鹉,remaining,position稚伍,limit弯予,capacity,put个曙,get...
- ByteBuffer字節(jié)緩沖區(qū)锈嫩,allocate(創(chuàng)建一個指定大小的緩沖區(qū)),array(返回緩沖區(qū)管理的字節(jié)數(shù)組),wrap(將數(shù)組包裝成字節(jié)緩沖區(qū))
- MappedByteBuffer內(nèi)存映射文件呼寸,ByteBuffer的子類那槽,對于讀取大文件很有幫助
- CharBuffer字符緩沖區(qū)
- 其他的XXBuffer(StringBuffer跟這些Buffer完全沒關(guān)系)
- Channel通道,通道是線程安全的等舔,可讀可寫骚灸,流是單向的,可以通過靜態(tài)的open方法創(chuàng)建一個通道慌植,也可以通過流的getChannel方法獲取通道
- FileChannel文件通道甚牲,map方法返回MappedByteBuffer的對象
- SocketChannel 客戶端TCP連接
- ServerSocketChannel 服務(wù)端TCP連接
- DatagramChannel UDP包
- CRC32(java.util.zip包中),計(jì)算循環(huán)冗余校驗(yàn)和蝶柿,用來判斷一個文件是否損壞
InputStream in = ...;
CRC32 crc = new CRC32();
int c;
while((c = in.read()) != -1) { crc.update(c)}
rerurn crc.getValue();//返回校驗(yàn)和
- 文件鎖FileLock丈钙,鎖定文件或文件的某一部分
如果多個進(jìn)程(或線程)要對同一個文件進(jìn)行訪問,為了保證文件的安全交汤,使用文件鎖雏赦,文件鎖通過channel獲得,channel調(diào)用lock(阻塞式)或tryLock(非阻塞式)來獲得文件鎖并鎖定文件芙扎,在鎖對象關(guān)閉(鎖對象調(diào)用close方法或release方法星岗,close最終還是調(diào)用release方法)或者channel關(guān)閉之前,其他人無法訪問該文件(或文件的某一部分)
Path path = Paths.get(str);
FileChannel channel = FileChannel.open(path);
FileLock lock = channel.lock();//or tryLock
正則表達(dá)式戒洼,\
和[
需要轉(zhuǎn)義
語法 | 描述 |
---|---|
字符 | |
c | 字符c |
\unn俏橘,\xnn,\0nn | 以特定進(jìn)制的形式給定代碼單元的字符 |
\t圈浇,\n寥掐,\r,\f磷蜀,\a召耘,\e | 控制字符,制表褐隆、換行污它、回車、換頁符妓灌、警告符轨蛤、逃逸符 |
字符類 | |
[C1C2...Cn] | 字符集中的任何一個字符,如[0-9]表示任何數(shù)字字符 |
[^C1C2...Cn] |
^ 也可以用虫埂! 字符集的補(bǔ)集,如[^0-9]表示任何非數(shù)字字符 |
[C1C2...&&B1B2...] | 兩個集合的交集 |
預(yù)定義字符類 | |
\d | 一個數(shù)字字符圃验,等同于[0-9] |
\D | 一個非數(shù)字字符掉伏,等同于[^0-9] |
\w | 一個詞語類字符把夸,即[0-9a-zA-Z_]浪册,包括數(shù)字,大小寫字母,下劃線 |
\W | 一個非詞語類字符 |
\s | 空白字符 |
\S | 非空白類字符 |
邊界匹配符 | |
^ $ | 輸入的開頭和結(jié)尾橡庞,或者多行模式下的行的開頭和結(jié)尾 |
\A | 輸入的開頭 |
\z | 輸入的結(jié)尾 |
量詞 | |
X? | 0或1個X |
X* | 0或多個X |
X+ | 1或多個X |
X{n} | n個X |
X{n,} | 至少n個X |
X{n,m} | n至m個X |
集合操作 | |
XY | 任何X中的字符串,后面緊跟Y中的字符串 |
XIY | X或Y中的字符串 |
String patternString = ...;
Pattern pattern = Pattern.compile(patternString);//獲取模式對象
String input = ...;
Matcher matcher = pattern.matcher(input)//獲取匹配器
if(matcher.matchs())//判斷input字符串是否匹配
String patternString = ...;
Pattern pattern = Pattern.compile(patternString);//獲取模式對象
String input = ...;
Matcher matcher = pattern.matcher(input)//獲取匹配器
//獲取輸入中匹配到的字符串
while(matcher.find()) {
int start = match.start();
int end = matcher.end();
String matchString = input.subString(start, end);
}
String patternString = ...;
Pattern pattern = Pattern.compile(patternString);//獲取模式對象
String input = ...;
Matcher matcher = pattern.matcher(input)//獲取匹配器
//替代第一個匹配到的
String str = matcher.replaceFirst(anotherString)
//替代所有匹配到的
String str1 = matcher.replaceAll(anotherString)//
URL
String urlString = "https://www.baidu.com";
URL url = new URL(urlString);
InputStreamReader = new InputStreamReader(url.openStream());
// 方法一
URL url = new URL("http://www.sina.com.cn");
URLConnection urlcon = url.openConnection();
InputStream is = urlcon.getInputStream();
// 方法二
URL url = new URL("http://www.yhfund.com.cn");
HttpURLConnection urlcon = (HttpURLConnection)url.openConnection();
InputStream is = urlcon.getInputStream();
//方法三
URL url = new URL("http://www.yhfund.com.cn");
InputStream is = url.openStream();
long begintime = System.currentTimeMillis();
URL url = new URL("http://www.yhfund.com.cn");
HttpURLConnection urlcon = (HttpURLConnection)url.openConnection();
urlcon.connect(); //獲取連接
InputStream is = urlcon.getInputStream();
BufferedReader buffer = new BufferedReader(new InputStreamReader(is));
StringBuffer bs = new StringBuffer();
String l = null;
while((l=buffer.readLine())!=null){
bs.append(l).append("/n");
}
System.out.println(bs.toString());
//System.out.println(" content-encode:"+urlcon.getContentEncoding());
//System.out.println(" content-length:"+urlcon.getContentLength());
//System.out.println(" content-type:"+urlcon.getContentType());
//System.out.println(" date:"+urlcon.getDate());
System.out.println("總共執(zhí)行時(shí)間為:"+(System.currentTimeMillis()-begintime)+"毫秒");
}catch(IOException e){
System.out.println(e);
}
}
}