Java當中的IO流(中)
Java當中的IO流(中)
刪除目錄
import java.io.File;
public class Demo{
public static void main(String[] args){
// 目錄
File dir = new File("E:\\hello");
// 刪除目錄
System.out.println(dir.delete());
// removeDir(dir);
// 下方方法
}
}
如果目錄裡面有檔案,或者還有目錄,就無法刪除,會顯示為false
的,那麼就要從裡頭往外進行刪除,可以進行遞迴的方法.
進行刪除裡標頭檔案或資料夾
public static void removeDir(File dir){ // 使用listFiles()方法,檢視目錄下是否有檔案以及資料夾 File[] files = dir.listFiles(); // 如果沒有目錄 if(files.length==0){ dir.delete(); return; } if(files!=null){ for(File file : files){ // 進行遍歷files物件,判斷是否是目錄 if(file.isDirectory()){ // 進行刪除目錄 removeDir(file); }else{ // 進行刪除檔案 System.out.println(file+":"+file.delete()); } } } System.out.println(dir+":"+dir.delete()); }
對學生資訊進行儲存
建立學生類:
public class Student implements Comparable<Student>{ private String name; private int cn, en, ma; private int sum; public Student(String name, int cn, int en, intma){ super(); this.name = name; this.cn = cn; this.en = en; this.ma = ma; this.sum = cn + en + ma; } public Student(){ super(); } // compareTo @Override public int compareTo(Student o){ int temp = this.sum - o.sum; return temp==0 ? this.name.compareTo(o.name):temp; } @Override public int hashCode(){ final int prime = 31; int result = 1; result = prime + result + cn; result = prime + result + sum; return result; } public String getName(){ return name; } public void setName(String name){ this.name = name; } public void setCn(int cn){ this.cn = cn; } public int getCn(){ return cn; } public void setEn(int en){ this.en = en; } public int getMa(){ return ma; } public void setMa(int ma){ this.ma = ma; } public int getSum(){ return sum; } public void setSum(int sum){ this.sum = sum; } @Override public String toString(){ return "Student [name=" + name + ", sum=" + sum + "]"; } }
將學生的成績等按照分數排序:
將資訊儲存到檔案,就要使用IO
流,有很多學生就要儲存集合
// 簡書作者:達叔小生
public class Demo {
private static final String LINE_SEPARATOR = System.getProperty("line.separator");
public static void main(String[] args) throws IOException {
Set<Student> set = new TreeSet<Student>(Collections.reverseOrder());
set.add(new Student("da",12,34,55));
set.add(new Student("shu",23,44,53));
set.add(new Student("dashu",24,12,34));
// 建立目錄,對應目錄
File dir = new File("Student");
// 如果目錄不存在就建立
if(!dir.exists()){
dir.mkdir();
}
// 對應目錄下的檔案
File desFiles = new File(dir,"student_info.txt");
// 把資料寫入到檔案中
writeToFile(set,desFiles);
}
// 方法writeToFile(set,desFiles);
public static void writeToFile(Set<Student> set, File desFile ) throws IOException {
FileOutputStream fos = null;
try{
fos = new FileOutputStream(desFile);
// 遍歷物件
for(Student stu:set){
String info = stu.getName() + "\t" + stu.getSum() + LINE_SEPARATOR;
// 資料寫到檔案中
fos.write(info.getBytes());
}
}finally{
if(fos!=null){
try{
// 關閉資源
fos.close();
}catch(IOException e){
throw new RuntimeException("系統資源關閉失敗");
}
}
}
}
}
檔案清單,就是獲取目錄中的檔案,使用遞迴的方法,通過過濾器找到指定的所有檔案.
public class Demo{
private static final String LINE_SEPARATOR = SeparatorTool.LINE_SEPARATOR;
public static void main(String[] args) throws IOException {
// 明確一個目錄
File dir = new File("E:\\hello");
// 過濾器 建立類 FileFilterByJava
FileFilter filter = new FileFilterBySuffix(".java");
// 建立集合
List<File> list = new ArrayList<File>();
// 指定檔案清單
getFileList(dir,filter,list);
System.out.println(list.size());
File desFile = new File(dir,"javalist.txt");
writeToFile(list,desFile);
}
// 方法writeToFile
public static void writeToFile(List<File> list, File desFile) throws IOException {
FileOutputStream fos = null;
BufferedOutputStream bufos = null;
try{
fos=new FileOutputStream(destFile);
bufos=new BufferedOutputStream(fos);
for(File file : list){
String info = file.getAbsolutePath()+LINE_SEPARATOR
bufos.write(info.getBytes());
bufos.flush();
}
}finally{
if(bufos!=null){
try{
fos.close();
}catch(IOException e){
throw new RuntimeException("關閉失敗");
}
}
}
}
public static void getFileList(File dir, FileFilter filter, List<File> list){
// 獲取目錄下的子目錄
File[] files = dir.llistFiles();
// 過濾器
// 遍歷子目錄
for(File file : files){
// 進行判斷是否是目錄,如果是進行遞迴
if(file.isDirectory()){
// 進行遞迴
getFileList(file,filter,list);
}else{
// if(file.getName().endsWith(".java")){
if(filter.accept(file)){
list.add(file);
}
}
}
}
}
FileFilterByJava:
// 簡書作者:達叔小生
import java.io.File;
public class FileFilterBySuffix implements FileFilter {
private String suffix;
public FileFilterBySuffix(String suffix){
super();
this.suffix = suffix;
}
@Override
public boolean accept(File pathname) {
return pathname.getName().endsWith(suffix);
}
}
分隔符工具:
public class SeparatorTool {
private SeparatorTool(){
super();
}
public static final String LINE_SEPARATOR = System.getProperty("line.separator");
public static final String PATH_SEPARATOR = System.getProperty("path.separator");
public static final String FILE_SEPARATOR = System.getProperty("file.separator");
}
位元組流輸入和輸出,字元流,位元組流讀取字元
InputStream和OutputStream
FileInputStream和FileOutputStream
BufferedInputStream和BufferedOutputStream
// 簡書作者:達叔小生
public class CharStreamDemo{
public static void main(String[] args) throws IOException{
// writeCNText();
FileInputStream fis = new FileInputStream("dashu\\dashu.txt");
// 如何判斷? 一箇中文預設為兩個位元組
byte[] buff = new byte[1024];
int len = 0;
while( (len = fis.read(buff) != -1){
String str = new String(buff,0,len);
System.out.println(str);
}
fis.close();
}
public static void readCNText() throws FileNotFoundException{
FileInputStream fis = new FileInputStream("dashu\\dashu.txt");
}
public static void writeCNText() throws FileNotFoundException, IOException{
FileOutputStream fos = new FileOutputStream("dashu\\dashu.txt");
fos.write("簡書作者:達叔小生".getBytes());
fos.close();
}
}
編碼表
編碼表
ASCII
美國標準資訊交換碼
將生活中的一切用計算機的二進位制進行對應表示關係表
中文的,GB2312
,用兩個位元組表示,6到7千
GBK,
常用的中文碼錶,用兩位元組表示,2萬多
unicode
為國際標準碼錶,用兩個位元組表示
UTF-8
是基於unicode
的,用一個位元組儲存,更加標準.
// Java中
char c = 'a';
無論什麼都是兩個位元組
字元流
FileReader
解碼和編碼
字串
構造方法
方法 | 說明 |
---|---|
String() |
是初始化一個String 物件,表示一個空字元序列 |
String(byte[] byte) |
是使用平臺預設的字符集解(預設的字符集為gbk )碼指定的byte 的陣列 |
String(byte[] bytes, Charset charset) |
是通過使用指定的charset解碼指定的byte 陣列 |
FileInputStream
java.lang.Object
-> java.io.InputStream
-> java.io.FileInputStream
public class FileInputStream extends InputStream
從檔案系統中的某個檔案中獲取輸入位元組
如果要讀取字元流,就要用
FileReader.
位元組流是用FileInputStream
哦~
讀取字元檔案的 FileReader
java.io
類 FileReader
java.lang.Object
-> java.io.Reader
-> java.io.InputStreamReader
-> java.io.FileReader
public class FileReader extends InputStreamReader
此類的構造方法自帶預設的字符集編碼和位元組緩衝區,FileReader
用於讀取字元流.
// 簡書作者:達叔小生
// 版本開始為JDK1.1
FileInputStream -> InputStreamReader
FileReader
類是一個操作字元檔案的便捷類,有預設的字符集編碼和位元組緩衝區
FileReader
的構造方法:
方法 | 說明 |
---|---|
FileReader(File file) |
是用來給定從中讀取資料的File |
FileReader(FileDescriptor fd) |
是給定從中讀取資料的FileDescriptor |
FileReader(String fileName) |
是用來讀取資料的檔名 |
java.io.InputStreamReader
繼承的方法
close, getEncoding, read, ready
java.io.Reader
繼承的方法
mark, markSupported, read, reset, skip
基礎頂層
java.io
類 Reader
java.lang.Object
-> java.io.Reader
用於讀取字元流的抽象類
Reader
public abstract class Reader extends Object
implements Readable, Closeable
Reader
方法:
close()為關閉該流,並且釋放所有資源
mark(int readAheadLinmit)為標記流中的當前位置
markSupported()為判斷此流是否支援mark()
read()為讀取單個字元
read(char[] cbuf)為將字元讀入陣列
read(char[] sbuf, int off, int len)為將字元一部分讀入陣列
read(CharBuffer target)為試圖將字元讀入指定的字元緩衝區
ready()為判斷是否準備讀取此流
reset()為重置此流
skip(long n)為跳過字元
FileReader
程式碼:
FileReader fr = new FileReader("dashu\\dashu.txt");
int ch = fr.read();
System.out.println(ch);
fr.close();
int ch = 0;
int count = 0;
while((ch=fr.read()) != -1){
if(ch=='好'){
count++;
}
}
System.out.println("count =" + count);
字元流
FileWriter
java.io
類 Writer
java.lang.Object
-> java.io.Writer
public abstract class Writer extends Object
implements Appendable, Closeable, Flushable
寫入字元流的抽象類
FileWriter
FileWriter
是用來寫入字元檔案的便捷類
FileOutputStream -> OutputStreamWriter
public class FileWriter extends OutputStreamWriter
java.io 類 FileWriter
java.lang.Object
-> java.io.Writer
-> java.io.OutputStreamWriter
-> java.io.FileWriter
FileWriter
此類的構造方法是假定預設的字元編碼和預設的位元組緩衝區大小,FileWriter
是用於寫入字元流
FileWriter(File file)
FileWriter(File file, boolean append)
FileWriter(FileDescriptor fd)
FileWriter(String fileName)
FileWriter(String fileName, boolean append)
FileWriter
程式碼例子:
// 輸出流
import java.io.FileWriter;
public class FileWriterDemo{
public static void main(String[] args) throws IOException {
// FileWriter, 如果不存在建立一個
FileWriter fw = new FileWriter("dashu\\dashu.txt");
fw.write("簡書作者:達叔小生");
fw.flush();
fw.close();
}
}
flush()和close()
flush
為重新整理該流的緩衝,將流中緩衝區的資料重新整理到目的地,重新整理後的流可以使用
public abstract void flush() throws IOException
close
為關閉此流,關閉流之前要先重新整理,關閉資源用的,在關閉前會將緩衝區裡的資料重新整理到目的地,然後在關閉流,關閉了就不可以在使用了.
public void close(){
flush();
}
// 簡書作者:達叔小生
public abstract void close() throws IOException
異常:
java.io.IOException: Steam closed
OutputStreamWriter字元流
FileOutputStream -> OutputStreamWriter
FileWriter
和FileReader
都是有預設的字符集編碼,如GBK
字元流通過位元組流的橋樑類是
OutputStreamWriter類 -> java.io
可以用charset
將寫入流中的字元編碼為位元組
OutputStreamWriter
預設的字符集可以給定,否則為平臺預設
java.lang.Object
-> java.io.Writer
-> java.io.OutputStreamWriter
public class OutputStreamWriter extends Writer
效率:OutputStreamWriter -> BufferedWriter
Writer out = new BufferedWriter(new OutputStream(System.out));
OutputStreamWriter
方法:
OutputStreamWriter(OutputStream out)為使用預設的字元編碼
OutputStreamWriter(OutputStream out, Charset cs)為使用給定的字符集編碼
OutputStreamWriter
例子
// GBK UTF-8
public class Demo{
public static void main(String[] args) throws UnsupportedEncodingException, IOException {
// 有的人用的卻是UTF-8
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("dashu\\dashu.txt"), "utf-8" );
osw.write("簡書作者:達叔小生");
osw.close();
}
}
升級:
// 導致亂碼
public static void read() throws IOException{
FileReader fr = new FileReader("dashu\\dashu.txt");
// int ch = (char)fr.read();
char[] buff = new char[1024];
int len = fr.read(buff);
System.out.println(new String(buff,0,len);
fr.close();
}
字元流 InputStreamReader
java.io
類 InputStreamReader
java.lang.Object
-> java.io.Reader
-> java.io.InputStreamReader
public class InputStreamReader extends Reader
InputStreamReader
是用來指定編碼讀取中文的,是位元組流通向字元流的橋樑,可以用charset
讀取位元組並解碼為字元.
為了提高效率,可以BufferedReader
內包裝InputSteamReader
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
InputStreamReader例子:
構造方法:
InputStreamReader(InputStream in)
InputStreamReader(InputStream in, Charset cs)
InputStreamReader(InputStream in, CharsetDecoder dec)
InputStreamReader(InputStream in, String charsetName)
InputStreamReader
方法:
// 簡書作者:達叔小生
close()
getEncoding()
read()
read(char[] cbuf, int offset, int length)
ready()
public static void read() throws IOException {
// 建立InputStreamReader物件
InputStreamReader isr = new InputStreamReader(new FileInputStream("dashu\\dashu.txt"), "utf-8");
char[] buff = new char[1024];
int len = isr.read(buff);
System.out.println(new String(buff,0,len));
isr.close();
}
// InputStreamReader Console輸出
IO流-InputStreamReader和OutputStreamWriter 轉換流
// 簡書作者:達叔小生
InputStreamReader isr = new InputStreamReader(new FileInputStream("dashu\\dashu.txt"), "GBK");
char[] buff = new char[1024];
int len = isr.read(buff);
System.out.println(new String(buff,0,len));
isr.close();
類 InputStreamReader
的子類為FileReader
類 OutputStreamWriter
的子類為FileWriter
在上面有寫到字元流和位元組的橋樑為OutputStreamWriter
和InputStreamReader
,所以稱為字元轉換流
其字元轉換流原理為位元組流和編碼表
字元流通過位元組流的橋樑類是
OutputStreamWriter類 -> java.io
可以用charset將寫入流中的字元編碼為位元組
InputStreamReader
是用來指定編碼讀取中文的,是位元組流通向字元流的橋樑
FileWriter
和FileReader
是OutputStreamWriter
和InputStreamReader
的子類,只是用來操作字元檔案的便捷類,使用的是預設的編碼表.
如果要使用其他編碼時,要使用字元轉換流,反之操作的是檔案,且用預設的編碼時,就使用FileWriter
和FileReader.
不轉換:
FileReader fr = new FileReader("dashu.txt");
轉換流:
InputStreamReader isr = new InputStreamReader(new FileInputStream("dashu.txt"), "GBK");
要點
位元組到字元, 輸入流, 為InputStreamReader
, 是需要讀的,
讀的是要給人懂的得,才能讀,從看不懂的到看得懂的.
字元到位元組, 輸出流, 為OutputStreamWriter
, 是需要寫的,
寫的是從看懂的到看不懂.
用字元流複製文字檔案
public class CopyTextFileTest{
public static void main(String[] args) throws IOException {
copyTextFile();
}
public static void copyTextFile() throws IOException {
// 明確目標
FileReader fr = new FileReader("dashu.java");
// 明確目的
FileWriter fw = new FileWriter("hello\\hello.txt");
// 迴圈,讀字元
// int ch = 0;
// while((ch=fr.read()) != -1){
// fw.write(ch);
// }
// 效率高的
char[] buff = new char[1024];
int len = 0;
while((len=fr.read(buff) != -1){
fw.write(buff,0,len);
}
// 關閉資源
fw.close();
fr.close();
}
}
字元流緩衝區物件複製文字檔案
java.io
類 Reader
java.lang.Object
-> java.io.Reader
public abstract class Reader extends Object
implements Readable, Closeable
Reader
是用來讀取字元流的抽象類
// 簡書作者:達叔小生
BufferedReader
BufferedWriter
字元輸入流中讀取文字-BufferedReader
緩衝區是給流的
java.io
類 BufferedReader
java.lang.Object
-> java.io.Reader
-> java.io.BufferedReader
從字元輸入流中讀取文字,用來緩衝各個字元
public class BufferedReader extends Reader
FileReader
和InputStreamReader
BufferedReader in = new BufferedReader(new FileReader("dashu.txt"));
BufferedReader
的構造方法:
// 簡書作者:達叔小生
BufferedReader(Reader in)為預設大小
BufferedReader(Reader in, int sz)使用指定的大小
BufferedReader
的方法
方法 | 說明 |
---|---|
close() |
返回型別為void ,是用來關閉資源的 |
mark(int readAheadLimit) |
返回型別為void , 是用來標記流中的當前位置 |
markSupported() |
返回型別為boolean , 判斷此流是否支援mark() 操作 |
read() |
返回型別為int ,是用來讀取單個字元的 |
read(char[] cbuf, int off, int len) |
返回型別為Int ,是將字元陣列一部分讀入 |
readLine() |
返回型別為String , 是用來讀取一個文字的 |
ready() |
返回型別為boolean , 是用來判斷此流是否已經準備好 |
reset() |
返回為void , 是將流重置到最新的標記 |
skip(long n) |
返回型別為long , 是用來跳過字元的 |
將文字寫入到字元輸出流-BufferedWriter
java.io
類 BufferedWriter
java.lang.Object
-> java.io.Writer
-> java.io.BufferedWriter
public class BufferedWriter extends Writer
將文字寫入字元輸出流
FileWriter
和OutputStreamWriter
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("dashu.txt"));
BufferedWriter
的方法
方法 | 說明 |
---|---|
close() |
返回型別為void ,是用來關閉資源的 |
flush() |
返回型別為void ,是用來重新整理該流的緩衝 |
newLine() |
返回型別為void ,是用來寫入一個行分隔符 |
write(char[] cbuf, int off, int len) |
返回型別為void , 是用來寫入字元陣列的一部分 |
write(int c) |
返回型別為void ,是用來寫入單個字元 |
write(String s, int off, int len) |
返回型別為void , 寫入字串的一部分 |
字元流的緩衝區
// 簡書作者:達叔小生
public class CharStreamBufferedDemo{
public static void main(String[] args) throws IOException {
// BufferedReader和BufferedWriter 字元流緩衝區
// BufferedReader
// 從字元輸入流中讀取文字,用來緩衝各個字元
// BufferedWriter
// 將文字寫入到字元輸出流
copyTextByBuffer();
readText();
writeText();
}
public static void writeText() throws IOException {
BufferedWriter b = new BufferedWriter(new FileWriter("hello.java");
for(int x=1, x<=4; x++){
b.write(x);
b.newLine();
b.flush();
}
b.close();
}
public static void readText() throws IOException {
BufferedReader buffer = new BufferedReader(new FileReader("dashu.java");
// String line = buffer.readLine();
// System.out.println(line);
String line = null;
while((line=buffer.readLine()) != null){
System.out.println(line);
}
buffer.close();
}
public static void copyTextByBuffer(){
BufferedReader bufr = new BufferedRead(new FileReader("hello.txt"));
BufferedWriter bufw = new BufferedWriter(new FileWriter("hello\\dashu.txt"));
// 迴圈
String line = null;
while((lline = bufr.readLine() != null){
bufr.write(line);
bufr.newLine();
bufr.flush();
}
bufw.close();
bufr.close();
}
}
流是一連流串的字元,是資訊的通道,分輸出流和輸入流。
IO
的分類
第一種分:輸入流和輸出流。
第二種分:位元組流和字元流。
第三種分:節點流和處理流。
Java
中流的分類:
流的運動方向,可分為輸入流和輸出流兩種。
流的資料型別,可以分為位元組流和字元流。
輸入流類都是抽象類
InputStream
(位元組輸入流)或抽象類Reader
類(字元輸入流)的子類。
輸出流類都是抽象類
OutputStream
(位元組輸出流)或抽象類Writer
類(字元輸出流)的子類。
輸入流從檔案輸入為讀取,輸出流從檔案輸出為寫入資料。
輸入流
輸入流用於讀取資料,使用者可以從輸入流中讀取資料,但不能寫入資料。
輸入流讀取資料過程如下:
(1)開啟一個流。
如:FileInputStream inputFile=new FileInputStream("資料來源");
(2)從資訊源讀取資訊。
如:inputFile.read();
(3)關閉流。
如:inputFile.close();
輸出流
輸出流用於寫入資料。只能寫,不能讀。
寫資料到輸出流過程如下:
(1)開啟一個流。
如:FileOutputStream outFile=new FileOutputStream("資料來源");
(2)寫入資訊到目的地。
如:outFile.write(inputFile.read()):
(3)關閉流。
如:outFile.close();
字元流Reader
和Writer
位元組字元轉換流:
// 簡書作者:達叔小生
InputStreamReader
OutputStreamWriter
往後餘生,唯獨有你
簡書作者:達叔小生
90後帥氣小夥,良好的開發習慣;獨立思考的能力;主動並且善於溝通
簡書部落格: https://www.jianshu.com/u/c785ece603d1
結語
- 下面我將繼續對 其他知識 深入講解 ,有興趣可以繼續關注
- 小禮物走一走 or 點贊