第7章 C#中的文件,數組和異常
C#處理數組和文件相當容易,並引入異常來簡化錯誤處理。
7.1 數組
const int MAX=10;
float[] xy=new float[MAX];
for (int i=0;i<MAX;i++){
xy[i]=i;
}
應當習慣數組的循環是從零到數組邊界值減1,正如我們在前面的代碼中所做的那樣。
所有的數組變量都有一個長度屬性,可以根據它查出數組的大小。
float[] z=new float[20];
for (int j=0;j<=z.length;j++){
z[j]=j;
}
C#中的數組是動態的,可以在任何時候重新分配空間。
在類內部創建一個數組的引用,然后分配空間,可這樣寫:
float[] z; //declare here
z=new float[20]; //create later
7.2 集合對象
7.2.1 ArrayList
ArrayList(數組表)對象本質上是一個可變長的數組,可以根據需要添加元素
使用ArrayList的方法可以向數組中添加元素,或取出,修改某個元素.
float[] z={1.0f,2.9f,5.6f};
ArrayList arl=new ArrayList();
for (int j=0;j<z.length;j++){
arl.Add(z[j]);
}
ArrayList有一個Count屬性,可用於確定它所包含的元素數目.
for (j=0;j<arl.count;j++){
Console.WriteLine(arl[j]);
}
foreach(float a in arl){
Console.WriteLine(a);
}
ArrayList的方法列表:
Clear
刪除ArrayList的內容
Contains(object)
如果ArrayList包含該對象,則返回true
CopyTo(array)
將ArrayList全部內容拷貝到一個一維數組中
IndexOf(object)
返回該對象的第一個索引值
Insert(index,object)
將元素插入到指定的位置
Remove(object)
從表中刪除該元素
RemoveAt(index)
刪除指定對象的元素
Sort
對ArrayList排序
從ArrayList中取出的每個對象都是object類型,這就意味着,在使用前通常需要將其轉換成合適的類型.
float x=(float)arl[j];
7.2.2 Hashtable 哈希表
Hashtable是一個可變長數組,表中的每個項目都通過關鍵字值來訪問.
關鍵字一般是某個字符串,也可以是其他類型的對象.
使用Hashtable可以快速訪問一個大而無序的記錄表
還可以將關鍵字和項目值顛倒過來,創建一個每條項目都是唯一的表.
Hashtable hash=new Hashtable();
float freddy=12.3f;
hash.Add("fred",freddy); //add to table
//get this one back out
float temp=(float)hash["fred"];
注意,同ArrayList一樣.從Hashtable中得到的數據也必須轉換成合適的類型
Hashtable也有一個Count屬性,可用來獲取關鍵字的列表或項目的列表.
7.2.3 SortedList
SortedList(排序表)類保存了兩個內部數組,可以通過基於零的下標或字母關鍵字來獲取元素.
float sammy=44.55f;
SortedList slist=new SortedLIst();
slist.Add("fred",freddy);
slist.Add("sam",sammy);
//get by index
float newFred=(float)slist.GetByIndex(0);
//get by key
float newSam=(float)slist["sam"];
在System.Collections名字空間還可以看到Stack(堆棧)對象和Queue(隊列)對象,
他們的特性和讀者期望一樣,可以在系統幫助文檔中找到他們的方法.
7.3 異常
C#用異常完成錯誤處理,而不是采用其他難以使用的錯誤檢測方法。
異常處理就是把引起錯誤的語句包含在try塊中,然后用catch語句捕獲錯誤.
try{
//Statements
}
catch(Exception e){
//do these if an error occurs
finally{
//do these anyway
}
一般使用這種方法檢查文件處理語句的錯誤,
也可以用語捕獲數組下標越界和許多其他錯誤情形。
執行try塊中的語句若無錯誤,則轉到finally語句;
若有錯誤,則轉到catch語句,然后轉到finally語句.
try{
//note-one too many
for(int i=0;i<=arl.count(arl[i]);
}
catch(Exception e){
Console.WriteLine(e.Message);
}
這段程序輸出了錯誤信息和程序中的調用位置,然后繼續運行.
相反,若不捕獲異常,運行時會給出一條錯誤信息.
程序將退出運行不再繼續下去並給出出錯界面.
C#中的常用異常類
AccessException
訪問類的方法或數據時出錯
ArgumentException
傳給方法的參數是無效的
ArgumentNullException
參數是空的
ArithmeticException
上溢或下溢
DivideByZereException
被0除
IndexOutOfRangeException
文件沒找到
EndOfStreamException
訪問超出了輸入數據流(如文件)的末端
DirectoryNotFoundException
目錄沒找到
NullReferenceException
對象變量沒有初始化成一個實際的值
7.4 多個異常
也可以在一系列catch塊中捕獲多個異常並分別進行處理:
try{
for(int i=0;i<=arl.count;i++){
int k=(int)(float)arl[i];
Console.Write(i+""+k/i);
}
}
catch(DivideByZereException e){
printZero(e);
}
catch(IndexOutofRangeException e){
printOErr(e);
}
catch(Exception e){
printErr(e);
}
這樣做可以讓程序以不同方式從各種錯誤中恢復過來.
7.5 拋出異常
try{
//statements
}
catch(Exception e){
throw(e); //pass on to calling program
}
7.6 文件處理
C#中的文件處理對象提供了一些相當靈活的處理文件的方法.
7.6.1 File對象
File(文件)對象代表一個文件,並為檢測文件是否存在,文件更名和文件刪除提供了一些有用的方法。
所有這些方法都是靜態的,也就是說,
不能使用new運算符創建file的實例,但可以直接使用File的方法.
if(File.Exists("Foo.txt"))
File.Delete("foo.txt");
用File對象獲得用於讀寫文件數據的文件流(FileStream)
//open text file for reading
StreamReader ts=File.OpenText("foo1.txt");
//open any type of file for reading
FileStream fs=File.OpenRead("foo2.any");
一些比較有用的File方法:
File.FileExists(filename)
若文件存在,則為true
File.Delete(filename)
刪除該文件
File.AppendText(String)
添加文本
File.Copy(fromFile,toFile)
拷貝一個文件
File.Move(fromFile,toFile)
移動文件,刪除舊文件
File.GetExtension(filename)
返回文件的擴展名
File.HasExtension(filename)
若文件有擴展名,則為true
7.6.2 讀文本文件
StreamReader ts=File.OpenText("foo1.txt");
string s=ts.ReadLine();
7.6.3 寫文本文件
//open for writing
StreamWriter sw=File.CreateText("foo3.txt");
sw.WriteLine("Hello file");
7.6.3 寫文本文件
//append to text file
StreamWriter asw=new StreamWriter("foo1.txt",true);
//true為用於追加的布爾參數
7.7 文件處理中的異常
try{
//open text file for reading
StreamReader ts=File.OpenText("foo1.txt");
string s=ts.ReadLine();
}
catch(Exception e){
Console.WriteLine(e.Message);
}
7.8 檢測文件末尾
private StreamReader rf;
private bool eof;
public String readLine(){
String s=rf.ReadLine();
if(s==null)
eof=true;
return s;
}
public bool fEof(){ //文件讀入類中創建一個文件結束函數
return eof;
}
另外一種保證讀數據不會超過文件末尾的方法:
Peek方法返回文件中下一個字符的Ascii碼,如果沒有字符則返回-1.
public String read_Line(){
String s="";
if(rf.Peek()>0){
s=rf.ReadLine();
}
else{
eof = true;
}
return s;
}
7.9 csFile類
將文件方法包裝在一個帶有易用方法的簡單類中會更方便,於是我們編寫了csFile類
這里把文件名fileName和路徑包含在構造函數里,也可以用重載的OpenForRead和OpenForWrite語句把它傳遞進來.
public class csFile{
private string fileName;
StreamReader ts;
StreamWriter ws;
private bool opened,writeOpened;
public csFile(){
init();
}
private void init(){
opened=false;
writeOpened=false;
}
public csFile(string file_name){
fileName=file_name;
init();
}
//打開用於讀數據的文件
public bool OpenForRead(string file_name){
fileName=file_name;
try{
ts=new StreamReader(fileName);
opened=true;
}
catch(FileNotFoundException e){
return false;
}
return true;
}
//接下來,可以用readLine方法從文本文件讀數據
public string readLine(){
return ts.ReadLine();
}
//打開一個用於寫數據的文件,並向其中寫入若干文本:
public void writeLine(string s){
ws.WriteLine(s);
}
public bool OpenForWrite(string file_name){
try{
ws=new StreamWriter(file_name);
fileName=file_name;
writeOpened=true;
return true;
}
catch(FileNotFoundException e){
return false;
}
}
}
在任何需要讀寫文件時,都會使用這個簡化的文件方法包裝類.
本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。