File
1.File類是一個(gè)對(duì)象,代表一個(gè)文件或一個(gè)文件目錄(即文件夾)
2.File類聲明在java.io包下
3.如何創(chuàng)建File類的實(shí)例
4.相對(duì)路徑:相較于某個(gè)路徑下单匣,指明的路徑
絕對(duì)路徑:包含盤符在內(nèi)的文件或文件目錄的路徑
5.路徑分隔符:windows:\ unix: \
File f1 = new File("hello.txt");//絕對(duì)路徑 hello.txt
File f2 = new File("E:\\User\\hell1.txt");//相對(duì)路徑 E:\User\hell1.txt
File f = new File("E:"+File.separatorChar+"User1"+File.pathSeparator+"h.txt");//E:\User1;h.txt
File f3 = new File("E:\\User","file");//E:\User\file
File f4 = new File(f3,"hello2o2.txt");//E:\User\file\hello2o2.txt
6.File中常用方法
File f1 = new File("hell1.txt");
System.out.println(f1.getAbsolutePath());//絕對(duì)路徑 E:\User\\hell1.txt
System.out.println(f1.getPath());//路徑 hell1.txt
System.out.println(f1.getName());//hell1.txt
System.out.println(f1.getParent());//上層文件目錄 null
System.out.println(f1.length());//內(nèi)容長(zhǎng)度
System.out.println(new Date(f1.lastModified()));//最后一次修改時(shí)間,毫秒值 Thu Jan 01 08:00:00 CST 1970
File f2 = new File("E:\\User\\hell1.txt");
System.out.println(f2.getAbsolutePath());//絕對(duì)路徑 E:\User\hell1.txt
System.out.println(f2.getPath());//路徑 E:\User\hell1.txt
System.out.println(f2.getName());//hell1.txt
System.out.println(f2.getParent());//父類 E:\User
System.out.println(f2.length());//內(nèi)容長(zhǎng)度
System.out.println(f2.lastModified());//最近被修改時(shí)間 1586955653716
File f = new File("E:\\User\\test");//
//list()獲取文件夾下的所有文件名
String[] list = f.list();
for(String s : list){
System.out.println(s);//test1 test2
}
File f1 = new File("E:\\User\\test");
//listFiles()獲取文件夾下的所有文件路徑名
File[] files = f1.listFiles();
for(File file : files){
System.out.println(file);//E:\User\test\test1 E:\User\test\test2
}
創(chuàng)建
/*
* 創(chuàng)建磁盤中對(duì)應(yīng)的文件或文件目錄
* 1.createNewFile() 創(chuàng)建文件秕硝,若文件存在暴浦,則不創(chuàng)建,返回false;反之崇败,創(chuàng)建文件并返回true
* 2.delete()刪除文件或文件夾盅称。
* 3.mkdir()、 mkdirs() 文件夾的創(chuàng)建
* */
File f = new File("h.txt");
try {
//文件的創(chuàng)建和刪除
System.out.println(f.createNewFile());
System.out.println(f.delete());
} catch (IOException e) {
e.printStackTrace();
}
//文件目錄的創(chuàng)建后室,如下文件目錄中只存在E:\User
File f1 = new File("E:\\User\\hell\\test1");
//1.mkdir()文件上層目錄不存在缩膝,則不會(huì)創(chuàng)建文件;如上由于hell文件目錄不存在岸霹,則創(chuàng)建文件目錄失敗
System.out.println(f1.mkdir());
File f2 = new File("E:\\User\\hell\\test2");
//2.mkdirs()文件上層目錄不存在疾层,則會(huì)創(chuàng)建上層目錄,如上hell文件目錄不存在贡避,但仍然會(huì)創(chuàng)建出該文件目錄
System.out.println(f1.mkdirs());
//刪除文件夾時(shí)痛黎,該文件夾下沒有內(nèi)容時(shí)可以刪除成功,否則刪除失敗
注:File類中涉及到文件和文件目錄的操作刮吧,并未涉及寫入或讀取文件的內(nèi)容操作湖饱,此操作需要借助IO流實(shí)現(xiàn);File類對(duì)象作為參數(shù)傳遞到流的構(gòu)造器中杀捻,指明讀取或?qū)懭氲摹敖K點(diǎn)”
IO流
節(jié)點(diǎn)流(即文件流井厌,訪問文件的操作)
字符流:對(duì)文件進(jìn)行讀取操作
/*
* 文件的相對(duì)路徑:
* idea中main:相對(duì)于Project而言致讥,JUnitTest中相對(duì)當(dāng)前moudle;eclipse中相對(duì)路徑相同
*
* */
public static void main(String[] args) {
File f = new File("\\Moudle\\hello.txt");//需要添加moudle的路徑
System.out.println(f.getAbsolutePath());//E:\User\vv\Moudle\hello.txt
}
@Test
public void test() throws Exception {
//1.指明要操作的文件
File f = new File("hello.txt");
System.out.println(f.getAbsolutePath()); //E:\User\vv\Moudle\hello.txt
//2.獲得文件的輸入流
FileReader fr = new FileReader(f);
int data ;
while((data = fr.read()) != -1){//判斷是否能讀取到字符,達(dá)到文件末尾時(shí)返回-1
System.out.print((char)data+"\t");//(char)fr.read()將字節(jié)碼轉(zhuǎn)換成字符
}
fr.close();
}
//為保證IO流可以正常關(guān)閉仅仆,應(yīng)該使用try-catch-finally而不是throws異常
@Test
public void test() {
//1.指明要操作的文件
File f = new File("hello.txt");
System.out.println(f.getAbsolutePath()); //E:\User\vv\Moudle\hello.txt
FileReader fr = null;
try {
//2.獲得文件的輸入流
fr = new FileReader(f);
int data ;
while((data = fr.read()) != -1){//判斷是否能讀取到字符,達(dá)到文件末尾時(shí)返回-1
System.out.print((char)data+"\t");//(char)fr.read()將字節(jié)碼轉(zhuǎn)換成字符
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//關(guān)閉文件輸入流
if(fr != null)
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//同時(shí)讀入的文件若不存在,則java.io.FileNotFoundException:
read()的各種重載方法讀取數(shù)據(jù)
//1.空參read()
int data ;
while((data = fr.read()) != -1){//判斷是否能讀取到字符,達(dá)到文件末尾時(shí)返回-1
System.out.print((char)data+"\t");//(char)fr.read()將字節(jié)碼轉(zhuǎn)換成字符
}
//2.read(char[] c)
char[] data = new char[5];//此時(shí)的數(shù)組大小固定拄踪,
int len ;
while((len = fr.read(data) )!= -1)
// //錯(cuò)誤寫法蝇恶,每次讀取的都是data的固定長(zhǎng)度字符,
// for (int i = 0; i < data.length; i++) {
// System.out.print(data[i]);//hello123lo 文件中是hello123惶桐;第一次hello撮弧,第二次時(shí)潘懊,將hello替換成123lo
// }
//正確寫法,每次遍歷讀取到的長(zhǎng)度len
for (int i = 0; i < len; i++) {
System.out.print(data[i]);//hello123
}
//3.read(char[] c,int offset,int count)
//方式二:
// //錯(cuò)誤寫法:原因和上述錯(cuò)誤一相同
// String str = new String(data);
// System.out.print(str);//hello123lo
//正確寫法
String str1 = new String(data,0,len);
System.out.print(str1);//hello123
字符流:對(duì)文件進(jìn)行輸出操作
/*
* 從內(nèi)存中寫入數(shù)據(jù)到硬盤文件里
* 說(shuō)明:在輸出操作中在輸出操作中
* 1.文件不存在時(shí)贿衍,不會(huì)報(bào)異常授舟,而是會(huì)自動(dòng)創(chuàng)建該文件
* 2.文件存在時(shí),new FileWriter(f,true);表示在原有文件后添加數(shù)據(jù)贸辈;
* new FileWriter(f,false);/new FileWriter(f);表示覆蓋原有數(shù)據(jù)释树,重新寫入
* */
@Test
public void test01() throws IOException {
//1.指明輸出的文件
File f = new File("Hi.txt");
//2.創(chuàng)建FileWriter用于文件輸出
FileWriter fw = new FileWriter(f);
//3.輸出內(nèi)容
fw.write("hello\n");
fw.write("world");
fw.close();
}
同時(shí)進(jìn)行字符的輸入和輸出操作
@Test
public void test02() {
File f1 = new File("Hi.txt");
File f2 = new File("HiHi.txt");
FileReader fr = null;
FileWriter fw = null;
try {
fr = new FileReader(f1);
fw = new FileWriter(f2);
int data;
char[] c = new char[5];
while((data = fr.read()) != -1){//data = fr.read(c)每次read字符的個(gè)數(shù)為c
fw.write(c,0,data);
}
}catch (IOException e) {
e.printStackTrace();
}
try {
if(fw != null)
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if(fr != null)
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
讀取時(shí)文本文件(txt、java擎淤、c++)使用字符流處理奢啥,對(duì)于非文本文件(圖片、音頻嘴拢、doc桩盲、ppt等)使用字節(jié)流處理;復(fù)制時(shí)席吴,文本文件可以通過字節(jié)流處理赌结,但非文本文件不能使用字符流處理
緩沖流:(字節(jié))對(duì)文件的讀取和寫入速度提高
@Test
public void test01() {
FileInputStream fis = null;
FileOutputStream fos = null;
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
//1.指明要操作的文件
File f1 = new File("2.PNG");
File f2 = new File("4.PNG");
//2.獲得文件的輸入和輸出流
//(1)造節(jié)點(diǎn)流
fis = new FileInputStream(f1);
fos = new FileOutputStream(f2);
//(2)造緩沖流
bis = new BufferedInputStream(fis);
bos = new BufferedOutputStream(fos);
//3.對(duì)文件進(jìn)行復(fù)制
int b;
byte[] bytes = new byte[1024];
while((b = bis.read(bytes)) != -1){//讀取的bytes
bos.write(bytes,0,b);
bos.flush();//刷新緩沖區(qū)
}
}catch(java.io.IOException e){
e.printStackTrace();
}finally{
//4.關(guān)流(緩沖流close操作中,內(nèi)部已經(jīng)對(duì)節(jié)點(diǎn)流close過孝冒,不需要再進(jìn)行關(guān)閉節(jié)點(diǎn)流)
if(bos != null) {
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(bis != null) {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
使用緩沖流(字符)輸出數(shù)據(jù)時(shí)柬姚,有兩種方式:char[] 和String
@Test
public void test01(){
BufferedReader br = null;
BufferedWriter bw = null;
try {
br = new BufferedReader(new FileReader(new File("1.txt")));
bw = new BufferedWriter(new FileWriter(new File("2.txt")));
// //方法一:使用char[]
// int i;
// char[] c = new char[1024];
// while ((i = br.read(c)) != -1){
// bw.write(c,0,i);
// }
//方法二:使用String
String data;
while((data = br.readLine()) != null) {//按行讀取
String str = new String(data);
//換行兩種方式
//一:
bw.write(str + "\n");
//二:
bw.write(str);//將String對(duì)象中的數(shù)據(jù)寫入文件,但此方法沒有進(jìn)行換行
bw.newLine();//進(jìn)行換行處理
}
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
對(duì)圖片加密操作
@Test
public void test01(){
try {
FileInputStream fis = new FileInputStream("5.PNG");
FileOutputStream fos = new FileOutputStream("6.PNG");
int b ;
byte[] bytes = new byte[10];
while ((b = fis.read(bytes)) != -1){
// //字節(jié)數(shù)組進(jìn)行修改
// //錯(cuò)誤:
// for(byte b1 : bytes){
// b1 = (byte)(b ^ 5);//次數(shù)是對(duì)新的b1變量修改了庄涡,但bytes并沒有改變
// }
//準(zhǔn)確
for (int i = 0; i < b; i++) {//循環(huán)的應(yīng)該是每次獲得的長(zhǎng)度
bytes[i] = (byte)(bytes[i] ^ 5);
}
fos.write(bytes,0,b);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
}
}
轉(zhuǎn)換流
1.InputStreamReader:將字節(jié)的輸入流轉(zhuǎn)換為字符的輸入流
OutputStreamWriter:將字符的輸出流轉(zhuǎn)換為字節(jié)的輸出流
2.作用:提供字節(jié)流和字符流之間的轉(zhuǎn)換
3.解碼:字節(jié)量承、字節(jié)數(shù)組----》字符數(shù)組、字符串
編碼:字符數(shù)組穴店、字符串----》字節(jié)宴合、字節(jié)數(shù)組
4.字符集
ASCII、ISO8859-1迹鹅、GB2312、GBK贞言、Unicode斜棚、utf-8(每8位傳輸)
ANSI編碼:即平臺(tái)默認(rèn)編碼;如:英文操作系統(tǒng)ISO-8859-1该窗,中文系GBK
實(shí)現(xiàn)字節(jié)流輸入流---》字符流輸入流
@Test
public void test01() throws IOException {
FileInputStream fis = new FileInputStream("1.txt");
//字節(jié)流---》字符流
InputStreamReader isr = new InputStreamReader(fis);//默認(rèn)使用該工具的字符集
InputStreamReader isr1 = new InputStreamReader(fis,"gbk");//自定義字符集
int i;
char[] c = new char[10];
while((i = isr1.read(c)) != -1){
System.out.println(c);
}
isr.close();
}
實(shí)現(xiàn)字節(jié)流輸入流---》字符流輸入流 和 字符輸出流-----》字節(jié)輸出流
@Test
public void test02() throws IOException {
FileInputStream fis = new FileInputStream("1.txt");
FileOutputStream fos = new FileOutputStream("3.txt");
InputStreamReader isr = new InputStreamReader(fis,"utf-8");//使用utf-8獲得輸入的字符流
OutputStreamWriter osr = new OutputStreamWriter(fos,"gbk");//使用gbk輸出字節(jié)流
int i;
char[] c = new char[10];
while((i = isr.read(c)) != -1){
osr.write(c,0,i);
}
osr.close();
isr.close();
fos.close();
fis.close();
}
獲取文本上每個(gè)字符出現(xiàn)的次數(shù)弟蚀,并進(jìn)行相加
@Test
public void test01() throws IOException {
//1.讀取的文件
FileReader fr = new FileReader("1.txt");
int r;
char[] c = new char[3];
//2.將讀取文件的字符和每個(gè)字符出現(xiàn)的次數(shù)存儲(chǔ)在HashMap中
HashMap<Character,Integer> hashMap = new HashMap<>();
while((r = fr.read(c)) != -1){
for (int i = 0; i < r; i++) {//循環(huán)時(shí)應(yīng)該根據(jù)讀取到的實(shí)際長(zhǎng)度判斷
//3.判斷該HashMap是否包含該字符,若包含酗失,則放入HashMap中义钉,出現(xiàn)次數(shù)+1,;不包含规肴,則放入HashMap中捶闸,出現(xiàn)數(shù)為1
if(hashMap.containsKey(c[i])){
hashMap.put(c[i],hashMap.get(c[i])+1);
}else{
hashMap.put(c[i],1);
}
}
}
fr.close();//必須將寫入流關(guān)閉夜畴,否則無(wú)法寫出數(shù)據(jù)
//4.將獲取的字符和出現(xiàn)的字符次數(shù)重新存入文件中
FileWriter fw = new FileWriter("char.txt");
Iterator<Map.Entry<Character, Integer>> iterator = hashMap.entrySet().iterator();
while(iterator.hasNext()){
Map.Entry<Character, Integer> next = iterator.next();
System.out.println(next.getKey() + "......" + next.getValue());
String str = new String(next.getKey() + "......" + next.getValue());
fw.write(str);
}
fw.close();
}
標(biāo)準(zhǔn)輸入輸出流
System.in(默認(rèn)從鍵盤輸入) System.out(默認(rèn)從控制臺(tái)輸出)
打印流
PrintStream PrintWriter
數(shù)據(jù)流:用于讀取或?qū)懭牖緮?shù)據(jù)類型、String類的變量或字符串
DataInputStream DataOutputStream
對(duì)象流ObjectOutputStream删壮、ObjectInputStream
1.作用:用于存儲(chǔ)和讀取基本數(shù)據(jù)類型或?qū)ο蟮奶幚砹魈盎妫饕强梢赃M(jìn)行序列化
2.序列化:即將內(nèi)存中的java對(duì)象保存到磁盤中或通過網(wǎng)絡(luò)傳輸出去(保存),好處在于可以將任何實(shí)現(xiàn)了Serializable接口的對(duì)象轉(zhuǎn)化為字節(jié)數(shù)據(jù)央碟,使其在保存和輸出時(shí)可以被還原
某個(gè)對(duì)象要實(shí)現(xiàn)序列化機(jī)制税灌,則必須實(shí)現(xiàn)Serializable或Externalizable接口,否則亿虽,會(huì)拋出NotSerializableException異常
3.反序列化:將磁盤中的文件對(duì)象還原為內(nèi)存中的一個(gè)java對(duì)象(讀攘獾印)
ObjectOutputStream、ObjectInputStream不能序列化static和transient修飾的成員變量
4.凡是Serializable接口的類都有一個(gè)表示序列化版本標(biāo)識(shí)符的靜態(tài)變量洛勉,用來(lái)表明類的不同版本間的兼容性粘秆;若沒有這個(gè)靜態(tài)變量,則類的實(shí)例變量進(jìn)行修改時(shí)坯认,serialVersionUID的值可能發(fā)生變化
即對(duì)象實(shí)現(xiàn)序列化的條件:
(1)需要實(shí)現(xiàn)接口
(2)對(duì)當(dāng)前類提供一個(gè)全局常量serialVersionUID
(3)出來(lái)當(dāng)前類需要SerialVersionUID接口外翻擒,還必須保證其內(nèi)部所有屬性也必須是可序列化的(默認(rèn)情況下,基本數(shù)據(jù)類型牛哺、String就可序列化)
例題:對(duì)象流對(duì)字符串進(jìn)行序列化和反序列操作
@Test
public void test01() throws IOException {
//序列化(OutputStream輸出流陋气,沒有文件會(huì)自動(dòng)創(chuàng)建)
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("2.dat"));
oos.writeObject("hhhh好的");
oos.close();
}
@Test
public void test02() throws IOException, ClassNotFoundException {
//反序列化(InputStream)
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("1.dat"));
Object o = ois.readObject();
String s = (String) o;
System.out.println(s);
ois.close();
}
serialVersionUID作用舉例
@Test
public void test01() throws IOException {
//1.對(duì)Person對(duì)象進(jìn)行序列化
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person1.txt"));
//沒有對(duì)Person序列化時(shí),java.io.NotSerializableException: com.vv.file.test.Person
oos.writeObject(new Person("xiaoli",14));
oos.close();
}
@Test
public void test02() throws IOException, ClassNotFoundException {
//1.對(duì)Person對(duì)象進(jìn)行反序列化
//java.io.InvalidClassException
//在未對(duì)該類賦予序列化常量引润,并對(duì)Person序列化后巩趁,又對(duì)該類修改,再執(zhí)行反序列化時(shí)淳附,沒有找到該類
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person1.txt"));
Object o = ois.readObject();
Person p = (Person) o;
System.out.println(p);
ois.close();
}
public class Person implements Serializable{
public static final long serialVersionUID = 123456789L;
public Account account;//Account類也必須是可序列化的
}
public class Account implements Serializable{
public static final long serialVersionUID = 456789321L;
}
RandomAccessFile
1.RandomAccessFile直接繼承與java.lang.Object類议慰,實(shí)現(xiàn)了DataInput和DataOutput
2.既可以作為輸入流,也可以作為輸出流
3.作為輸出流時(shí)奴曙,寫出的文件若不存在别凹,則創(chuàng)建;若存在洽糟,則會(huì)對(duì)原有文件內(nèi)容進(jìn)行覆蓋炉菲。(默認(rèn)情況下,從頭覆蓋)
//獲取操作的文件坤溃,并指定操作的方式可讀和可寫
RandomAccessFile rsf2 = new RandomAccessFile("1.txt","rw");
// //1."1.txt"中原內(nèi)容abcdef 寫入后ok1def
// rsf2.write("ok1".getBytes());
//// rsf2.close();
//
// //2.在指定位置寫入
// rsf2.seek(3);//原內(nèi)容ok1def 寫入后ok1ok1
// rsf2.write("ok1".getBytes());
//// rsf2.close();
//3.在指定位置寫入拍霜,但不會(huì)覆蓋原有數(shù)據(jù) 元數(shù)據(jù)ok1mnp 插入后數(shù)據(jù)ok1hhhmnp
StringBuilder sb = new StringBuilder((int) new File("1.txt").length());//指定文件的長(zhǎng)度
int i;
byte[] b = new byte[2];
rsf2.seek(3);//保存指針3后的數(shù)據(jù)到StringBuilder中
while ((i = rsf2.read(b)) != -1){
sb.append(new String(b, 0, i));
}
rsf2.seek(3);//指定位置插入
rsf2.write("hhh".getBytes());//指定位置插入的數(shù)據(jù)
System.out.println(rsf2.getFilePointer());
rsf2.write(sb.toString().getBytes());//將插入后的文件中追加剛才保存的數(shù)據(jù)
rsf2.close();
java NIO支持面向緩沖區(qū)的(IO是面向流的)即基于通道的IO操作
分為量部分:1.針對(duì)標(biāo)準(zhǔn)輸入輸出的NIO 2.針對(duì)網(wǎng)絡(luò)編程的NIO
java.nio.channels.Channel
jdk7出現(xiàn)Path、Paths薪介、Files