Java IO流
什么是流?
概念:記憶體和存盤設備之間傳輸資料的通道,
資料借助流傳輸,
流分類:
- 按照方向:輸入流(將存盤設備中的內容讀入到記憶體中)和輸出流(將記憶體中的內容寫入到存盤設備中)
- 按照單位:位元組流(以位元組為單位,可以讀寫所有資料)和字符流(以字符為單位,只能讀取文本資料)
- 按照功能:節點流(具有實際傳輸資料的讀寫功能)和過濾流(在節點流的基礎之上增強功能)
位元組流
位元組流的父類(抽象類):
- InputStream:位元組輸入流:提供一些如read(),close()的方法
- OutputStream:位元組輸出流:提供一些如write(),close()的方法
檔案位元組流
- FileInputStream:檔案位元組輸入流,繼承位元組輸入流
- FileOutputStream:檔案位元組輸出流,繼承位元組輸入流
檔案位元組輸入流操作:
//創建FileInputStream并且指定檔案路徑
FileInputStream fis = new FileInputStream("d:\\aa.txt");
int data = https://www.cnblogs.com/rainaftersummert/p/0;
//read回傳的int,當等于-1表示讀完了,如果是字符回傳對應的asc碼
//一次讀取一個位元組
while ((data=fis.read())!=-1){
System.out.println((char) data);
}
/*
a
b
c
什么為一次讀取一個位元組的情況
當需要一次讀取多個位元組
//創建FileInputStream并且指定檔案路徑
FileInputStream fis = new FileInputStream("d:\\aa.txt");
//一次讀取多個個位元組
byte[] buf = new byte[3];
//本處read回傳實際讀取個數,讀完回傳-1,并且將讀取到的存盤在buf中
//因為陣列大小一次讀取三個
System.out.println(fis.read(buf));
System.out.println(new String(buf));
fis.close();
/*
3
abc
*/
//或者
FileInputStream fis = new FileInputStream("d:\\aa.txt");
byte[] buf = new byte[3];
int count=0;
while ((count=fis.read(buf))!=-1){
System.out.println(new String(buf,0,count));
}
fis.close();
/*
abc
def
g
本處只是例子,實際操作時緩沖區陣列不需要創建得太小,可以是1024以上
檔案位元組輸出流操作:
//創建檔案位元組輸出流,為true代表檔案已經存在時追加,false每次都會覆寫(默認)
FileOutputStream fos=new FileOutputStream("d://aa.txt",false);
fos.write(97);
fos.write('b');
fos.write('c');
//檔案中:abc
//要寫入字串:轉成byte陣列
String s = "helloworld";
fos.write(s.getBytes());
//檔案中:abchelloworld
實作復制操作:
FileInputStream fis = new FileInputStream("d:\\aa.txt");
FileOutputStream fos = new FileOutputStream("d:\\bb.txt");
byte[] buf = new byte[1024];
int count=0;
while ((count=fis.read(buf))!=-1){
fos.write(buf,0,count);
}
fis.close();
fos.close();
位元組緩沖流
- 緩沖流:BufferedInputStream/BufferedOutputStream
- 繼承了過濾流(FilterOutputStream/FilterInputStream),而過濾流又繼承了檔案位元組流
- 內置了快取區(8k)
- 作用:提高IO效率,減少訪問磁盤次數;資料存盤在快取區,flush是將緩沖區的內容寫入檔案中,也可以直接close,后面實作緩沖區的類類似
位元組輸入緩沖流:
// 創建BufferedInputStream,需要傳入一個底層流
FileInputStream fis = new FileInputStream("d:\\aa.txt");
BufferedInputStream bis = new BufferedInputStream(fis);
// 讀取:類似,但是這個有緩沖區效率更高
int data = https://www.cnblogs.com/rainaftersummert/p/0;
while ((data=bis.read())!=-1){
System.out.print((char)data);
}
//當然也可以和檔案位元組流一樣,直接再創建一個緩沖區實作,一模一樣但是因為內部緩沖區的存在效率更高
// 關閉這一個就行
bis.close();
//out:abchelloworld
位元組輸出緩沖流:
FileOutputStream fos = new FileOutputStream("d://bb.txt");
BufferedOutputStream bos = new BufferedOutputStream(fos);
//轉義符如換行等也可以寫入也可以
String s = "hello\r\n";
bos.write(s.getBytes());//這是寫入了緩沖區,沒有寫入檔案
bos.flush();//需要重繪才能從緩沖區真正寫入檔案
bos.close();//當然close時自動flush
物件流
- 物件流:ObjectOutputStream/ObjectInputStream
- 可以實作寫入或者讀取物件
- 增強了緩沖區功能
- 增強了讀寫8種基本資料型別和字串的功能,不只是能讀寫int和byte
- readObject()從流中讀取一個物件;writeObject(Object obj)向流中寫入一個物件
- 使用流傳輸物件的程序被稱為序列化(寫入)和反序列化(讀取)
- 繼承檔案位元組流,需要基于其才能創建
- 序列化和反序列化的物件類都必須實作Serializable介面(該介面本身沒有任何方法僅僅標志該類可以序列化),而且其中關聯的其他類也要實作該介面
- 可以在類中自定義生成常量private static final long serialVersionUID ,該常量為序列化版本號用來標識該類,即使是同一個類如果UID不同依舊被認為不是同一個類無法反序列化不同UID的類
- 使用transient修飾實作,表示該屬性不需要序列化(例如:private transient int age )
- 靜態屬性不能序列化
序列化:
public class Student implements Serializable {}
//main:
FileOutputStream fos = new FileOutputStream("d://aa.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
// 序列化
Student student = new Student();
oos.writeObject(student);
// oos.writeBoolean();寫入boolean
// oos.writeBytes("hellow");//寫入字串
// 其他基本型別也有相應的辦法寫入
oos.close();
反序列化:
FileInputStream fis = new FileInputStream("d://aa.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
//讀取存入的第一個物件
Student s = (Student)ois.readObject();
ois.close();
序列化、反序列化多個物件時可以使用集合:
//序列化
FileOutputStream fos = new FileOutputStream("d://aa.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
// 序列化
Student student = new Student();
Student student1 = new Student();
ArrayList<Student> arrayList = new ArrayList<>();
arrayList.add(student);
arrayList.add(student1);
oos.writeObject(arrayList);
oos.close();
//反序列化
FileInputStream fis = new FileInputStream("d://aa.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
ArrayList<Student> arrayList = (ArrayList<Student>) ois.readObject();
ois.close();
常見字符編碼
字符流
問題的引出:
FileInputStream fis = new FileInputStream("d://aa.txt");
int data = https://www.cnblogs.com/rainaftersummert/p/0;
while ((data=fis.read())!=-1){
System.out.println((char)data);
}
fis.close();
//上述代碼當我們讀取的檔案中為中文時得到亂碼,
//原因:我們是運用位元組流一個一個位元組讀取檔案,而本處的檔案編碼方式是utf-8(中文常見的編碼方式),每個中文字占3個位元組,當一個一個位元組讀取時出現亂碼
這種情況下我們需要字符流
字符流的父類(抽象類):
Reader(字符輸入流)和Writer(字符輸出流)
只能用于文本檔案
檔案字符流
- FileReader和FileWriter
- 父類是InputStreamReader和OutputStreamWriter,而這兩者的父類又是Reader和Writer
- 采用默認字符編碼
FileReader:
FileReader fr = new FileReader("d://aa.txt");
//單個字符的讀取
// int data = https://www.cnblogs.com/rainaftersummert/p/0;
// while ((data=fr.read())!=-1){//讀取一個字符
// System.out.println((char)data);
// }
//創建緩沖區讀取
//緩沖區為2字符
char[] buf = new char[2];
int count = 0;
while ((count = fr.read(buf))!=-1){
System.out.println(new String(buf,0,count));
}
fr.close();
/*out:
你好
呀
FileWriter:
FileWriter fw = new FileWriter("d://aa.txt");
fw.write("你好嗎");
fw.flush();
fw.close();
字符緩沖流
- 緩沖流:BufferedReader/BufferedWriter
- 高效讀寫
- 支持輸入換行符
- 可以一次寫一行、讀一行
- 可以指定緩沖區大小,也可以默認(8K)
- 新建需要基礎字符流(檔案字符流)
- 繼承Reader和Writer
讀取:
FileReader fr = new FileReader("d://aa.txt");
BufferedReader br = new BufferedReader(fr);
// 和上面其他類類似的方法不再重寫
// 特有的:讀一行,末尾回傳null
String s = null;
//一行一行的讀取
while ((s=br.readLine())!=null){
System.out.println(s);
}
br.close();
//out:你好呀
寫入:
FileWriter fw = new FileWriter("d:\\aa.txt");
BufferedWriter bw = new BufferedWriter(fw);
// 寫入
bw.write("好好學習");
// 寫入一個換行windows:\r\n linux:\n
bw.newLine();
bw.write(",天天向上");
bw.close();
/*檔案:
好好學習
,天天向上
列印流
-
PrintWriter:
- 支持print()/println(),支持寫入后換行
- 支持資料原樣列印
- 繼承Writer類
- 類似PrintStream,但是PrintWriter只能列印字符流,而PrintStream可以列印位元組流
PrintWriter pw = new PrintWriter("d://aa.txt"); // 列印并且換行 pw.println(97); pw.println(true); //列印 pw.print("a"); pw.print("b"); pw.close(); /*檔案中: 97 true ab
轉換流
- 也叫橋轉換流:InputStreamReader/OutputStreamWriter
- 可以將位元組流轉換為字符流
- 可設定字符的編碼方式
- 繼承字符流Reader/Writer
- 創建時需要基本的檔案字符流
InputStreamReader:
FileInputStream fis = new FileInputStream("d://aa.txt");
InputStreamReader isr = new InputStreamReader(fis,"utf-8");
int data=https://www.cnblogs.com/rainaftersummert/p/0;
//一個一個字符讀取
while ((data=isr.read())!=-1){
System.out.print((char)data);
}
isr.close();
OutputStreamWriter:
FileOutputStream fos = new FileOutputStream("d://aa.txt");
OutputStreamWriter osw = new OutputStreamWriter(fos,"gbk");
for(int i=0;i<10;i++){
osw.write("我愛中國\r\n");
osw.flush();
}
osw.close();
File類
- 概念:代表物理盤符中的一個檔案或者檔案夾
// 分隔符
System.out.println("路徑分割符"+File.pathSeparator);
System.out.println("名字分割符"+File.separator);
File file = new File("d://cc.txt");
// 判斷檔案是否存在
if(!file.exists()){
// 創建檔案
boolean b = file.createNewFile();
System.out.println("創建結果:"+b);
}
if(file.exists()) {
// 直接洗掉
System.out.println("洗掉結果" + file.delete());
//使用jvm退出時洗掉
file.deleteOnExit();
}
// 獲取檔案資訊
System.out.println("絕對路徑"+file.getAbsolutePath());
//看你創建時傳入的路徑
System.out.println("獲取路徑"+file.getPath());
// 獲取名稱
System.out.println("獲取名稱"+file.getName());
// 獲取父目錄
System.out.println("獲取父目錄"+file.getParent());
// 獲取檔案長度
System.out.println("獲取檔案長度"+file.length());
// 檔案創建時間
System.out.println("檔案創建時間"+new Date(file.lastModified()).toString());
// 判斷檔案是否可寫
System.out.println("是否可寫"+file.canWrite());
// 是否是檔案
System.out.println("是否是檔案"+file.isFile());
// 是否隱藏
System.out.println("是否隱藏"+file.isHidden());
/*
路徑分割符;
名字分割符\
創建結果:true
洗掉結果true
絕對路徑d:\cc.txt
獲取路徑d:\cc.txt
獲取名稱cc.txt
獲取父目錄d:\
獲取檔案長度0
檔案創建時間Thu Jan 01 08:00:00 CST 1970
是否可寫false
是否是檔案false
是否隱藏false
檔案夾操作:
File dir = new File("d://cc/aa");
// 判斷檔案是否存在
if(!dir.exists()){
// 創建檔案夾:只能創建單集目錄
// boolean b = dir.mkdir();
// 創建多級目錄
boolean b = dir.mkdirs();
System.out.println("創建結果:"+b);
}
if(dir.exists()) {
// 直接洗掉:最下層且必須為空目錄
System.out.println("洗掉結果" + dir.delete());
//使用jvm退出時洗掉,休眠結束后洗掉
dir.deleteOnExit();
Thread.sleep(5000);
}
// 獲取檔案資訊
System.out.println("絕對路徑"+dir.getAbsolutePath());
//看你創建時傳入的路徑
System.out.println("獲取路徑"+dir.getPath());
// 獲取名稱
System.out.println("獲取名稱"+dir.getName());
// 獲取父目錄
System.out.println("獲取父目錄"+dir.getParent());
// 檔案創建時間
System.out.println("檔案創建時間"+new Date(dir.lastModified()).toString());
// 判斷是否是檔案夾
System.out.println("是否可寫"+dir.isDirectory());
// 是否隱藏
System.out.println("是否隱藏"+dir.isHidden());
// 遍歷檔案夾
String[] file = dir.list();
FileFilter介面
-
public interface FileFIlter
- boolean accept(File pathname)
-
當呼叫File類的listFiles()方法時,支持傳入一個實作了FileFilter介面的實作類對檔案進行過濾,只有滿足條件的檔案才能出現在listFiles()回傳值中
-
實作過濾
File dir = new File("d://cc/aa");
File[] files= dir.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
//如果名字以.jpg結尾回傳,否則不回傳
if(pathname.getName().endsWith(".jpg")){
return true;
}
else{
return false;
}
}
});
遞回遍歷檔案夾(遞回洗掉檔案夾:先把檔案內刪空再洗掉檔案夾):
public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
listDir(new File("d://aa"));
}
public static void listDir(File dir){
File[] files = dir.listFiles();
if(files!=null && files.length>0){
for (File file : files) {
if(file.isDirectory()){
//遞回
listDir(file);
}
else {
System.out.println(file.getAbsolutePath());
}
}
}
}
Prorerties
-
屬性集合
-
特點:
- 存盤屬性名和屬性值
- 屬性名和屬性值都是字串型別
- 沒有泛型
- 繼承Hashtable集合,具體看集合那一章筆記
- 和流有關
// 創建集合
Properties properties = new Properties();
// 添加資料
properties.setProperty("username","zhangsan");
properties.setProperty("age","20");
System.out.println(properties.toString());
//遍歷
// 1.keySet遍歷
// properties.keySet();
// 2.entrySet遍歷
// 3.stringPropertyNames變數
Set<String> set = properties.stringPropertyNames();
for (String s : set) {
System.out.println(s+":"+properties.getProperty(s));
}
// 和流有關的辦法
// list方法
PrintWriter pw = new PrintWriter("d://aa.txt");
//將properties寫入該檔案
properties.list(pw);
pw.close();
//store方法保存寫入該檔案
FileOutputStream fos = new FileOutputStream("d://aa.txt");
properties.store(fos,"這是注釋");
fos.close();
/*
{age=20, username=zhangsan}
age:20
username:zhangsan
Properties properties1 = new Properties();
FileInputStream fis = new FileInputStream("d://aa.txt");
properties1.load(fis);
fis.close();
System.out.println(properties1.toString());
//{age=20, username=zhangsan}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/553193.html
標籤:Java
上一篇:小愛同學呼叫本地jar -巴法云
下一篇:返回列表