AssetBundle使用,卸載,校驗
633
2025-04-02
一、概念:IO流用來處理設備之間的數據傳輸
Java對數據的操作是通過流的方式
Java用于操作流的對象都在IO包中
流按操作數據分為兩種:字節流與字符流。
流按流向分為:輸入流,輸出流。
二、IO流常用基類
字節流的抽象基類:
? InputStream , OutputStream。
字符流的抽象基類:
? Reader , Writer。
注:由這四個類派生出來的子類名稱都是
以其父類名作為子類名的后綴。
? 如: InputStream的子類FileInputStream。
? 如: Reader的子類FileReader
三、字符流——創建文件
? 創建流對象,建立數據存放文件
? FileWriter fw = new FileWriter(“Test.txt”);
? 調用流對象的寫入方法,將數據寫入流
? fw.write(“text”);
? 關閉流資源,并將流中的數據清空到文件中。
? fw.close();
1、寫文件
例:package aaa;
import java.io.FileWriter;
import java.io.IOException;
public class FileWriterDemo {
public static void main(String[] args) throws IOException {
//創建一個可以往文件中寫入字符數據的字符輸出流對象。
/*
* 既然是往一個文件中寫入文字數據,那么在創建對象時,就必須明確該文件(用于存儲數據的目的地)。
* 如果文件不存在,則會自動創建。
* 如果文件存在,則會被覆蓋。
* 如果構造函數中加入true,可以實現對文件進行續寫!
*/
FileWriter fWriter = new FileWriter("D:demo.txt",true);
/*
* 調用Writer對象中的write(string)方法,寫入數據。
* 其實數據寫入到臨時存儲緩沖區中。
*/
fWriter.write("adfsadfsafa");
fWriter.flush();//進行刷新,將數據直接寫到目的地中。
fWriter.write("dtrdtrd");//關閉流,關閉資源。在關閉前會先調用flush刷新緩沖中的數據到目的地。
fWriter.close();
}
}
完整的寫法:
private static final String LINE_SEPARATOR = System.getProperty("line.separator");//換行
public static void main(String[] args) {
FileWriter fw = null;
try {
fw = new FileWriter("k:\demo.txt");
fw.write("abcde" + LINE_SEPARATOR + "hahaha");
} catch (IOException e) {
System.out.println(e.toString());
} finally {
if (fw != null)
try {
fw.close();
} catch (IOException e) {
// code....
throw new RuntimeException("關閉失敗");
}
}
}
四、字符流——讀取文件
建立一個流對象,將已存在的一個文件加載進
流。
? FileReader fr = new FileReader(“Test.txt”);
創建一個臨時存放數據的數組。
? char[] ch = new char[1024];
調用流對象的讀取方法將流中的數據讀入到數組
中。
? fr.read(ch);
2、讀文件:需求:讀取一個文本文件。將讀取到的字符打印到控制臺.
//第一種寫法
package cn.itcast.p3.io.filereader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class FileReaderDemo {
public static void main(String[] args) throws IOException {
//1,創建讀取字符數據的流對象。
/*
* 在創建讀取流對象時,必須要明確被讀取的文件。一定要確定該文件是存在的。
* 用一個讀取流關聯一個已存在文件。
*/
FileReader fr = new FileReader("demo.txt");
int ch = 0;
while((ch=fr.read())!=-1){
System.out.println((char)ch);
這兩種寫法的區別:第一種一次只能讀取一個字符,第二種寫法一次能讀取多個字符,減少循環。所以第二種寫法更有優勢。
}
fr.close();
}
}
//第二種寫法:
package cn.itcast.p3.io.filereader;
import java.io.FileReader;
import java.io.IOException;
public class FileReaderDemo2 {
public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("demo.txt");
/*
* 使用read(char[])讀取文本文件數據。
* 先創建字符數組。
*/
char[] buf = new char[1024];
int len = 0;
while((len=fr.read(buf))!=-1){
System.out.println(new String(buf,0,len));
}
fr.close();
}
}
完整代碼
public class FileWriterDemo {
public static void main(String[] args) throws IOException {
FileReader fr = null;
try {
fr = new FileReader("c:\\test.txt");
char[] buf = new char[1024];
int len = 0;
while ((len = fr.read(buf)) != -1) {
System.out.println(new String(buf, 0, len));
}
} catch (IOException e) {
System.out.println("read-Exception :" + e.toString());
} finally {
if (fr != null) {
try {
fr.close();
} catch (IOException e) {
System.out.println("close-Exception :" + e.toString());
}
}
}
}
}
注意:
定義文件路徑時,可以用“/”或者“\\”。
在創建一個文件時,如果目錄下有同名文
件將被覆蓋。
在讀取文件時,必須保證該文件已存在,
否則出異常。
練習:將D的文件復制到E盤
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
//練習:將D的文件復制到E盤
//第一種? 一個一個的讀
public class CopyText {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
FileReader fr = new FileReader("D:\\1.txt");
FileWriter fw = new FileWriter("e:\\2.txt");
int ch = 0;
while ((ch = fr.read()) != -1) {
fw.write(ch);
}
fr.close();
fw.close();
}
}
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
//第二種 一次讀多個放到數組里面
//練習:將D的文件復制到E盤
public class CopyText {
private static final int BUFFER_SIZE = 1024;
public static void main(String[] args) throws IOException {
FileReader fr = null;
FileWriter fw = null;
try {
fr = new FileReader("D:\\1.txt");
fw = new FileWriter("e:\\2.doc");
char[] buf=new char[BUFFER_SIZE];//緩沖區 創建一個臨時容器,用于緩存讀取到的字符
int len=0;
while((len=fr.read(buf))!=-1){fw.write(buf, 0, len);}
} catch (Exception e) {
throw new RuntimeException("讀寫失敗");
} finally {
if (fw != null) {
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fr != null) {
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
五、字符流的緩沖區
緩沖區的出現提高了對數據的讀寫效率
對應類: BufferWriter? BufferReader
緩沖區要結合流才可以使用,是在流的就出上對流的功能進行了增強。
1、BufferReader舉例:
import java.io.FileReader;
import java.io.BufferedReader;
import java.io.IOException;
public class CopyText {
public static void main(String[] args) throws IOException {
FileReader fr=new FileReader("D:\\1.txt");
BufferedReader bufr=new BufferedReader(fr);
String line=null;
while((line=bufr.readLine())!=null)
System.out.println(line);
bufr.close();
}
}
2、BufferedWriter寫入舉例:
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
public class BufferedWriterDemo {
private static final String LINE_SEPARATOR = System
.getProperty("line.separator");
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
FileWriter fw = new FileWriter("buf.txt");
//為了提高寫入效率,使用字符流的緩沖區,創建了一個字符寫入流的緩沖區對象,并額指定要緩沖的流對象相關聯
BufferedWriter bufw = new BufferedWriter(fw);
for (int i = 0; i < 4; i++) {
bufw.write("asdfghjk" + i);
bufw.newLine();
bufw.flush();
}
bufw.close();
}
}
練習:利用BufferedReader和BufferedWriter復制文件
import java.io.*;
public class CopyTextByBufTest {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
FileReader fr = new FileReader("buf.txt");
BufferedReader bufr = new BufferedReader(fr);
FileWriter fw = new FileWriter("buf_Copy.txt");
BufferedWriter bufw = new BufferedWriter(fw);
String line = null;
while ((line = bufr.readLine()) != null) {
bufw.write(line);
bufw.newLine();
bufw.flush();
}
bufw.close();
bufr.close();
}
}
六、裝飾者模式
對原有類進行了功能的改變,增強。
例:
public class PersonDemo {
public static void main(String[] args) {
Person p = new Person();
p.chiFan();
NewPerson p1 = new NewPerson(p);
p1.chiFan();
}
}
class Person {
void chiFan() {
System.out.println("吃飯");
}
}
// 這個類的出現是為了增強Person而出現的。
class NewPerson {
private Person p;
NewPerson(Person p) {
this.p = p;
}
public void chiFan() {
System.out.println("開胃酒");
p.chiFan();
System.out.println("甜點");
}
}
利用LineNumberReader裝飾類設置行號。
import java.io.*;
public class LineNumberReaderDemo {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
FileReader fr = new FileReader("buf.txt");
LineNumberReader lnr = new LineNumberReader(fr);
String line = null;
lnr.setLineNumber(100);
while ((line = lnr.readLine()) != null) {
System.out.println(lnr.getLineNumber() + ":" + line);
}
lnr.close();
}
}
七、字節流
基本操作與字符流相同,但是它不僅可以操作字符,還可以操作其他媒體文件
FileInputStream 讀取流 ,FileOutputStream 輸出流。
1、讀取流舉例:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.FileNotFoundException;
public class ByteStreamDemo {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
demo_read();
}
static void demo_read() throws IOException {
FileInputStream fis = new FileInputStream("IO.txt");
System.out.println(fis.available());
//第一種讀取方式
byte[] buf = new byte[fis.available()];
fis.read(buf);
System.out.println(new String(buf));
//第二種讀取方式,建議使用這種
byte[] buf1=new byte[1024];
int len=0;
while((len=fis.read(buf1))!=-1)
{
System.out.print(new String(buf1,0,len));
}
//第三種,一個字節的讀
/*???? int ch=0;
while((ch=fis.read())!=-1)
{
System.out.print((char)ch);
}*/
fis.close();
}
}
2、FileOutputStream 輸出流舉例
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.FileNotFoundException;
public class ByteStreamDemo {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
//demo_read();
demo_write();
}
public static void demo_write() throws IOException {
//1,創建字節輸出流對象。用于操作文件.如果沒有就創建新的文件
FileOutputStream fos = new FileOutputStream("bytedemo.txt");
//2,寫數據。直接寫入到了目的地中。
fos.write("abcdefg".getBytes());
fos.close();//關閉資源動作要完成。
}
}
八、字節流的緩沖區
同樣是提高了字節流的讀寫效率。
BufferedInputStream和BufferedOutputStream
幾種讀取文件的效率舉例:
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class CopyMp3Test {
public static void main(String[] args) throws IOException {
copy_4();
}
//???? 千萬不要用,效率沒有!
public static void copy_4() throws IOException {
FileInputStream fis = new FileInputStream("c:\\0.mp3");
FileOutputStream fos = new FileOutputStream("c:\\4.mp3");
int ch = 0;
while((ch =fis.read())!=-1){
fos.write(ch);
}
fos.close();
fis.close();
}
//不建議。
public static void copy_3() throws IOException {
FileInputStream fis = new FileInputStream("c:\\0.mp3");
FileOutputStream fos = new FileOutputStream("c:\\3.mp3");
byte[] buf = new byte[fis.available()];
fis.read(buf);
fos.write(buf);
fos.close();
fis.close();
}
public static void copy_2() throws IOException {
FileInputStream fis = new FileInputStream("c:\\0.mp3");
BufferedInputStream bufis = new BufferedInputStream(fis);
FileOutputStream fos = new FileOutputStream("c:\\2.mp3");
BufferedOutputStream bufos = new BufferedOutputStream(fos);
int ch = 0;
while((ch=bufis.read())!=-1){
bufos.write(ch);
}
bufos.close();
bufis.close();
}
public static void copy_1() throws IOException {
FileInputStream fis = new FileInputStream("c:\\0.mp3");
FileOutputStream fos = new FileOutputStream("c:\\1.mp3");
byte[] buf = new byte[1024];
int len = 0;
while((len=fis.read(buf))!=-1){
fos.write(buf,0,len);
}
fos.close();
fis.close();
}
}
九、轉換流
InputStreamReader :字節到字符的橋梁。解碼。
OutputStreamWriter:字符到字節的橋梁。編碼。
轉換流的由來:1、字符流與字節流之間的橋梁。2、方便了字符流與字節流之間的操作
轉換流的應用:字節流中的數據都是字符時,轉成字符流操作更高效。
例:獲取鍵盤輸入的字符
import java.io.IOException;
import java.io.InputStream;
public class ReadKey {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
StringBuilder sb = new StringBuilder();
InputStream in = System.in;
int ch = 0;
//read()方法是阻塞式方法
while ((ch = in.read()) != -1) {
if (ch == '\r')
continue;
if (ch == '\n') {
String temp = sb.toString();
if ("over".equals(temp))
break;
System.out.println(temp.toUpperCase());
sb.delete(0, sb.length());
} else {
sb.append((char) ch);
}
}
}
}
例2:利用轉換流實現讀取鍵盤的操作,一次讀取一行。
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
public class TransStreamDemo {
public static void main(String[] args) throws IOException {
InputStream in = System.in;//字節流
InputStreamReader isr = new InputStreamReader(in);//將字節轉成字符的橋梁。轉換流。
BufferedReader bufr = new BufferedReader(isr);//字符流
OutputStream out = System.out;
OutputStreamWriter osw = new OutputStreamWriter(out);
BufferedWriter bufw = new BufferedWriter(osw);
String line = null;
while ((line = bufr.readLine()) != null) {
if ("over".equals(line))
break;
bufw.write(line.toUpperCase());
bufw.newLine();
bufw.flush();
}
}
}
例2的簡化版:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class TransStreamDemo2 {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
BufferedReader bufr = new BufferedReader(new InputStreamReader(
System.in));
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(
System.out));
String line = null;
while ((line = bufr.readLine()) != null) {
if ("over".equals(line))
break;
bufw.write(line.toUpperCase());
bufw.newLine();
bufw.flush();
}
}
}
例3:將輸入的字符,存到文件里。
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class TransStreamDemo2 {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
BufferedReader bufr = new BufferedReader(new InputStreamReader(
System.in));
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("buf.txt")));
String line = null;
while ((line = bufr.readLine()) != null) {
if ("over".equals(line))
break;
bufw.write(line.toUpperCase());
bufw.newLine();
bufw.flush();
}
bufw.close();
}
}
例3:將文件中的字符讀取到控制臺
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class TransStreamDemo2 {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
BufferedReader bufr = new BufferedReader(new InputStreamReader(new FileInputStream("buf.txt")));
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));
String line = null;
while ((line = bufr.readLine()) != null) {
if ("over".equals(line))
break;
bufw.write(line.toUpperCase());
bufw.newLine();
bufw.flush();
}
bufw.close();
}
}
例4:將一個文件中的內容復制到另一個文件中
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class TransStreamDemo2 {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
BufferedReader bufr = new BufferedReader(new InputStreamReader(new FileInputStream("buf.txt")));
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("buf_Copy.txt")));
String line = null;
while ((line = bufr.readLine()) != null) {
if ("over".equals(line))
break;
bufw.write(line.toUpperCase());
bufw.newLine();
bufw.flush();
}
bufw.close();
}
}
九、字符編碼
字符流的出現為了方便操作字符。
更重要是的加入了編碼轉換。
通過子類轉換流來完成。
? InputStreamReader
? OutputStreamWriter
在兩個對象進行構造的時候可以加入字符
集。
常見的編碼表:
1、ASCII:美國標準信息交換碼。 用一個字節的7位可以表示。
2、ISO8859-1:拉丁碼表,歐洲碼表。用一個字節的8位表示。
3、GB2312:中國的中文編碼表。
4、GBK:中國的中文編碼表升級,融合了更多的中文文字符
號。
5、Unicode:國際標準碼,融合了多種文字。 所有文字都用兩個字節來表示,Java語言使用的就是unicode
7、UTF-8:最多用三個字節來表示一個字符。
轉換流的編碼應用:
1、可以將字符以指定編碼格式存儲。
2、可以對文本數據指定編碼格式來解讀。
3、指定編碼表的動作由構造函數完成。
字符編碼: 編碼:字符串→字節數組? 解碼:字節數組→字符串
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
public class TransStreamDemo3 {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
write_1();
writeText_2();
writeText_3();// UTF-8編碼寫入
readText_1();
readText_2();//用UTF-8編碼讀取GBK編碼的文件
}
public static void readText_2() throws IOException {
InputStreamReader isr = new InputStreamReader(new FileInputStream(
"gbk_1.txt"), "utf-8");
char[] buf = new char[10];
int len = isr.read(buf);
String str = new String(buf, 0, len);
System.out.println(str);
isr.close();
}
public static void readText_1() throws IOException {
FileReader fr = new FileReader("gbk_1.txt");
char[] buf = new char[10];
int len = fr.read(buf);
String str = new String(buf, 0, len);
System.out.println(str);
fr.close();
}
public static void writeText_3() throws IOException {
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("u8_1.txt"), "UTF-8");
osw.write("你好");
osw.close();
}
public static void writeText_2() throws IOException {
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(
"gbk_3.txt"), "GBK");
// 等同于FileWriter fw=new FileWriter("gbk_3.txt"); 系統默認是 GBK
/*
* 這兩句代碼的功能是等同的。 FileWriter:其實就是轉換流指定了本機默認碼表的體現。而且這個轉換流的子類對象,可以方便操作文本文件。
* 簡單說:操作文件的字節流+本機默認的編碼表。 這是按照默認碼表來操作文件的便捷類。
*
* 如果操作文本文件需要明確具體的編碼。FileWriter就不行了。必須用轉換流。
*/
osw.write("你好");
osw.close();
}
public static void write_1() throws IOException {
FileWriter fw = new FileWriter("gbk_1.txt");
fw.write("你好");
fw.close();
}
}
十、File類
1、用來將文件或者文件夾封裝成對象
2、方便對文件與文件夾的屬性信息進行操作。
3、File對象可以作為參數傳遞給流的構造函數。
4、了解File類中的常用方法。
例:初始化File類的幾種方式
import java.io.File;
public class FileDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
constructorDemo();
}
public static void constructorDemo()
{
File f1=new File("D:\\1.txt");
System.out.println(f1.exists());
File f2=new File("D:\\","1.txt");
System.out.println(f2.exists());
File f3=new File("D:\\");
File f4=new File(f3,"a.txt");
System.out.println(f4.exists());
File f5=new File("D:"+File.separator+"1.txt");
System.out.println(f5);
}
}
File類常用的方法舉例:
import java.io.File;
import java.io.IOException;
import java.text.DateFormat;
import java.util.Date;
public class FileMethodDemo {
public static void main(String[] args) {
/*
* File對象的常見方法。
*
* 1,獲取。 1.1 獲取文件名稱。 1.2 獲取文件路徑。 1.3 獲取文件大小。 1.4 獲取文件修改時間。
*
* 2,創建與刪除。
*
* 3,判斷。
*
* 4, 重命名
*/
getDemo();
// createAndDeleteDemo();
// isDemo();
// renameToDemo();
// listRootsDemo();
}
輸出結果:
parent:null
name:C:\Users\WH\Workspaces\MyEclipse Professional 2014\Test\IO.txt
path:IO.txt
len:8543
time:1470094643508
str_time:2016年8月2日 上午07時37分23秒
private static void getDemo() {
// TODO Auto-generated method stub
File file = new File("IO.txt");
String name = file.getName();
String absPath = file.getAbsolutePath();// 絕對路徑
String path = file.getPath();
long len = file.length();
long time = file.lastModified();// 最后修改時間
Date date = new Date(time);
DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG,
DateFormat.LONG);
String str_time = dateFormat.format(date);
System.out.println("parent:" + file.getParent());
System.out.println("name:" + absPath);
System.out.println("path:" + path);
System.out.println("len:" + len);
System.out.println("time:" + time);
System.out.println("str_time:" + str_time);
}
}
private static void createAndDeleteDemo() {
//創建單級文件夾
輸出結果:
false
true
true
File dir = new File("D:\\abc");
boolean b = dir.mkdir();
System.out.println(b);
System.out.println(dir.delete());
//創建多級文件夾
File dir1=new File("D:\\sds\\ds\\adsa\\sa\\as\\a");
dir1.mkdirs();
System.out.println(dir1.delete());//雖然輸出結果True,但只能刪除最底層的文件夾
}
public static void isDemo() throws IOException{
File f = new File("aaa");
輸出結果:
b=true
true
false
f.createNewFile();
boolean b = f.exists();
System.out.println("b="+b);
// 最好先判斷是否存在。
System.out.println(f.isFile());
System.out.println(f.isDirectory());
輸出結果:getFreeSpace:419413291008
getTotalSpace:429492695040
getUsableSpace:419413291008
C:\
D:\
E:\
H:\
}
public static void listRootsDemo() {
File file = new File("d:\\");
System.out.println("getFreeSpace:"+file.getFreeSpace());
System.out.println("getTotalSpace:"+file.getTotalSpace());
System.out.println("getUsableSpace:"+file.getUsableSpace());
File[] files? = File.listRoots();
for(File file1 : files){
System.out.println(file1);
}
}
public static void renameToDemo() {
File f1 = new File("c:\\9.mp3");
File f2 = new File("d:\\aa.mp3");
boolean b = f1.renameTo(f2);//將f1的文件重命名為f2的文件名
System.out.println("b="+b);
}
FileFilter應用舉例:
import java.io.File;
import java.io.FileFilter;
public class FilterByHidden implements FileFilter {
public boolean accept(File pathname) {
return !pathname.isHidden();
}
}
import java.io.File;
import java.io.FilenameFilter;
public class FilterByJava implements FilenameFilter {
@Override
public boolean accept(File dir, String name) {
System.out.println(dir+"---"+name);
return name.endsWith(".txt");
}
}
import java.io.File;
import java.io.FilenameFilter;
public class SuffixFilter implements FilenameFilter{
private String suffix ;
public SuffixFilter(String suffix) {
super();
this.suffix = suffix;
}
@Override
public boolean accept(File dir, String name) {
return name.endsWith(suffix);
}
}
import java.io.File;
public class FistListDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
listDemo();
listDemo_2();
listDemo_3();
listDemo_4();
}
/**
* 查找C下不是隱藏的文件
*/
public static void listDemo_3() {
File dir = new File("c:\\");
File[] files = dir.listFiles(new FilterByHidden());
for(File file : files){
System.out.println(file);
}
}
/**
* 查找D盤下所有的文件和文件夾
*/
public static void listDemo() {
/*
* 獲取當前目錄下的文件以及文件夾的名稱,包含隱藏文件。 調用list方法的File對象中封裝的必須是目錄。
* 否則會發生NullPointerException 如果訪問的系統級目錄也會發生空指針異常。
* 如果目錄存在但是沒有內容,會返回一個數組,但是長度為0.
*/
File file = new File("D:\\");
String[] names = file.list();
System.out.println(names.length);
for (String name : names) {
System.out.println(name);
}
}
/**
* 篩選出后綴為.txt的文件
*/
public static void listDemo_2() {
File dir = new File("D:\\");
String[] names = dir.list(new SuffixFilter(".txt"));
for (String name : names) {
System.out.println(name);
}
}
/**
* FileFilter 過濾文件:先遍歷,找符合條件的再放到數組中輸出出來
*/
public static void listDemo_4() {
File dir = new File("D:\\");
String[] names = dir.list(new FilterByJava());
for (String name : names) {
System.out.println(name);
}
}
}
十一、遞歸:函數自己調用自己。
注意:遞歸時一定要明確結束條件。
應用場景: 當某一功能要重復使用時。
注意:
* 1,遞歸一定明確條件。否則容易棧溢出。
* 2,注意一下遞歸的次數。
例:讀取文件夾下的所有文件
import java.io.File;
public class FileTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
File dir = new File("D:");
listAll(dir, 0);
}
public static void listAll(File dir, int level) {
System.out.println(getSpace(level) + dir.getName());
// 獲取指定目錄下當前的所有文件夾或者文件對象。
level++;
File[] files = dir.listFiles();
for (int x = 0; x < files.length; x++) {
if (files[x].isDirectory()) {
listAll(files[x], level);
} else
System.out.println(getSpace(level) + files[x].getName());
}
}
private static String getSpace(int level) {
StringBuilder sb = new StringBuilder();
sb.append("|--");
for (int x = 0; x < level; x++) {
sb.insert(0, "|? ");
}
return sb.toString();
}
}
例:遞歸刪除文件夾下所有的文件和文件夾
import java.io.File;
public class RemoveDirTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
File dir = new File("D:\\腳本復制\\ewwe");
dir.delete();
removeDir(dir);
}
public static void removeDir(File dir) {
File[] files = dir.listFiles();
for (File file : files) {
if (file.isDirectory()) {
removeDir(file);
} else {
System.out.println(file + ":" + file.delete());
}
}
System.out.println(dir+":"+dir.delete());
}
}
例:遞歸舉例,計算數的和
public class DiGuiDemo {
/**
* @param args
*/
public static void main(String[] args) {
/*
* 遞歸:
* 函數自身直接或者間接的調用到了自身。
* 一個功能在被重復使用,并每次使用時,參與運算的結果和上一次調用有關。
* 這時可以用遞歸來解決問題。
* 注意:
* 1,遞歸一定明確條件。否則容易棧溢出。
* 2,注意一下遞歸的次數。
*/
int sum = getSum(9000);
System.out.println(sum);
}
public static int getSum(int num){
int x = 9;
if(num==1)
return 1;
return num+getSum(num-1);
}
}
十二、Properties集合
特點:
1,該集合中的鍵和值都是字符串類型。
2,集合中的數據可以保存到流中,或者從流獲取。
通常該集合用于操作以鍵值對形式存在的配置文件。
例:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintStream;
import java.util.Properties;
import java.util.Set;
/*
* Map
* ??????? |--Hashtable
* ???????????????? |--Properties:
* Properties集合:
* 特點:
* 1,該集合中的鍵和值都是字符串類型。
* 2,集合中的數據可以保存到流中,或者從流獲取。
*
* 通常該集合用于操作以鍵值對形式存在的配置文件。
*/
public class PropertiesDemo {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
PropertiesUpDateAndAdd();
methodDemo_2();
methodDemo_3();
methodDemo_4();
PropertiesReadAndUpdate();
}
/**
* 對已有的配置文件中的信息進行修改。 思路:讀取這個文件。 并將這個文件中的鍵值數據存儲到集合中。 在通過集合對數據進行修改。
* 在通過流將修改后的數據存儲到文件中。
* @throws IOException
*/
public static void PropertiesReadAndUpdate() throws IOException {
File file = new File("info.txt");
if (!file.exists()) {
file.createNewFile();
}
FileReader fr = new FileReader(file);
// 創建集合存儲配置信息
Properties prop = new Properties();
// 將流中信息存儲到集合中。
prop.load(fr);
prop.setProperty("wangwu", "16");
FileWriter fw = new FileWriter(file);
prop.store(fw, "");
prop.list(System.out);
fw.close();
fr.close();
}
/**
* 讀取保存到本地的Properties文件
* @throws IOException
*/
public static void methodDemo_4() throws IOException {
Properties prop = new Properties();
// 集合中的數據來自于一個文件。
// 注意;必須要保證該文件中的數據是鍵值對。需要使用到讀取流。
FileInputStream fis = new FileInputStream("info.txt");
// load方法
prop.load(fis);
prop.list(System.out);
}
/**
* 集合中的字符串鍵值信息持久化存儲到文件中
* @throws IOException
*/
public static void methodDemo_3() throws IOException {
Properties prop = new Properties();
// 存儲元素。
prop.setProperty("zhangsan", "30");
prop.setProperty("lisi", "31");
prop.setProperty("wangwu", "36");
prop.setProperty("zhaoliu", "20");
// 想要將這些集合中的字符串鍵值信息持久化存儲到文件中。需要關聯輸出流。
FileOutputStream fos = new FileOutputStream("info.txt");
prop.store(fos, "info");
fos.close();
}
/**
* 演示Properties集合和流對象相結合的功能。
*/
public static void methodDemo_2() {
Properties prop = System.getProperties();
prop.list(System.out);
}
/**
* Properties集合的修改和增加
*/
public static void PropertiesUpDateAndAdd() {
Properties prop = new Properties();
// 存儲元素
prop.setProperty("張三", "30");
prop.setProperty("lisi", "31");
prop.setProperty("wangwu", "36");
prop.setProperty("zhaoliu", "20");
// 修改元素
prop.setProperty("wangwu", "26");
Set
for (String name : names) {
String value = prop.getProperty(name);
System.out.println(name + ":" + value);
}
}
}
練習:定義功能,獲取一個應用程序運行的次數,如果超過5次,給出使用次數已到請注冊的提示。并不要在運行程序。
思路:
1,應該有計數器。
每次程序啟動都需要計數一次,并且是在原有的次數上進行計數。
2,計數器就是一個變量。 突然冒出一想法,程序啟動時候進行計數,計數器必須存在于內存并進行運算。
可是程序一結束,計數器消失了。那么再次啟動該程序,計數器又重新被初始化了。
而我們需要多次啟動同一個應用程序,使用的是同一個計數器。
這就需要計數器的生命周期變長,從內存存儲到硬盤文件中。
3,如何使用這個計數器呢?
首先,程序啟動時,應該先讀取這個用于記錄計數器信息的配置文件。
獲取上一次計數器次數。 并進行試用次數的判斷。
其次,對該次數進行自增,并自增后的次數重新存儲到配置文件中。
4,文件中的信息該如何進行存儲并體現。
直接存儲次數值可以,但是不明確該數據的含義。 所以起名字就變得很重要。
這就有了名字和值的對應,所以可以使用鍵值對。
可是映射關系map集合搞定,又需要讀取硬盤上的數據,所以map+io = Properties.
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
public class PropertiesTest {
public static void main(String[] args) throws IOException {
getAppCount();
}
/**
* @throws IOException
*/
public static void getAppCount() throws IOException {
File conFile = new File("count.properties");
if (!conFile.exists()) {
conFile.createNewFile();
}
FileInputStream fis = new FileInputStream(conFile);
Properties prop = new Properties();
prop.load(fis);
String value = prop.getProperty("time");
int count = 0;
if (value != null) {
count = Integer.parseInt(value);
if (count >= 5) {
throw new RuntimeException("使用次數已到,請注冊,給錢!");
}
}
count++;
//將改變后的次數重新存儲到集合中
prop.setProperty("time", count+"");
FileOutputStream fos=new FileOutputStream(conFile);
prop.store(fos, "count");
fos.close();
fis.close();
}
}
練習: 獲取指定目錄下,指定擴展名的文件(包含子目錄中的)
這些文件的絕對路徑寫入到一個文本文件中。簡單說,就是建立一個指定擴展名的文件的列表。? 思路:
1,必須進行深度遍歷。
2,要在遍歷的過程中進行過濾。將符合條件的內容都存儲到容器中。
3,對容器中的內容進行遍歷并將絕對路徑寫入到文件中。
package Test23;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
File dir = new File("C:\\Users\\WH\\Workspaces\\MyEclipse Professional 2014\\Test");
FilenameFilter filter = new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.endsWith(".java");
}
};
List
getFiles(dir, filter, list);
File destFile = new File(dir, "javalist.txt");
write2File(list, destFile);
}
/**
* 對指定目錄中的內容進行深度遍歷,并按照指定過濾器,進行過濾, 將過濾后的內容存儲到指定容器List中。
* @param dir
* @param filter
* @param list
*/
public static void getFiles(File dir, FilenameFilter filter, List
File[] files = dir.listFiles();
for (File file : files) {
if (file.isDirectory()) {
// 遞歸啦!
getFiles(file, filter, list);
} else {
// 對遍歷到的文件進行過濾器的過濾。將符合條件File對象,存儲到List集合中。
if (filter.accept(dir, file.getName())) {
list.add(file);
}
}
}
}
public static void write2File(List
throws IOException {
BufferedWriter bufw = null;
try {
bufw = new BufferedWriter(new FileWriter(destFile));
for (File file : list) {
bufw.write(file.getAbsolutePath());
bufw.newLine();
bufw.flush();
}
}
finally {
if (bufw != null)
try {
bufw.close();
} catch (IOException e) {
throw new RuntimeException("關閉失敗");
}
}
}
}
總結:流的操作規律:
之所以要弄清楚這個規律,是因為流對象太多,開發時不知道用哪個對象合適。
想要知道開發時用到哪些對象。只要通過四個明確即可。
1,明確源和目的(匯)
源:InputStream? Reader
目的:OutputStream? Writer
2,明確數據是否是純文本數據。
源:是純文本:Reader
否:InputStream
目的:是純文本 Writer
否:OutputStream
到這里,就可以明確需求中具體要使用哪個體系。
3,明確具體的設備。
源設備:
硬盤:File
鍵盤:System.in
內存:數組
網絡:Socket流
目的設備:
硬盤:File
控制臺:System.out
內存:數組
網絡:Socket流
4,是否需要其他額外功能。
1,是否需要高效(緩沖區);
是,就加上buffer.
2,轉換。
需求1:復制一個文本文件。
1,明確源和目的。
源:InputStream Reader
目的:OutputStream? Writer
2,是否是純文本?
是!
源:Reader
目的:Writer
3,明確具體設備。
源:
硬盤:File
目的:
硬盤:File
FileReader fr = new FileReader("a.txt");
FileWriter fw = new FileWriter("b.txt");
4,需要額外功能嗎?
需要,需要高效。
BufferedReader bufr = new BufferedReader(new FileReader("a.txt"));
BufferedWriter bufw = new BufferedWriter(new FileWriter("b.txt"));
================================================
需求2:讀取鍵盤錄入信息,并寫入到一個文件中。
1,明確源和目的。
源:InputStream Reader
目的:OutputStream? Writer
2,是否是純文本呢?
是,
源:Reader
目的:Writer
3,明確設備
源:
鍵盤。System.in
目的:
硬盤。File
InputStream in = System.in;
FileWriter fw = new FileWriter("b.txt");
這樣做可以完成,但是麻煩。將讀取的字節數據轉成字符串。再由字符流操作。
4,需要額外功能嗎?
需要。轉換。??????? 將字節流轉成字符流。因為名確的源是Reader,這樣操作文本數據做便捷。
所以要將已有的字節流轉成字符流。使用字節-->字符 。InputStreamReader
InputStreamReader isr = new InputStreamReader(System.in);
FileWriter fw = new FileWriter("b.txt");
還需要功能嗎?
需要:想高效。
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufw = new BufferedWriter(new FileWriter("b.txt"));
===================================================
需求3:將一個文本文件數據顯示在控制臺上。
1,明確源和目的。
源:InputStream Reader
目的:OutputStream? Writer
2,是否是純文本呢?
是,
源:Reader
目的:Writer
3,明確具體設備
源:
硬盤:File
目的:
控制臺:System.out
FileReader fr = new FileReader("a.txt");
OutputStream out = System.out;//PrintStream
4,需要額外功能嗎?
需要,轉換。
FileReader fr= new FileReader("a.txt");
OutputStreamWriter osw = new OutputStreamWriter(System.out);
需要,高效。
BufferedReader bufr = new BufferedReader(new FileReader("a.txt"));
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));
================================================================
需求4:讀取鍵盤錄入數據,顯示在控制臺上。
1,明確源和目的。
源:InputStream Reader
目的:OutputStream? Writer
2,是否是純文本呢?
是,
源:Reader
目的:Writer
3,明確設備。
源:
鍵盤:System.in
目的:
控制臺:System.out
InputStream in = System.in;
OutputStream out = System.out;
4,明確額外功能?
需要轉換,因為都是字節流,但是操作的卻是文本數據。
所以使用字符流操作起來更為便捷。
InputStreamReader isr = new InputStreamReader(System.in);
OutputStreamWriter osw = new OutputStreamWriter(System.out);
為了將其高效。
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));
============================================================
5,將一個中文字符串數據按照指定的編碼表寫入到一個文本文件中.
1,目的。OutputStream,Writer
2,是純文本,Writer。
3,設備:硬盤File
FileWriter fw = new FileWriter("a.txt");
fw.write("你好");
注意:既然需求中已經明確了指定編碼表的動作。
那就不可以使用FileWriter,因為FileWriter內部是使用默認的本地碼表。
只能使用其父類。OutputStreamWriter.
OutputStreamWriter接收一個字節輸出流對象,既然是操作文件,那么該對象應該是FileOutputStream
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("a.txt"),charsetName);
需要高效嗎?
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("a.txt"),charsetName));
什么時候使用轉換流呢?
1,源或者目的對應的設備是字節流,但是操作的卻是文本數據,可以使用轉換作為橋梁。
提高對文本操作的便捷。
2,一旦操作文本涉及到具體的指定編碼表時,必須使用轉換流 。
十三、IO包中的其他類
打印流
? PrintWriter與PrintStream
? 可以直接操作輸入流和文件。
PrintStream:
1,提供了打印方法可以對多種數據類型值進行打印。并保持數據的表示形式。
2,它不拋IOException.
構造函數,接收三種類型的值:
* 1,字符串路徑。
* 2,File對象。
* 3,字節輸出流。
例:
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintStream;
public class PrintStreamDemo {
public static void main(String[] args) throws IOException {
PrintStream out = new PrintStream("print.txt");
//????????????? int by = read();
//????????????? write(by);
//????????????? out.write(610);//只寫最低8位,
//????????????? out.print(97);//將97先變成字符保持原樣將數據打印到目的地。
out.close();
}
}
PrintWriter:字符打印流。
構造函數參數:
1,字符串路徑。
2,File對象。
3,字節輸出流。
4,字符輸出流。
例:
import java.io.BufferedReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
public class PrintWriterDemo {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(new FileWriter("out.txt"),true);
String line =? null;
while((line=bufr.readLine())!=null){
if("over".equals(line))
break;
out.println(line.toUpperCase());
//?????????????????????? out.flush();
}
out.close();
bufr.close();
}
}
序列流
? SequenceInputStream
? 對多個流進行合并。
例:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.SequenceInputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Iterator;
public class SequenceInputStreamDemo {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
/*
* 需求:將1.txt 2.txt 3.txt文件中的數據合并到一個文件中。
*/
ArrayList
for(int x=1; x<=3; x++){
al.add(new FileInputStream(x+".txt"));
}
Enumeration
SequenceInputStream sis = new SequenceInputStream(en);
FileOutputStream fos = new FileOutputStream("1234.txt");
byte[] buf = new byte[1024];
int len = 0;
while((len=sis.read(buf))!=-1){
fos.write(buf,0,len);
}
fos.close();
sis.close();
}
}
切割文件舉例:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
public class SplitFileDemo {
private static final int SIZE = 1024 * 1024;
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
File file = new File("D:\\重慶測試數據.zip");
splitFile(file);
}
private static void splitFile(File file) throws IOException {
FileInputStream fis = new FileInputStream(file);
byte[] buf = new byte[SIZE];
FileOutputStream fos = null;
int len = 0;
int count = 1;
/*
* 切割文件時,必須記錄住被切割文件的名稱,以及切割出來碎片文件的個數。 以方便于合并。
* 這個信息為了進行描述,使用鍵值對的方式。用到了properties對象
*
*/
Properties prop = new Properties();
File dirFile = new File("D:\\partFiles");
if (!dirFile.exists())
dirFile.mkdir();
while ((len=fis.read(buf))!=-1) {
fos=new FileOutputStream(new File(dirFile,(count++)+".part"));
fos.write(buf,0,len);
fos.close();
}
prop.setProperty("partCount", count+"");
prop.setProperty("fileName", file.getName());
fos=new FileOutputStream(new File(dirFile,count+".properties"));
prop.store(fos, "Save file Info");
fos.close();fis.close();
}
}
將切割的文件合并,合并信息從配置文件中獲取:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.SequenceInputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Properties;
public class MergerFile {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
File dir = new File("D:\\partFiles");
mergeFile_2(dir);
}
public static void mergeFile_2(File dir) throws IOException {
// 獲取指定目錄下的配置文件對象。
File[] files = dir.listFiles(new SuffixFilter(".properties"));
if (files.length != 1)
throw new RuntimeException(dir + ",該目錄下沒有Properties擴展名的文件或者不唯一");
//記錄文件對象。
File conFile=files[0];
//獲取該文件中的信息
Properties properties=new Properties();
FileInputStream fis=new FileInputStream(conFile);
properties.load(fis);
String fileName=properties.getProperty("fileName");
int count=Integer.parseInt(properties.getProperty("partCount"));
//獲取該目錄下的所有碎片文件。
File[] partFiles=dir.listFiles(new SuffixFilter(".part"));
if (partFiles.length!=(count-1)){
throw new RuntimeException("碎片文件不符合要求,個數不對!應該"+count+"個");
}
ArrayList
for (int i = 0; i < partFiles.length; i++) {
a1.add(new FileInputStream(partFiles[i]));
}
Enumeration
SequenceInputStream sisStream=new SequenceInputStream(en);
FileOutputStream fos=new FileOutputStream(new File(dir,fileName));
byte[] buf=new byte[1024];
int len=0;
while((len=sisStream.read(buf))!=-1)
{
fos.write(buf,0,len);
}
fos.close();
sisStream.close();
}
}
操作對象
? ObjectInputStream與ObjectOutputStream
? 被操作的對象需要實現Serializable (標記接口);
Java 數據結構
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。