輸入流與輸出流
在程序中所有的數據都是以流的方式進行傳輸或保存的,在流操作中存在有輸入流和輸出流的概念
操作流分類:
- 字節操作流(是在JDK 1.0的時候定義的):OutputStream、InputStream
- 字符操作流(是在JDK 1.1的時候定義的):Writer、Reader
流程:
1.如果要操作的是文件,那麼首先要通過File類對象找到一個要操作的文件路徑(路徑可能存在,也可能不存在,如果不存在要創建路徑)。
2.通過字節流或者字符流的子類爲字節流或字符流的對象實例化
3.執行讀/寫操作
4.一定要關閉操作的資源(close()),不管隨後代碼如何操作,資源永遠要關閉。
16.2.1 OutputStream字節輸出流
字節是(Byte)是進行I/O操作的基本數據單位,在程序進行字節數據輸出時可以使用java.io.OutputStream類完成,此類定義如下:
pubic abstract class OutputStream extends Object implements Closeable,Flushable{}
OutputStream字節輸出流
範例:使用OutputStream類實現內容輸出
package com.lxh.sixteenchapter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class JavaIODemo403 {
public static void main(String[] args) {
//1.文件路徑
File file=new File("E:"+File.separator+"lilei"+File.separator+"ff.txt");
if(!file.getParentFile().exists()) { //如果父目錄不存在
file.getParentFile().mkdirs(); //創建父路徑
}
OutputStream out=null;
//2.通過子類實例化
try {
out=new FileOutputStream(file);
String str="今天星期六";
out.write(str.getBytes()); //3.將字符串變爲字節數組
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally { //4.關流
if(out!=null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
執行結果
範例:文件內容追加
package com.lxh.sixteenchapter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class JavaIODemo403 {
public static void main(String[] args) {
//1.文件路徑
File file=new File("E:"+File.separator+"lilei"+File.separator+"ff.txt");
if(!file.getParentFile().exists()) { //如果父目錄不存在
file.getParentFile().mkdirs(); //創建父路徑
}
OutputStream out=null;
//2.通過子類實例化
try {
out=new FileOutputStream(file,true);
String str="今天星期六\r\n";
out.write(str.getBytes()); //3.將字符串變爲字節數組
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally { //4.關流
if(out!=null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
執行結果
16.2.2 InputStream字節輸入流(讀取)
此類結構定義:
public abstract class InputStream extends Object implements Closeable{}
InputStream字節輸入流
InputStream數據讀取操作
讀取單個字節
讀取多個字節
範例:使用InputStream類讀取文件內容
package com.lxh.sixteenchapter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
public class JavaIODemo405 {
public static void main(String[] args) {
//1.文件路徑
File file=new File("E:"+File.separator+"lilei"+File.separator+"ff.txt");
InputStream input=null;
if(file.exists()) {
try {
input=new FileInputStream(file); //2.子類實例化
byte data[]=new byte[1024]; //3.創建字節數組 ,用來存儲,數據讀取緩衝區
int len=input.read(data); //讀取數據,將數據讀取到緩衝區中,同時返回讀取的字節個數
System.out.println(new String(data,0,len)); //4.字節轉爲字符串
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if(input!=null) {
try {
input.close(); //5.關流
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}
執行結果
今天星期六今天星期六
今天星期六
今天星期六
今天星期六
今天星期六
今天星期六
範例:讀取全部內容
package cn.mldn.demo;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
public class JavaIODemo {
public static void main(String[] args) throws Exception {
File file = new File("D:" + File.separator + "hello" +
File.separator + "mldn.txt"); // 輸出文件路徑
if (file.exists()) { // 文件存在
InputStream input = new FileInputStream(file) ;// 文件輸入流
byte data [] = input.readAllBytes() ; // 讀取全部數據
System.out.println("【" + new String(data) + "】");
input.close(); // 關閉輸入流
}
}
}
16.2.3 Writer字符輸出流
Writer類定義
public abstract class Writer extends Object implements Closeable, Flushable, Appendable{}
writer類常用方法
範例:使用FileWriter類實現數據輸出
package com.lxh.sixteenchapter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
public class JavaIODemo407 {
public static void main(String[] args) {
//1.文件路徑
File file=new File("E:"+File.separator+"File"+File.separator+"lilei"+File.separator+"ll.txt");
if(!file.getParentFile().exists()) { //父目錄必須存在,不存在創建
file.getParentFile().mkdirs();
}
Writer writer=null;
try {
writer=new FileWriter(file); //2.子類實例化
//3.輸出字符串
writer.write("今天好好學習!");
writer.append("加油");
} catch (IOException e) {
e.printStackTrace();
}finally { //4.關流
if(writer!=null) {
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
執行結果
16.2.4 Reader字符輸入流
Reader定義
public abstract class Reader extends Object implements Closeable, Readable{}
Reader是實現字符輸入流的操作類,可以實現char數據類型的讀取
範例:文件內容讀取
package com.lxh.sixteenchapter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
public class JavaIODemo408 {
public static void main(String[] args) throws IOException {
//1.文件路徑
File file=new File("E:"+File.separator+"File"+File.separator+"lilei"+File.separator+"ll.txt");
Reader in=null;
if(file.exists()) {
//2.子類實例化
try {
in=new FileReader(file);
//3.緩衝區
char [] data=new char[1024];
//4.讀取數據
int len=in.read(data);
System.out.println(new String(data,0,len));
} catch (FileNotFoundException e) {
e.printStackTrace();
}finally {
in.close();//5.關流
}
}
}
}
執行結果
今天好好學習!加油
16.2.5 字節流與字符流區別
數據傳輸(或者將數據保存在磁盤)時所操作的數據依然爲字節數據,字符數據都是通過緩衝區來進行處理後得到的內容。
兩類操作最大的區別,就在於字符流使用了緩衝區(這樣更適合於中文數據的操作),而字節流是直接進行數據處理操作。所以當使用字符輸出流進行輸出時就必須使用Flushable接口中提供的flush()方法強制性刷新緩衝區中的內容,字符流如果不使用close()方法。否則數據將不會輸出。
範例:字符流輸出並強制刷新緩衝區
package com.lxh.sixteenchapter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
public class javaIODemo409 {
public static void main(String[] args) {
//1.文件路徑
File file=new File("E:"+File.separator+"File"+File.separator+"lilei"+File.separator+"ll.txt");
if(!file.getParentFile().exists()) { //父目錄必須存在,不存在創建
file.getParentFile().mkdirs();
}
try {
Writer writer=new FileWriter(file); //2.子類實例化
//3.輸出字符串
writer.write("今天好好學習!");
writer.append("加油");
writer.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
執行結果
16.2.6 轉換流
轉換流的設計目的是爲了解決字節流與字符流之間操縱類型的轉換,java.io包中提供有兩個轉換流:OutputStreamWriter、InputStreamReader
OutputStreamWriter類繼承結構
InputStreamReader類繼承結構
範例:實現OutputStream與Writer轉換
package com.lxh.sixteenchapter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
public class JavaIODemo411 {
public static void main(String[] args) {
File file=new File("E:"+File.separator+"File"+File.separator+"lilei"+File.separator+"ll.txt");
if(!file.getParentFile().exists()) { //父目錄必須存在,不存在創建
file.getParentFile().mkdirs();
}
OutputStream output=null;
Writer out =null;
try {
output=new FileOutputStream(file); //字節流
out =new OutputStreamWriter(output); //字節流轉字符流
out.write("早起早睡,身體好!");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
out.close();
output.close(); //倒着關流
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
執行結果
16.2.7 文件複製
package com.lxh.sixteenchapter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class JavaIODemo412 {
public static void main(String[] args) {
if(args.length!=2) {
System.out.println("命令執行錯誤,拷貝失敗!");
System.exit(1);
}
long start=System.currentTimeMillis();
FileUtil fu=new FileUtil(args[0],args[1]);
System.out.println(fu.copy()?"文件拷貝成功":"文件拷貝失敗");
long end=System.currentTimeMillis();
System.out.println("花費時間:"+(end-start));
}
}
class FileUtil{ //拷貝工具類
private File srcFile; //源文件路徑
private File desFile; //目標文件路徑
public FileUtil(File srcFile, File desFile) { //接收復制路徑
this.srcFile = srcFile; //保存源文件路徑
this.desFile = desFile; //保存目標文件路徑
}
public FileUtil(String src, String des) { //接收復制路徑
this(new File(src),new File(des)); //調用構造
}
public boolean copy() {
if(!srcFile.getParentFile().exists()) { //源文件必須存在
System.out.println("拷貝源文件不存在");
return false;
}
if(desFile.getParentFile().exists()) { //目標文件不存在,則需要創建
desFile.getParentFile().mkdirs();
}
byte data[] =new byte[1024]; //開闢一個拷貝緩衝區
InputStream in=null;
OutputStream out=null;
int len=0;
try {
in=new FileInputStream(this.srcFile);
out=new FileOutputStream(this.desFile);
while((len=in.read(data))!=-1) {
out.write(data,0,len);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if(out!=null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(in!=null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return true;
}
}
執行結果
文件拷貝成功
花費時間:136