本章內容
1,file類
2,遞歸
3,IO流
4,字符流,字符緩衝區
5,裝飾者模式
6,字節流,字節流緩衝區
7,轉換流
8,其他流
9,編碼問題
一、file類
- 用來將文件或者文件夾封裝成對象
- 方便對文件與文件夾的屬性信息進行操作
- FILe能新建,刪除,重命名文件與目錄,但file不能訪問文件內容
File(String pathname)
可以把一個存在或者不存在的文件(文件目錄)封裝成一個對象
File(String parent, String child)
File(File parent, String child)
判斷:
* exists() 判斷文件或者文件夾是否存在
* isDirectory() 判斷文件對象是不是一個文件夾
* isFile() 判斷文件對象是不是一個文件
* isAbsolute() 判斷當前路徑是不是絕對路徑
* isHidden() 判斷文件是否隱藏
獲取類方法
* getAbsolutePath() 獲取文件的絕對路徑,返回路徑字符串
* getAbsoluteFile() 獲取文件的絕對路徑,返回File對象
* getParentFile() 獲取當前路徑的父路徑,以File對象的形式返回父路徑
* getParent() 獲取當前路徑的父路徑,以字符串形式返回父路徑
* getPath() 獲取當前路徑
* getName() 獲取當前文件或文件夾名稱
* lastModified() 獲取文件最後修改時間
* length() 獲取文件長度
* getTotalSpace() 獲取分區總大小
* renameTo(File newFile) 給文件改名字
* list() 以字符串形式返回當前路徑下的所有文件和文件夾
* listFiles() 以File對象的形式返回當前路徑下的所有文件和文件夾
package Test1;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import org.junit.Test;
public class Demo {
/*
* File(String pathname)
* 可以把一個存在或者不存在的文件(文件目錄)封裝成一個對象
*
* File(String parent, String child)
*File(File parent, String child)
*/
@Test
public void testConstructor(){
// /斜槓 \反斜槓
File f1 = new File("E:/practice/b.txt");//絕對路徑
File f2 = new File("E:/xxxx");
File f3 = new File("E:/practice","b.txt");
File parent = new File("E:/practice");
File f4 = new File(parent,"b.txt");
}
/*
* 創建和刪除文件:
*
* CreateNewFile() 指定的文件不存在,就創建文件返回true,否則false
* mkdir() 創建單級文件夾
* mkdirs() 創建多級文件夾
*
* delete() 刪除單個文件或者多個文件夾
*/
@Test
public void testCreateAndDelete() throws IOException{
File f = new File("F:/pp");
boolean flag = f.createNewFile();
System.out.println(flag);
// boolean mkidir = f.mkdirs();
// System.out.println(mkidir);
// boolean delete = f.delete();
// System.out.println(delete);
}
/*
* 判斷
* exists() 判斷文件或者文件夾是否存在
* isDirectoery()判斷文件對象是不是文件
* isFile() 判斷文件對象是不是一個文件
* isAbsolute();
* isHidden();
*
*
*/
@Test
public void testPanduan(){
File f1 = new File("F:/pp");
// boolean exists = f1.exists();
// System.out.println(exists);
// boolean directory = f1.isDirectory();
// System.out.println(directory);
// boolean file = f1.isFile();
// System.out.println(file);
boolean file = f1.isAbsolute();
boolean hidden = f1.isHidden();
System.out.println(file);
}
/*
* 獲取類方法
* getAbsoluteFile() 獲取文件的絕對路徑, 返回Flle對象
* getAbsolutePath() 獲取文件的絕對路徑,返回路徑字符串
* getParentFile() 獲取當前路徑的父路徑,以File對象的形式返回路徑
* getPath() 獲取當前路徑
* getName() 獲取當前文件夾或文件的名稱
* lastModified() 獲取文件最後修改時間
* length() 獲取文件的長度
* getTotalSpace() 獲取文件佔用磁盤的大小,分區的大小
*/
@Test
public void testGet(){
File f1 = new File("F:/pp");
File f2 = new File("F:/xcc");
File absoluteFile = f1.getAbsoluteFile();
String absolutePath = f1.getAbsolutePath();
File parentFile = f1.getParentFile();
String path = f1.getPath();
String name = f1.getName();
long lastModified = f2.lastModified();
long length = f1.length();
long totalSpace = f2.getTotalSpace();
boolean renameTo = f1.renameTo(f2);
System.out.println(renameTo);
Date d = new Date(lastModified);
System.out.println(d.toLocaleString());
System.err.println(totalSpace);
}
/*
* List() 以字符串形式返回當前路徑下的所有 文件和文件夾
* ListFiles 以File對象的形式返回當前路徑下的所有文件和文件夾
*
*
*/
@Test
public void testList(){
File f = new File("F:/K/A");
String[] list = f.list();
for(String str : list){
System.out.println(str);
}
System.out.println();
System.out.println();
File[] listFiles = f.listFiles();
for(File file : listFiles){
System.out.println(file.getName());
}
System.out.println();
System.out.println(listFiles.length);
}
}
2,遞歸
爲了求一個數值,不斷的調用本身。。具體內容前面有,這裏就不贅述了
例一:遞歸
package Digui;
public class Demo {
public static void main(String[] args) {
int result = jiecheng(5);
System.out.println(result);
}
public static int jiecheng(int n){
if(n == 1){
return 1;
}
else{
return n*jiecheng(n-1);
}
}
}
再來一個用遞歸算法思想來完成文件夾的遍歷與批量刪除
package Digui;
import java.io.File;
public class Demo2 {
public static void main(String[] args) {
// //列出一個文件夾下所有子文件夾以及子文件
// File file = new File("E://Desktop//chapter12//src//com//jp");
// showList(file);
//刪除一個目錄的過程是如何進行的?
File file = new File("G://a");
remove(file);
}
private static void remove(File file) {
if(file.isDirectory()){
File[] listFiles = file.listFiles();
for( File f : listFiles ){
if(f.isFile()){
f.delete();
}else if(f.isDirectory()){
remove(f);
}
}
}
file.delete();
}
//* isDirectory() 判斷文件對象是不是一個文件夾
// isFile() 判斷文件對象是不是一個文件
/*private static void showList(File file) {
if(file.isDirectory()){
File[] listFiles = file.listFiles();//以File對象的形式返回當前路徑下的所有文件和文件夾
for(File f : listFiles){
if(f.isFile()){
System.err.println("文件: " + f.getName() );
}else if(f.isDirectory()){
//這裏是正在循環的f的文件對象
showList(f);//這裏用的就是遞歸
}
}
}
System.out.println("文件夾: " + file.getName());
}*/
}
3.IO流
- IO流用來處理設備之間的數據傳輸
- java對對數據的操作是通過 流(系統資源)的方式
- java用於操作流的對象都在java.io包中
- 流按操作數據分爲兩種:字節流,和 字符流
- 流按流向分爲:輸入流(讀),輸出流(寫)
帶Stream後綴的都是字節
帶另一種的就是字符流。下面的圖爲老師上課講的圖,方便看點
4.字符流-創建文件
創建流對象,建立數據存放文件
--FileWriter fw =new FIleWriter("a.txt");
調用流對象的寫入方法,將數據寫入流
--fw.write("aafsa");
-關閉流資源,並將流中的數據清空到文件中。
--fw.close();
package Writer;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
public class FileWriterDemo {
public static void main(String[] args) throws IOException {
File file = new File("a.txt");
FileWriter fw = new FileWriter(file);
// fw.write(97);
// fw.flush();//刷新
// fw.close();//關閉流,自帶刷新功能
int i = 100;
System.out.println((char)i);
}
}
寫入異常的處理
package Writer;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
public class FileWriterDemo2 {
public static void main(String[] args) {
FileWriter fw = null;
try {
File file = new File("xx:/a.txt");
fw = new FileWriter(file,true);
fw.write(97);
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(fw != null){
fw.close();
}
} catch (IOException e) {
//保存到日誌
throw new RuntimeException("流關閉出門啦!!趕緊來處理");
}
}
}
}
字符流-讀取文件
- 建立一個流對象,和指定的文件數據關聯
- --FileReader fr = new FileReader("01.txt");
- 創建一個臨時存放數據的數組。
- --char[] ch = new char[1024];
- 調用流對象的讀取方法將流中的數據讀入到數組。
- --fr.read(ch);
\r\n代表回車鍵
讀的第一個例子:
package Reader;
import java.io.FileReader;
import java.io.IOException;
public class FileReaderDemo {
public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("a.txt");
// int read1 = fr.read();
// System.out.println(read1);
// int read2 = fr.read();
// System.out.println(read2);
// int read3 = fr.read();
// System.out.println(read3);
int len = 0;
while((len = fr.read()) != -1){
// \r\n代表回車鍵
System.out.println(len);
}
fr.close();
}
}
自定義緩衝區:
package Reader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
public class FileReaderDemo2 {
public static void main(String[] args) throws IOException {
FileReader fr = new FileReader(new File("a.txt"));
//臨時緩衝區
char[] c = new char[10];
// int len1 = fr.read(c);//將數據讀取到一個字符數組中
// System.out.println("長度:" + len1 + "---讀取的內容是:" + new String(c));
// int len2 = fr.read(c);
// System.out.println("長度:" + len2 + "---讀取的內容是:" + new String(c));
// int len3 = fr.read(c);
// System.out.println("長度:" + len3 + "---讀取的內容是:" + new String(c));
int len = 0;
while((len= fr.read(c)) != -1){
System.out.println(new String(c, 0, len));
}
}
}
字符流練習:比較正規的
package Example;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class CopyDoc1 {
public static void main(String[] args){
FileReader fr = null;
FileWriter fw = null;
try {
//源文件
File sourceFile = new File("F://a.txt");
//目標文件
File targetFile = new File("D://copy.doxc");
//建立讀取流的通道
fr = new FileReader(sourceFile);
//建立寫入流通道
fw = new FileWriter(targetFile);
//建立臨時緩衝區,以提高效率
char[] c = new char[1024];
//記錄讀取的字符個數
int len = 0;
while((len = fr.read(c)) != -1){
fw.write(c, 0, len);
fw.flush();//刷新
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(fr != null){
fr.close();
}
} catch (IOException e) {
throw new RuntimeException("讀取流關閉出問題啦");
}
try {
if(fw != null){
fw.close();
}
} catch (IOException e) {
throw new RuntimeException("寫入流關閉出問題啦");
}
}
}
}
- 字符流--緩衝區
- 緩衝區提高了對數據的讀寫效率
- 對應類:
- ---BufferedWriter
- ---BufferedReader
- 緩衝區要結合流纔可以使用。
- 在流的基礎上對流的功能進行了增強
package Buffer;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class BufferDemo2 {
public static void main(String[] args) throws IOException {
BufferedReader br = null;
BufferedWriter bw = null;
try {
br = new BufferedReader(new FileReader(new File("F://a.txt")));
bw = new BufferedWriter(new FileWriter(new File("D://nihao.txt")));
String line = null;
while((line = br.readLine()) != null){
bw.write(line);
bw.newLine();//換行
bw.flush();//刷新
}
} catch (IOException e) {
e.printStackTrace();
}finally {
if(br != null){
br.close();
}
if(bw != null){
bw.close();
}
}
}
}
5,裝飾者設計模式
- 對原有類進行了功能增強
- 它與繼承有什麼不同?
- 繼承:被增強的對象固定
- 被增強的內容也是固定的
- 裝飾者模式;被增強的對象是可以切換的
- 被增強的內容是固定的
- 動態代理(AOP) :被增強的對象可以切換
- 被增強的內容也是可以切換的
6,字節流
FileInputStream
FileOutputStream
複製一個mv到別的盤
package FileInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo {
public static void main(String[] args) throws IOException {
FileInputStream fis =null;
FileOutputStream fos = null;
try {
File sourceFile = new File("D://123.mp4");
File targetFile = new File("G://xcc.mp4");
fis = new FileInputStream(sourceFile);
fos = new FileOutputStream(targetFile);
byte[] b = new byte[1024];
int len = 0;
while((len = fis.read(b)) != -1){
fos.write(b, 0, len);
fos.flush();
}
} catch (IOException e) {
e.printStackTrace();
}finally{
if(fis != null){
try{
fis.close();
}catch(IOException e){
throw new RuntimeException("關閉讀取流出問題");
}
}
if(fos != null){
try{
fos.close();
}catch(IOException e){
throw new RuntimeException("關閉寫入流出問題");
}
}
}
}
}
字節流----緩衝區
- BufferedInputStream
- BufferedOutputStream
package Test1;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class BufferedDemo3 {
public static void main(String[] args) throws IOException {
FileInputStream fis = null;
FileOutputStream fos =null;
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
fis = new FileInputStream("E://Desktop//大二 上學期//123.mp4");
fos = new FileOutputStream("d://copy1.mp4");
bis = new BufferedInputStream(fis);
bos = new BufferedOutputStream(fos);
byte[] b = new byte[1024];
int len = 0;
while((len = bis.read(b)) != -1) {
bos.write(b, 0, len);
bos.flush();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch (IOException e){
e.printStackTrace();
}finally {
try {
if(fis != null){
fis.close();
}
} catch (IOException e) {
throw new RuntimeException("出問題啦");
}
try {
if(fos != null){
fos.close();
}
} catch (IOException e) {
throw new RuntimeException("出問題啦");
}
try {
if(bis != null){
bis.close();
}
} catch (IOException e) {
throw new RuntimeException("出問題啦");
}
try {
if(bos != null){
bos.close();
}
} catch (IOException e) {
throw new RuntimeException("出問題啦");
}
}
}
}
7,轉換流
- InputStreamReader , OutputStreamWriter
- 轉換流的由來
- --字符流與字節流之間的橋樑
- --方便了字符流與字節流之間的操作
- 轉換流的應用
- -字節流中的數據都是字符時,轉換字符流的操作更高效
- GBK讀中文的碼錶
package Trans;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
public class TransDemo {
public static void main(String[] args) throws IOException {
//FileInputStream fis = new FileInputStream("E://xx.txt");
// 需要轉換嗎?
//InputStreamReader isr = new InputStreamReader(fis, "gbk");
FileReader fr = new FileReader("G://xx.txt");
// 需要提高效率嗎?
BufferedReader br = new BufferedReader(fr);
FileOutputStream fos = new FileOutputStream("F://yy.txt");
OutputStreamWriter osw = new OutputStreamWriter(fos, "gbk");
BufferedWriter bw = new BufferedWriter(osw);
String line = null;
while ((line = br.readLine()) != null) {
bw.write(line);
bw.flush();
}
fr.close();
br.close();
fos.close();
osw.close();
bw.close();
}
}
8,標準輸入輸出流
- System.in 和 System.out分別代表了系統標準的輸入和輸出設備
- 默認輸入設備是鍵盤,輸出設備是顯示器
- System.in 的類型是 InputStream
- System.out 的類型是 PrintStream,其實OutoutStream 的子類
- 通過System 類的seth,setOut方法對默認設備進行改變。
- Public static void setln(InputStream in)
- public static void setOut(PrintStream out)
package SYs;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
public class SystemDemo {
public static void main(String[] args) throws IOException {
InputStream in = System.in;
// int read = in.read();
// System.out.println(read);
// int read1 = in.read();
// System.out.println(read1);// 13 \r
// int read2 = in.read();
// System.out.println(read2);// 10\n
// int len = 0;
// while((len = in.read()) != -1){
// System.out.println(len);
// }
InputStreamReader isr = new InputStreamReader(in);
BufferedReader br = new BufferedReader(isr);
PrintStream out = System.out;
OutputStreamWriter osw = new OutputStreamWriter(out);
BufferedWriter bw = new BufferedWriter(osw);
String line = null;
while((line = br.readLine()) != null ){
//System.out.println(line);
if("over".equals(line)){
break;
}
bw.write(line.toUpperCase());//大寫
bw.newLine();//換行
bw.flush();//刷新
}
in.close();
isr.close();
br.close();
out.close();
osw.close();
bw.close();
}
}
8、其他流
- 打印流
- ---printWriter 與 printStream
- 可以直接操作輸入流文件
- 序列流
- ---SequenceInputStream
- 對多個流進行合併
- 對象流
- --- ObjectInputStream與ObjectOutputStream
- 被操作的對象需要Serializable(標記接口)
打印流
package Pint;
import java.io.IOException;
import java.io.PrintStream;
import org.junit.Test;
public class PrintDemo {
@Test
public void testPrintDemo() throws IOException{
PrintStream ps = new PrintStream("preawer.txt");
ps.print(91);
ps.println();
ps.flush();
ps.close();
}
@Test
public void testPrintWriter(){
//字節流 ctrl + t 查看代碼的結構
PrintStream out = System.out;
// PrintWriter pw = new PrintWriter(out);
// pw.print('a');
// pw.flush();
// pw.close();
out.print("aaa");
}
}
對象流
package com.jp.obj;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import org.junit.Test;
public class ObjDemo {
@Test
public void testObjectInputStream() throws IOException, ClassNotFoundException{
ObjectInputStream in = new ObjectInputStream(new FileInputStream("zs.txt"));
//對象的反序列化
Object readObject = in.readObject();
Person p = (Person)readObject;
System.out.println(p.getName());
in.close();
}
@Test
public void testObjectOutputStream() throws IOException{
//對象的寫出流,寫入到磁盤上
ObjectOutputStream out= new ObjectOutputStream(new FileOutputStream("zs.txt"));
//對象序列化過程
out.writeObject(new Person("zs", 20));
out.flush();
out.close();
}
}
9、常見碼錶
編碼變的由來:
計算機智能識別二進制數據,早期由來是電信號,爲了方便應用計算機,讓它可以識別各個國家的文字,就將各個國家的文字用數學來表示,並一一對應,形成一張表,這就是編碼表
常見的編碼表如下
- 編碼: 字符串-----字節數組
- 解碼:字節數組---字符串
- 轉換流的編碼應用
- 可以將字符按指定編碼格式存儲
- 可以對文本數據按指定編碼格式來解讀
- 指定編碼表的動作由構造器來完成
package Example;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class CopyDoc1 {
public static void main(String[] args){
FileReader fr = null;
FileWriter fw = null;
try {
//源文件
File sourceFile = new File("F://a.txt");
//目標文件
File targetFile = new File("D://copy.doxc");
//建立讀取流的通道
fr = new FileReader(sourceFile);
//建立寫入流通道
fw = new FileWriter(targetFile);
//建立臨時緩衝區,以提高效率
char[] c = new char[1024];
//記錄讀取的字符個數
int len = 0;
while((len = fr.read(c)) != -1){
fw.write(c, 0, len);
fw.flush();//刷新
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(fr != null){
fr.close();
}
} catch (IOException e) {
throw new RuntimeException("讀取流關閉出問題啦");
}
try {
if(fw != null){
fw.close();
}
} catch (IOException e) {
throw new RuntimeException("寫入流關閉出問題啦");
}
}
}
}