流概述: 流是一組有序的資料序列,根據操作的類型,可分為輸入流和輸出流兩種。I/O(Input/Output,輸入/輸出)流提供了一條通道程式,可以使用這條通道把源中的位元組序列送到目的地。 輸入和輸出模式如下圖:
輸入/輸出流 所有輸出流淚都是抽象類InputStream(位元組輸入流)或抽象類Reader(字元輸入流)的子類,所有輸出流都是抽象類OutputStream(位元組輸出流)或抽象類Writer(字元輸出流)的子類。 字元流和位元組流的差別: 因為資料編碼的不同,而有了對字元進行高效操作的流對象。本質其實就是基于位元組流讀取時,去查了指定的碼表。 1.讀寫機關不同,位元組流以位元組為機關,字元流以字元為機關,根據碼表映射字元,一次可能讀多個位元組。 2.處理對象不同,位元組流能處理所有的類型的資料,而字元流自能處理字元類型的資料 3.位元組流在操作的時候不會用到緩沖區,是檔案本身的直接操作,而字元流在操作時會用到緩沖區。 總的來說,一般都選擇用位元組流,除了純文字的情況用字元流更加高效。 示例(将一些文字存儲到檔案中):
/*
思路:因為是純文字的,是以使用字元流
因為是寫入到檔案中,是以要建立一個輸出流對象,并且要明确一個目的地,如果目的地沒有
檔案那麼就自動建立一個,如果存在就覆寫
*/
import java.io.*;
class FileWriterDemo
{
public static void main(String[] args) throws IOException
{
FileWriter fw = new FileWriter("FileDemo.txt");//建立目的檔案
fw.write("abc");//用write方法寫入資料
fw.flush();//重新整理流資料,将資料寫入到目的地中
fw.close();//關閉流
}
}
如果建立檔案對象時,使用FileWriter fw = new FileWriter("FileDemo.txt",true) 那麼目的中的檔案就不會被覆寫,而是會續寫。
示例(将一個檔案中的資料在控制台顯示):
import java.io.*;
class FileReaderDemo
{
public static void main(String[] args) throws IOException
{
FileReader fr = new FileReader("FileDemo.txt");//選擇源檔案
int i = 0;
while((i=fr.read())!=-1)
{
System.out.println((char)i); //強轉之後輸出到控制台
}
fr.close();//關閉流
}
}
運作結果:
示例(複制一個文本檔案):
import java.io.*;
class CopyDemo
{
public static void main(String[] args) throws IOException
{
FileReader fr = new FileReader("FileDemo.txt"); //讀取一個已有的本文檔案并用字元流關聯
FileWriter fw = new FileWriter("FileDemoCopy.txt");//建立一個目的檔案用來存儲資料
int i = 0;
while((i=fr.read())!=-1)//循環讀寫
{
fw.write(i);
}
fw.close();
fr.close();
}
}
可以使用緩沖區提高讀寫效率。 緩沖區:就像是喝水,一滴一滴的喝想要解渴太久了,用水杯将水裝滿之後再喝就快多了。
import java.io.*;
public class BufferedWriterDemo{
public static void main(String[] args) throws IOException{
FileWriter fw = new FileWriter("buf.txt" );
//建立一個字元寫入流的緩沖區對象,并且指定與要被緩沖的流對象相關聯
BufferedWriter bufw = new BufferedWriter(fw);
for(int x = 1; x <= 4; x++){
//将資料先寫入到緩沖區中
bufw.write( "abcdef" + x);
//換行方法:newLine();
bufw.newLine();
bufw.flush();
}
//将資料刷目的地中
bufw.flush();
//關閉緩沖區
fw.close();
}
}
操作文本檔案用字元流更高效。不過位元組流的運用更廣。例如音頻視屏檔案都隻能用位元組流來操作。 示例(複制一個map3檔案,運用緩沖區更加高效):
import java.io.*;
class CopyMp3Demo
{
public static void main(String[] args) throws IOException
{
FileInputStream fis = new FileInputStream("1.map3"); //讀取已有檔案并用位元組流關聯
FileOutputStream fos = new FileOutputStream("2.mp3"); //建立一個目的存儲資料
byte[] buf = new byte[1024]; //建立緩沖區
int len = 0;
while((len=fis.read(buf))!=-1) //位元組不斷的寫入資料
{
fos.write(buf,0,len);
}
fis.close(); //關閉流
fos.close();
}
}
寫IO流的程式。首先應該明确幾點 1源和目的 源 InputStream 或者 Reader 目的 OutputStream 或者 Writer 2是否是純文字 純文字就用字元流 Reader 或者 Writer 不是純文字就用位元組流 InputStream 或者 OutputStream 另外還有: 判斷是否要加入緩沖區功能
關于轉換流:
InputStreamReader 位元組到字元,解碼 OutputStreamWriter 字元到位元組,編碼 為了友善字元流和位元組流之間的操作 當位元組流中的資料都是字元時,将位元組轉換成字元操作更高效 示例(将輸入的字母轉換成小寫的,并在控制台顯示):
import java.io.*;
class TranDemo
{
public static void main(String[] args) throws IOException
{
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("886".equals(line))
break;
bufw.write(line.toLowerCase());
bufw.newLine();
bufw.flush();
}
}
}
運作結果:
示例(将鍵盤輸入的資料存儲到檔案中): 分析: 源:鍵盤 System.in 目的:檔案 FIle 是否純文字: 是 是否要使用緩沖區:是 另外:将讀取的位元組流資料轉換成字元流操作更高效,是以要用到轉換流
import java.io.*;
class TranDemo
{
public static void main(String[] args) throws IOException
{
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("TranDemo.txt")));
String line = null;
while((line=bufr.readLine())!=null)
{
if("886".equals(line))
break;
bufw.write(line);
bufw.newLine();
bufw.flush();
}
}
}
FileWriter其實就是轉換流指定了本機預設碼表的展現,而且這個轉換流的子類對象,可以友善操作文本檔案。
簡單說:操作檔案的位元組流+本機預設的編碼表。
這是按照預設碼表來操作檔案的便捷類
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("d.txt"),"GBK");
如果操作文本檔案需要明确具體的碼表,FileWriter就不行了,必須用轉換流。
示例:
import java.io.*;
public class TransStreamDemo {
public static void main(String[] args) throws IOException {
writeText();
}
public static void writeText() throws IOException {
//下面這句代碼等同于FileWriter fw = new FileWriter("b.txt");
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("d.txt" ),"UTF-8" );
osw.write( "您好");
osw.close();
}
}
示例(将一個指定的txt檔案中的内容在控制台顯示):
import java.io.Exception
class TransStreamDemo {
public static void main(String[] args) throws IOException {
writeText();//調用方法
}
public static void writeText() throws IOException {
InputStreamReader isr = new InputStreamReader(new FileInputStream("demo.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(); //流關閉
}
}
示例(擷取目錄下的檔案和檔案的名稱):
import java.io.*;
class FileListDemo{
public static void main(String[] args) throws IOException {
listDemo();
}
public static void listDemo() throws IOException {
File file = new File("c:\\" );
//擷取目錄下的檔案以及檔案夾的名稱,包含隐藏檔案
//調用list方法的File對象中封裝的必須是目錄,否則會産生NullPointerException
//如果通路的是系統級目錄也會發生空指針異常
//如果目錄存在但是沒有内容,會傳回一個數組,但是長度為0
String[] names = file.list();
for(String name : names){
System.out.println(name);
}
}
}
示例(擷取D盤下java檔案夾中.java結尾的檔案):
import java.io.*;
class FileListDemo{
public static void main(String[] args){
listDemo(); //調用listDemo()方法
}
public static void listDemo(){
File dir = new File("d:\\java" ); //讀取指定目錄
String[] names = dir.list( new FilterByJava()); //擷取文檔名稱
for(String name : names){ //進階的for循環遞歸
System.out.println(name);
}
}
}
class FilterByJava implements FilenameFilter{
public boolean accept(File dir,String name){//判斷檔案名稱是否符合
return name.endsWith(".java" );
}
}
示例(将指定目錄下所有.java檔案拷貝到另一個目的中,并改為.txt格式):
import java.io.*;
import java.util.*;
class JavaDocDemo
/*
要求:編寫程式,将指定目錄下所有.java檔案拷貝到另一個目的中,并将擴充名改為.txt
思路 1.用遞歸的方法周遊指定目錄下的檔案
2.将以.java結尾的檔案名存入集合
3.将以.java結尾的檔案複制到指定目的并改名
*/
{
public static void main(String[] args) throws Exception
{
ArrayList<String> list = new ArrayList<String>();//定義集合用來存儲java檔案的名字
File src = new File("C:\\Users\\zlf\\Desktop\\java");//源檔案的路徑
File des = new File("C:\\Users");//目的檔案路徑
if(!des.exists())//判斷目的檔案是否存在,不存在建立
des.mkdirs();
fileTolist(src,list);//将源檔案中的Java檔案的名字存入到集合中
for(String fileName:list)
writeTofile(src,des,fileName);//将源檔案中的Java檔案存入到目的檔案夾中
}
//将源檔案中的Java檔案的名字存入到集合中
public static void fileTolist(File file,List<String>list)
{
File[] files = file.listFiles();//擷取源檔案夾中的檔案
for(File f:files)//周遊檔案并将Java檔案的名字存到集合中
{
list.add(f.getName());
}
}
//将源檔案中的Java檔案存入到目的檔案夾中
public static void writeTofile(File src,File des,String fileName)throws Exception
{
BufferedReader bufr = new BufferedReader(new FileReader(new File(src,fileName)));
BufferedWriter bufw = new BufferedWriter(new FileWriter(new File(des,fileName.replace(".java",".txt"))));
String line = null;
while((line=bufr.readLine())!=null)
{
bufw.write(line);
bufw.newLine();
bufw.flush();
}
bufw.close();
bufr.close();
}
}