概述
一、IO流,即Input Output流
1.IO流用來處理設備之間的數據傳輸
2.Java對數據的操作是通過流的形式
3.Java用於操作流的對象都存放於IO包中
4.流按操作數據分爲兩種:字節流和字符流
5.按流向分爲:輸入流和輸出流
6.字符流對象中融合了編碼表
(GB2312--->GBK 中文相對於二進制的映射表,ASCII 英文相對於二進制的映射表,unicode--->UTF-8
國際通用編碼表)
二、IO流常用基類
1、字符流的抽象基類
Reader Writer
2、字節流的抽象基類
InputStream OutputStream
由以上四個類派生出來的子類的名稱都是以其父類名作爲子類名的後
FileWriter類
一、功能定義
FileWriter
用於寫入字符流。此類的構造方法假定默認字符編碼和默認字節緩衝區大小都是可接受的。專門用於操作文件的Writer子類對象。二、方法
1.構造方法(根據給定的文件名構造一個 FileWriter 對象。)
FileWriter(String fileName)
創建一個FileWriter對象,該對象一被初始化就要指定文件名,而且該文件會被創建到指定目錄下,如果指定目錄下存在同名文件,那麼將會覆蓋已存在的文件,該步目的是要明確數據要存放的目的地。
2.寫入字符串
3.刷新流對象中緩衝的數據,將數據刷到目的地中。
void
flush()
FileWriter f=new FileWriter("demo.txt");
f.write("abdcd");
f.flush();
4.關閉此流,但要先刷新它。void
close()
IO異常處理方式
一、IO異常處理程序
import java.io.*;
class FileWriterDemo2
{
public static void main(String[] args)
{
FileWriter f=null;//爲了將f作用於整個函數,在外面建立引用,在try內初始化
try
{
f=new FileWriter("demo.txt");
f.write("abcd");
}
catch (IOException e)
{
System.out.println(e.toString());
}
finally
{
try
{
if(f!=null)//爲了防止創建文件失敗,而導致f爲空,在關閉文件前先做判斷
f.close();//文件出現異常後,一定要關閉,所以要放在finally中
}
catch (IOException e)
{
System.out.println(e.toString());
}
}
}
}
文件的續寫
一、FileWriter構造方法:根據給定的文件名以及指示是否附加寫入數據的 boolean 值來構造 FileWriter 對象。
FileWriter(String fileName, boolean append)
import java.io.*;
class FileWriterDemo3
{
public static void main(String[] args) throws IOException
{
FileWriter f=new FileWriter("demo.txt",true);
f.write("wqz\r\nwwb");//\n記事本不識別,\r\n記事本可以識別爲換行
f.close
}
}
文本文件讀取方式
一、FileReader類
FileReader
用於讀取字符流。此類的構造方法假定默認字符編碼和默認字節緩衝區大小都是適當的。
二、方法
1.構造方法(在給定從中讀取數據的文件名的情況下創建一個新FileReader。)
FileReader(String fileName)
如果文件不存在,會發生FileNotFoundException異常2. 讀取單個字符。
int
read()
import java.io.*;
class FileReaderDemo
{
public static void main(String[] args) throws IOException
{
FileReader fr=new FileReader("demo.txt");//demo.txt中存放着abc
int ch1=fr.read();
int ch2=fr.read();
int ch3=fr.read();
int ch4=fr.read();
System.out.println("ch1:"+(char)ch1);
System.out.println("ch2:"+(char)ch2);
System.out.println("ch3:"+(char)ch3);
System.out.println("ch4:"+(char)ch4);//如果已讀取到末尾,會返回-1
fr.close();
/*代碼簡化如下
int ch=0;
while((ch=fr.read())!=-1)
{
System.out.println((char)ch);
}
*/
}
}
3.將字符讀入數組。
int
read(char[] cbuf)
import java.io.*;
class FileReaderDemo2
{
public static void main(String[] args) throws IOException
{
<span style="white-space:pre"> </span>/*代碼簡化如下
FileReader fr=new FileReader("demo.txt");
int num=0;
char[] ch=new char[3];//一般定義1024的整數倍
while((num=fr.read(ch))!=-1)
{
System.out.println(new String(ch,0,num));
}
*/
char[] ch=new char[3];
int num1=fr.read(ch);
System.out.println("num1="+num1+"...ch="+new String(ch));//輸出3,abc
int num2=fr.read(ch);
System.out.println("num2="+num2+"...ch="+new String(ch));//輸出3,def
int num3=fr.read(ch);
System.out.println("num3="+num3+"...ch="+new String(ch));//輸出1,gef
int num4=fr.read(ch);
System.out.println("num4="+num4+"...ch="+new String(ch));//輸出-1,gef
fr.close();
}
}
單獨取最後一個g,可以使用
String(char[] value,
int offset, int count)構造方法,即分配一個新的 String
,它包含取自字符數組參數一個子數組的字符。
三、文本文件讀取練習(讀取一個.java文件,並打印在控制檯上)
拷貝文本文件
一、將C盤下的一個文本文件複製到D盤中
1.在D盤創建一個文件
2.定義讀取流和C盤文件完成關聯
3.通過不斷的讀寫完成對數據的存儲
4.關閉資源
第一種方式:(不建議)
import java.io.*;
class CopyText
{
public static void main(String[] args) throws IOException
{
FileWriter fw=new FileWriter("demo_destination.txt");//創建一個文件
FileReader fr=new FileReader("FileReaderDemo.java");//讀取流與要讀取的文件建立關係
int ch=0;
while((ch=fr.read())!=-1)//完成對數據的讀寫
{
fw.write(ch);
}
fw.close();//關閉資源
fr.close();
}
}
第二種方式:將數據批量讀取到內存中,一次性完成數據轉移import java.io.*;
class CopyText2
{
public static void main(String[] args)
{
FileWriter fw=null;
FileReader fr=null;
try
{
fw=new FileWriter("demo1_destination.txt");
fr=new FileReader("FileReaderDemo.java");
int num=0;
char[] ch=new char[1024];
while((num=fr.read(ch))!=-1)
{
fw.write(ch,0,num);
}
}
catch (IOException e)
{
throw new RuntimeException("數據讀寫出現錯誤");
}
finally
{
if(fr!=null)
try
{
fr.close();
}
catch (IOException e)
{
}
if(fw!=null)
try
{
fw.close();
}
catch (IOException e)
{
}
}
}
}
二、拷貝文本圖例BufferedWriter
***字符流緩衝區***
1.緩衝區的出現提高了對數據的讀寫效率
2.對應的類有
BufferedWriter BufferedReader
3.緩衝區要結合流纔可以使用
4.在流的基礎上對流的功能進行了加強
一、功能定義
1.將文本寫入字符輸出流,緩衝各個字符,從而提供單個字符、數組和字符串的高效寫入。
2.可以指定緩衝區的大小,或者接受默認的大小。在大多數情況下,默認值就足夠大了。二、方法
1.構造方法(創建一個使用默認大小輸出緩衝區的緩衝字符輸出流。)
BufferedWriter(Writer out)
2.寫入一個行分隔符。
void
newLine()
跟平臺無關,無論什麼平臺都是換行。import java.io.*;
class BufferedWriterDemo
{
public static void main(String[] args) throws IOException
{
FileWriter fw=new FileWriter("demo2.txt");
BufferedWriter bw=new BufferedWriter(fw);
/*
bf.write("abcde");
bf.flush();//只要用到緩衝區就要記得刷新
bf.close();
*/
for(int i=1;i<=5;i++)
{
bw.write("abcde"+i);
bw.newLine();
bw.flush();
}
//fw.close();無需此操作,因爲在關閉緩衝區的時候就是在關閉數據流
}
}
BufferedReader
一、功能定義
1.從字符輸入流中讀取文本,緩衝各個字符,從而實現字符、數組和行的高效讀取。
2.可以指定緩衝區的大小,或者可使用默認的大小。大多數情況下,默認值就足夠大了。
二、方法
1.構造方法(創建一個使用默認大小輸入緩衝區的緩衝字符輸入流。)
BufferedReader(Reader in)
2.讀取一個文本行。
import java.io.*;
class BufferedReaderDemo
{
public static void main(String[] args) throws IOException
{
FileReader fr=new FileReader("demo2.txt");
BufferedReader br=new BufferedReader(fr);
String line=null;
while((line=br.readLine())!=null)
{
System.out.println(line);
}
}
}
MyBufferedReader
一、概述
自定義一個類,這個類包含一個功能和readLine()一樣的方法,來模擬一下BufferedReader類
二、代碼
import java.io.*;
class MyBufferedReader
{
private FileReader fr=null;
MyBufferedReader(FileReader fr)
{
this.fr=fr;
}
public String myReadLine() throws IOException//定義一個一下可以讀一行數據的方法。拋出異常,誰調用,誰處理
{
//定義一個臨時容器,原BufferedReader封裝的是字符數組
//爲了演示方便,在這裏使用StringBuilder容器來代替,因爲最終要把數據編程字符串
StringBuilder sb=new StringBuilder();
int ch=0;
while((ch=fr.read())!=-1)
{
if(ch=='\r')
continue;
if(ch=='\n')
return sb.toString();
else
sb.append((char)ch);
}
if(sb.length()!=0)
return sb.toString();
return null;
}
public void myClose() throws IOException
{
fr.close();
}
}
class MyBufferedReaderDemo
{
public static void main(String[] args) throws IOException
{
FileReader fr=new FileReader("demo2.txt");
MyBufferedReader mbr=new MyBufferedReader(fr);
String s=null;
while((s=mbr.myReadLine())!=null)
{
System.out.println(s);
}
mbr.myClose();
}
}
裝飾設計模式
一、概述當想要對已有的對象進行功能增強時——可以自定義一個類,將已有對象傳入,基於已有對象的功能,並提供加強功能,那麼自定義的該類就被成爲裝飾類。比如上節中自定義的MyBufferedReader類。
二、代碼
class Person
{
public void eat()
{
System.out.println("喫飯");
}
}
class SuperPerson
{
private Person p=null;
SuperPerson(Person p)
{
this.p=p;
}
public void superEat()
{
System.out.println("開胃菜");
System.out.println("開胃酒");
p.eat();
System.out.println("飯後甜點");
}
}
class DecorationDemo
{
public static void main(String[] args)
{
Person p=new Person();
SuperPerson sp=new SuperPerson(p);
sp.superEat();
}
}
三、裝飾與集成的區別參見視頻19-07
LineNumberReader和MyLineNumberReader
一、功能定義
LineNumberReader是BufferedReader的子類,提供了getLineNumber()和setLineNumber()方法來獲取設置行號
二、方法
1.獲得當前行號。
int
getLineNumber()
2.設置當前行號。
void setLineNumber(int lineNumber)
import java.io.*;
class LineNumberReaderDemo
{
public static void main(String[] args) throws IOException
{
FileReader fr=new FileReader("demo2.txt");
LineNumberReader lnr=new LineNumberReader(fr);
String line=null;
lnr.setLineNumber(100);
while((line=lnr.readLine())!=null)
{
System.out.println(lnr.getLineNumber()+" "+line);
}
}
}
三、自定義MyLineNumberReader參見視頻19-10
IO練習
一、概述
有五個學生,每個學生有3門課的成績,
從鍵盤輸入以上數據,包括姓名,三門課的成績。
輸入的格式:如 zhangsan,30,40,50
並把學生的信息和計算出的總分數高低順序存放在磁盤文件"stud.txt"中
二、思想:
1.通過獲取鍵盤錄入一行數據,並將該行中的信息取出封裝成學生對象。
2.因爲學生很多,那麼久需要存儲,使用到集合。
3.因爲要對學生的總分排序,所以使用到TreeSet集合。
4.將集合的信息寫入到一個文件中。
從鍵盤輸入以上數據,包括姓名,三門課的成績。
輸入的格式:如 zhangsan,30,40,50
並把學生的信息和計算出的總分數高低順序存放在磁盤文件"stud.txt"中
二、思想:
1.通過獲取鍵盤錄入一行數據,並將該行中的信息取出封裝成學生對象。
2.因爲學生很多,那麼久需要存儲,使用到集合。
3.因爲要對學生的總分排序,所以使用到TreeSet集合。
4.將集合的信息寫入到一個文件中。
三、代碼
import java.util.*;
import java.io.*;
class Student implements Comparable<Student>
{
private String name;
private int en,cn,ma;
private int sum;
Student(String name,int en,int cn,int ma)
{
this.name=name;
this.en=en;
this.cn=cn;
this.ma=ma;
sum=en+cn+ma;
}
public String getSum()
{
return this.name;
}
public int compareTo(Student stu)
{
if(this.sum==stu.sum)//爲什麼可以stu.sum而不報錯?sum不是私有變量嗎?why?
return this.name.compareTo(stu.name);
return this.sum-stu.sum;
}
public int hashCode()
{
return name.hashCode()+sum*36;
}
public boolean equals(Object obj)
{
if(obj instanceof Student)
return false;
Student s=(Student)obj;
return s.name.equals(this.name) && s.sum==this.sum;
}
public String toString()
{
return "student"+"["+name+","+ma+","+en+","+cn+","+sum+"]";
}
}
class StudentTool
{
public static Set<Student> getStudents() throws IOException
{
Set<Student> set=new TreeSet<Student>(Collections.reverseOrder());
BufferedReader bufr=
new BufferedReader(new InputStreamReader(System.in));
String line=null;
while((line=bufr.readLine())!=null)
{
if("over".equals(line))
break;
String[] info=line.split(",");
Student s=new Student(info[0],Integer.parseInt(info[1]),Integer.parseInt(info[2]),Integer.parseInt(info[3]));
set.add(s);
}
bufr.close();
return set;
}
public static void write2File(Set<Student> stu) throws IOException
{
BufferedWriter bw=new BufferedWriter(new FileWriter("student.txt"));
for(Student s : stu)
{
bw.write(s.toString()+"\t");
bw.write(s.getSum());
bw.newLine();
bw.flush();
}
bw.close();
}
}
class StudentsIOTest
{
public static void main(String[] args) throws IOException
{
Set<Student> ts=StudentTool.getStudents();
StudentTool.write2File(ts);
}
}
/*
zhangsan,66,22,33
lisi,33,88,99
wangwu,76,85,96
*/