java.io包是負責整個IO編程的開發包,在這個開發包中包含有核心的5個類和1個接口
IO學習的關鍵:同一個方法根據不同的子類可能有不同的實現
一、File類
在整個java.io包裏面File是唯一一個與文件本身有關的處理類。例如:文件的創建、重命名等操作都屬於文件本身的操作,如果要想使用File類進行操作,那麼必須設置一個操作的路徑,所以如果要想設置File類的操作文件路徑,則可以使用如下構造:
。構造:public File(String pathname),要設置完整路徑;
。構造:public File(File parent, String child),設置父路徑與子路徑。
如果要進行文件的基礎操作,那麼應該使用如下的處理辦法:
。創建新文件:public boolean createNewFile() throws IOException;
。判斷路徑是否存在:public boolean exists();
。刪除文件:public boolean delete();
範例:File類的基本操作
package cn.file;
import java.io.File;
public class Test {
public static void main(String args[]) throws Exception{
File file = new File("E:"+ File.separator +"demo.txt") ;
if(file.exists()){
file.delete() ;
}else{
file.createNewFile() ;
}
}
}
範例:File類目錄操作
如果說現在給定的路徑中有相應的目錄存在,那麼這個時候靠createNewFile()方法是無法正常創建文件的,那麼要想在程序中進行目錄的創建,則需要如下的方法支持:
。取得父路徑:public File getParentFile() ;
。創建目錄:public boolean mkdirs() ;
package cn.file;
import java.io.File;
public class Test {
public static void main(String args[]) throws Exception{
File file = new File("E:" + File.separator + "test1" + File.separator +
"test2" + File.separator + "demo.txt") ;
if(!file.getParentFile().exists()){
file.getParentFile().mkdirs() ;
}
if(file.exists()){
file.delete() ;
}else{
file.createNewFile() ;
}
}
}
FIle類取得文件信息
所有的文件本身都有一些自己的保留信息。例如:文件的創建時間、文件的大小等。可以使用如下的辦法取得文件相關的信息。
。取得文件的大小:public long length(),返回的單位是字節
。取得的是否的路徑:public boolean isDirectory();
。取得的是否是文件:public boolean isFile();
。重命名:public boolean renameTo(File dest);
。最後一次修改時間:public long lastModified();
package cn.file;
import java.io.File;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
public class Test3 {
public static void main(String[] args) {
File file = new File("E:" + File.separator + "pic.jpg");
if (file.exists()) { //文件存在
if (file.isFile()) { //如果是文件
System.out.println("文件大小" + file.length() + "字節、"
+ (new BigDecimal(file.length() / (double) 1024 / 1024)
.divide(new BigDecimal(1), 2,
BigDecimal.ROUND_HALF_UP)) + "兆");
System.out.println("最後一次修改日期"+ new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS")
.format(new java.util.Date(file
.lastModified())));
}
}
}
}
二:字節流和字符流
如果需要針對文件的內容進行處理操作,則必須要使用兩類數據流:
。字節流:OutputStream InputStre;
。字符流:Writer Read;
字節流是直接進行操作,而字符流需要經過處理,所有保存在磁盤上或者網絡傳輸的數據都是字節,而所有的字節重新在內存之中整合在一起,就是字符。
但是不管使用的是字節流還是字符流,其中基本的操作流程都是類似的,以文件操作爲例子:
。通過File類設置一個要操作的文件路徑;
。通過字節流或字符流的子類爲父類對象實例化;
。進行數據的讀寫操作;
。關閉流;
2.1、字節輸出流:OutputStream
字節輸出流採用的是byte數據進行的操作處理,主要可以進行二進制數據的操作。如果要進行字節數據的傳輸操作使用OutputStream類完成,這個類的定義如下:
public abstract class OutputStream
extends Object
implements Closeable, Flushable
可以發現OutputStream這個抽象類同時實現了 Closeable 和 Flushable接口;
。 Closeable :表示的所有需要被關閉的資源接口,裏面只有一個close()方法,從JDK1.5開始;
|-從JDK1.7開始Closeable又多出了AutoCloseable接口;
。Flushable:表示刷新處理,JDK1.5後添加
在OutPutStream類裏面提供有3個write()方法,這3個方法定義如下:
。輸出整個字節數組的數據:public void write(byte[] b) throws IOException ;
。輸出部分字節數組的數據:public void write(byte[] b, int off, int len) throws IOException ;
。輸出單個字節:public abstract void write(int b) throws IOException ;
OutPutStream是一個抽象類,所以如果是抽象類則需要通過子類進行對象的實例化處理,既然要進行文件的處理,所以可以使用FileOutputStream子類爲OutputStream父類實例化構造方法:
。構造方法(創建新的):public FileOutputStream(File file) throws FileNotFoundException ;
。構造方法(追加):public FileOutputStream(File file, boolean append) throws FileNotFoundException ;
範例:使用OutputStream
package cn.file;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
public class Test4 {
public static void main(String[] args) throws Exception{
//通過File類設置要輸出的文件路徑
File file = new File("E:" + File.separator + "test1" + File.separator +
"test2" + File.separator + "demo.txt") ;
//判斷父目錄是否存在,不存在則創建
if(!file.getParentFile().exists()){ //不存在
file.getParentFile().mkdirs() ; //創建
}
//通過OutputStream爲子類FileOutputStream類實例化
OutputStream output = new FileOutputStream(file) ;
//定義要輸出的數據並且將其輸出
String msg = "Hello World!" ;
//將字符串變成字符數組
byte data[] = msg.getBytes() ;
//輸出
output.write(data) ;
//關閉流
output.close() ;
}
}
2.2字節輸入流:InputStrea
既然可以使用OutputStream實現了數據的輸出操作,那麼也同樣可以實現數據讀取操作,讀取的操作可以使用InputStream類完成,先來看看InputStream類的定義:
public abstract class InputStream
extends Object
implements Closeable
在InputStream類中提供3個讀取的操作方法:
。讀取數據:public int read(byte[] b) throws IOException ;
。。 |-向字節數組中讀取,返回讀取的個數,如果沒有數據了返回-1 ;
。讀取數據:public int read(byte[] b, int off, int len) throws IOException ;
。。|-向字節數組中讀取部分數據,返回的是讀取的數據數,如果沒有數據了返回-1 ;
。讀取數據:public abstract int read() throws IOException ;
。。|-讀取單個字節數據, 如果沒有數據了返回-1 ;
既然是通過文件讀取,那麼肯定是使用FileInputStream;
。構造:public FileInputStream(File file) throws FileNotFoundException ;
範例:實現數據的讀取:
package cn.file;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
public class Test5 {
public static void main(String[] args) throws Exception{
//通過File類設置要輸出的文件路徑
File file = new File("E:" + File.separator + "test1" + File.separator +
"test2" + File.separator + "demo.txt") ;
//判斷文件是否存在
//文件存在並且是一個文件
if(file.exists() && file.isFile()){
InputStream input = new FileInputStream(file) ;
byte data[] = new byte[1024] ;
//讀取到字節數組中
int len = input.read(data) ;
System.out.println(" " + new String(data, 0, len) + " ") ;
input.close() ;
}
}
}
2.3、字符輸出流
Writer是專門負責(char,String)輸出的操作,首先這個類定義如下:
public abstract class Writer
extends Object
implements Appendable, Closeable, Flushable
writer本身依舊是一個抽象類,所以如果要操作文件一定要使用FileWriter子類,而後在writer類裏面也提供有一組的輸出方法,其中最爲重要的一個是:public void write(String str) throws IOException ;
package cn.file;
import java.io.File;
import java.io.FileWriter;
import java.io.Writer;
public class Test6 {
public static void main(String[] args)throws Exception {
File file = new File("E:" + File.separator + "test1" + File.separator +
"test2" + File.separator + "demo.txt") ;
if(!file.getParentFile().exists()){
file.getParentFile().mkdirs() ;
}
Writer out = new FileWriter(file) ;
out.write("Hello World!") ;
out.close() ;
}
}
2.4、字符輸入流
Reader屬於字符輸入流的抽象類,可以使用FileReader實現文件的讀取操作,在Reader裏面如果要進行數據的讀取使用如下方法完成:public int read(char[] cbuf) throws IOException ;
範例:使用Reader實現數據讀取:
package cn.file;
import java.io.File;
import java.io.FileReader;
import java.io.Reader;
public class Test7 {
public static void main(String[] args)throws Exception {
File file = new File("E:" + File.separator + "test1" + File.separator +
"test2" + File.separator + "demo.txt") ;
if(file.exists() && file.isFile()){
char data[] = new char[1024] ;
Reader in = new FileReader(file) ;
int len = in.read(data) ;
System.out.println(new String(data,0,len));
in.close() ;
}
}
}
所有的流程和之前的inputStream一樣,除了數據類型不同。
2.5、字節流與字符流的區別
清楚了字節流和字符流的概念之後必須面對的問題在於:開發之中使用哪種數據流,以及2種數據流的區別是什麼?
一句話總結:如果描述中文的處理一定使用字符流,如果處理數據傳輸,那麼使用字節流。
在使用字節流進行處理的時候不會使用到內存處理,而是直接與原始數據產生交互。在使用字符流處理的時候如果沒有進行關閉處理,那麼所有的數據都只是會保存在緩衝區之中,而當進行關閉處理之後會強制性的將緩衝區的數據清空。如果現在使用字符流的時候不希望關閉,那麼也可以使用flush()強制清空:public abstract void flush() throws IOException ;
字符流的所有操作都需要經過內存處理後得來,正因爲如此,所以字符適合保存中文。像圖片,音樂,電影,文字都是字節描述的,所以如果要傳遞的圖片是二進制數據,必須使用字節流。