1.6k likes | 1.72k Views
Chapter 17 – Files and Streams.
E N D
Chapter 17 – Files and Streams Outline17.1 Introduction17.2 Data Hierarchy17.3 Files and Streams17.4 Classes File and Directory17.5 Creating a Sequential-Access File17.6 Reading Data from a Sequential-Access File17.7 Random-Access Files17.8 Creating a Random-Access File17.9 Writing Data Randomly to a Random-Access File17.10 Reading Data Sequentially from a Random-Access File17.11 Case Study: A Transaction-Processing Program
17.1 Introduction • Variables and arrays only temporary • Lost during garbage collection or when a program terminates • Files used for long term storage • Called persistent data • This chapter deals with: • Sequential-access files • Random-access files • File processing features • Stream-input/output features
17.4 File and Directory classes • Namespace System.IO needed for file processing • Information stored in files • File class used to manipulate files • Only has static methods, cannot instantiate File objects • Files organized in directories • Directory class used to manipulate directories
Exceptions • FileNotFoundException: ngoại lệ này được phát sinh khi không tìm thấy tập tin • DirectoryNotFoundException: ngoại lệ này được phát sinh khi không tìm thấy thư mục • IOException: ngoại lệ này được phát sinh từ một số ngoại lệ khác • EndOfStreamException: ngoại lệ này được phát sinh khi không tìm thấy dấu hiệu kết thúc của tập tin • FileLoadException: ngoại lệ này được phát sinh khi có lỗi đọc tập tin
Example 1 Xử lý nhấn nút Enter trong textbox: + Lấy nội dung trong textbox + Nếu nội dung này là tập tin thì: - Đọc các thông tin của tập tin ra textbox - Đọc nội dung của tập tin ra textbox + Nếu nội dung này là thư mục thì: - Đọc các thông tin của thư mục ra textbox - Hiện các con trực tiếp của thư mục này ra textbox + Nếu nội dung này không phải là tập tin hoặc thư mục thì thông báo lỗi
1 // Fig 17.5: FileTest.cs 2 // Using classes File and Directory. 3 4 using System; 5 using System.Drawing; 6 using System.Collections; 7 using System.ComponentModel; 8 using System.Windows.Forms; 9 using System.Data; 10 using System.IO; 11 12 // displays contents of files and directories 13 public class FileTestForm : System.Windows.Forms.Form 14 { 15 private System.Windows.Forms.Label directionsLabel; 16 17 private System.Windows.Forms.TextBox outputTextBox; 18private System.Windows.Forms.TextBox inputTextBox; 19 20 private System.ComponentModel.Container components = null; 21 22 [STAThread] 23 static void Main() 24 { 25 Application.Run( new FileTestForm() ); 26 } 27 28 // Visual Studio .NET generated code 29 30 // invoked when user presses key 31private void inputTextBox_KeyDown( 32 object sender, System.Windows.Forms.KeyEventArgs e ) 33 { FileTest.cs
34 // determine whether user pressed Enter key 35if ( e.KeyCode == Keys.Enter ) 36 { 37 string fileName; // name of file or directory 38 39 // get user-specified file or directory 40 fileName = inputTextBox.Text; 41 42 // determine whether fileName is a file 43if ( File.Exists( fileName ) ) 44 { 45 // get file's creation date, 46 // modification date, etc. 47 outputTextBox.Text = GetInformation( fileName ); 48 49 // display file contents through StreamReader 50 try 51 { 52 // obtain reader and file contents 53 StreamReader stream = new StreamReader( fileName ); 54 outputTextBox.Text += stream.ReadToEnd(); 55 } 56 // handle exception if StreamReader is unavailable 57 catch( IOException ) 58 { 59 MessageBox.Show( "File Error", "File Error", 60 MessageBoxButtons.OK, MessageBoxIcon.Error ); 61 } 62 } 63 64 // determine whether fileName is a directory 65else if ( Directory.Exists( fileName ) ) 66 { 67 // array for directories 68 string[] directoryList; FileTest.cs
69 70 // get directory's creation date, 71 // modification date, etc. 72 outputTextBox.Text = GetInformation( fileName ); 73 74 // obtain file/directory list of specified directory 75 directoryList = Directory.GetDirectories( fileName ); 76 77 outputTextBox.Text += 78 "\r\n\r\nDirectory contents:\r\n"; 79 80 // output directoryList contents 81 for ( int i = 0; i < directoryList.Length; i++ ) 82 outputTextBox.Text += directoryList[ i ] + "\r\n"; 83 } 84 else 85 { 86 // notify user that neither file nor directory exists 87 MessageBox.Show( inputTextBox.Text + 88 " does not exist", "File Error", 89 MessageBoxButtons.OK, MessageBoxIcon.Error ); 90 } 91 } // end if 92 93 } // end method inputTextBox_KeyDown 94 95 // get information on file or directory 96 private string GetInformation( string fileName ) 97 { 98 // output that file or directory exists 99string information = fileName + " exists\r\n\r\n"; 100 101 // output when file or directory was created 102 information += "Created: " + 103 File.GetCreationTime( fileName ) + "\r\n"; FileTest.cs
Get last time file was modified Get last time file was accessed Return file information 104 105 // output when file or directory was last modified 106 information += "Last modified: " + 107 File.GetLastWriteTime( fileName ) + "\r\n"; 108 109 // output when file or directory was last accessed 110 information += "Last accessed: " + 111 File.GetLastAccessTime( fileName ) + "\r\n" + "\r\n"; 112 113return information; 114 115 } // end method GetInformation 116 117 } // end class FileTestForm FileTest.cs
1 // Fig 17.6: FileSearch.cs 2 // Using regular expressions to determine file types. 3 4 using System; 5 using System.Drawing; 6 using System.Collections; 7 using System.ComponentModel; 8 using System.Windows.Forms; 9 using System.Data; 10 using System.IO; 11 using System.Text.RegularExpressions; 12 using System.Collections.Specialized; 13 14 public class FileSearchForm : System.Windows.Forms.Form 15 { 16 private System.Windows.Forms.Label directionsLabel; 17 private System.Windows.Forms.Label directoryLabel; 18 19 private System.Windows.Forms.Button searchButton; 20 21 private System.Windows.Forms.TextBox outputTextBox; 22 private System.Windows.Forms.TextBox inputTextBox; 23 24 private System.ComponentModel.Container components = null; 25 26 string currentDirectory = Directory.GetCurrentDirectory(); 27 string[] directoryList; // subdirectories 28 string[] fileArray; 29 30 // store extensions found and number found 31 NameValueCollection found = new NameValueCollection(); 32 FileSearch.cs
33 [STAThread] 34 static void Main() 35 { 36 Application.Run( new FileSearchForm() ); 37 } 38 39 // Visual Studio .NET generated code 40 41 // invoked when user types in text box 42 private void inputTextBox_KeyDown( 43 object sender, System.Windows.Forms.KeyEventArgs e ) 44 { 45 // determine whether user pressed Enter 46 if ( e.KeyCode == Keys.Enter ) 47 searchButton_Click( sender, e ); 48 49 } // end method inputTextBox_KeyDown 50 51 // invoked when user clicks "Search Directory" button 52private void searchButton_Click( 53 object sender, System.EventArgs e ) 54 { 55 // check for user input; default is current directory 56 if ( inputTextBox.Text != "" ) 57 { 58 // verify that user input is valid directory name 59if ( Directory.Exists( inputTextBox.Text ) ) 60 { 61 currentDirectory = inputTextBox.Text; 62 63 // reset input text box and update display 64 directoryLabel.Text = "Current Directory:" + 65 "\r\n" + currentDirectory; 66 } FileSearch.cs
67 else 68 { 69 // show error if user does not specify valid directory 70 MessageBox.Show( "Invalid Directory", "Error", 71 MessageBoxButtons.OK, MessageBoxIcon.Error ); 72 } 73 } 74 75 // clear text boxes 76 inputTextBox.Clear(); 77 outputTextBox.Clear(); 78 79 // search directory 80 SearchDirectory( currentDirectory ); 81 82 // summarize and print results 83foreach ( string current in found ) 84 { 85 outputTextBox.Text += "* Found " + 86 found[ current ] + " " + current + " files.\r\n"; 87 } 88 89 // clear output for new search 90 found.Clear(); 91 92 } // end method searchButton_Click 93 94 // search directory using regular expression 95 private void SearchDirectory( string currentDirectory ) 96 { 97 // search directory 98 try 99 { 100 string fileName = ""; 101 FileSearch.cs
102 // regular expression for extensions matching pattern 103 Regex regularExpression = new Regex( 104 "[a-zA-Z0-9]+\\.(?<extension>\\w+)" ); 105 106 // stores regular-expression-match result 107 Match matchResult; 108 109 string fileExtension; // holds file extensions 110 111 // number of files with given extension in directory 112 int extensionCount; 113 114 // get directories 115 directoryList = 116 Directory.GetDirectories( currentDirectory ); 117 118 // get list of files in current directory 119 fileArray = Directory.GetFiles( currentDirectory ); 120 121 // iterate through list of files 122foreach ( string myFile in fileArray ) 123 { 124 // remove directory path from file name 125 fileName = myFile.Substring( 126 myFile.LastIndexOf( "\\" ) + 1 ); 127 128 // obtain result for regular-expression search 129 matchResult = regularExpression.Match( fileName ); 130 131 // check for match 132if ( matchResult.Success ) 133 fileExtension = 134 matchResult.Result( "${extension}" ); FileSearch.cs
135else 136 fileExtension = "[no extension]"; 137 138 // store value from container 139if ( found[ fileExtension ] == null ) 140 found.Add( fileExtension, "1" ); 141 else 142 { 143 extensionCount = Int32.Parse( 144 found[ fileExtension ] ) + 1; 145 146 found[ fileExtension ] = extensionCount.ToString(); 147 } 148 149 // search for backup(.bak) files 150if ( fileExtension == "bak" ) 151 { 152 // prompt user to delete (.bak) file 153 DialogResult result = 154 MessageBox.Show( "Found backup file " + 155 fileName + ". Delete?", "Delete Backup", 156 MessageBoxButtons.YesNo, 157 MessageBoxIcon.Question ); 158 159 // delete file if user clicked 'yes' 160 if ( result == DialogResult.Yes ) 161 { 162 File.Delete( myFile ); 163 164 extensionCount = 165 Int32.Parse( found[ "bak" ] ) - 1; 166 FileSearch.cs
167 found[ "bak" ] = extensionCount.ToString(); 168 } 169 } 170 } 171 172 // recursive call to search files in subdirectory 173foreach ( string myDirectory in directoryList ) 174 SearchDirectory( myDirectory ); 175 } 176 177 // handle exception if files have unauthorized access 178 catch( UnauthorizedAccessException ) 179 { 180 MessageBox.Show( "Some files may not be visible" + 181 " due to permission settings", "Warning", 182 MessageBoxButtons.OK, MessageBoxIcon.Information ); 183 } 184 185 } // end method SearchDirectory 186 187 } // end class FileSearchForm FileSearch.cs
Thứ tự của việc đọc (ghi) một tập tin • Bước 1: Mở (tạo mới) tập tin • Bước 2: Thiết lập một luồng đọc (ghi) từ tập tin • Bước 3: Đọc (ghi) dữ liệu từ (lên) tập tin • Bước 4: Đóng lập tin lại
đọc - ghi tập tin • Đọc – ghi tập tin văn bản • Đọc – ghi tập tin nhị phân
Ghi tập tin văn bản • Bước 1: Tạo mới tập tin • Dùng lớp File (để tạo ra đối tượng StreamWriter) • Ex: StreamWriter fsw= File.CreateText (“D:\\myText.txt”); • Bước 2: Thiết lập một luồng ghi từ tập tin • Dùng lớp StreamWriter • Ex: StreamWriter sw = fsw; • Bước 3: Ghi dữ liệu lên tập tin • Dùng Write, WriteLine method của StreamWriter • Ex: sw.WriteLine(“bai hoc ve tap tin”); • Bước 4: Đóng tập tin, luồng • Dùng Close methods
Ghi tập tin văn bản Tạo tập tin và luồng ghi Ghi dữ liệu vào tập tin Đóng tập tin StreamWriter sw (File.CreateText) (File.AppendText) sw.Write(…) sw.WriteLine(…) sw.Close()
Ví dụ: Ghi tập tin văn bản // tạo luồng ghi tập tin StreamWriter sw = File.CreateText (“D:\\myText.txt”); // ghi nội dung tập tin sw.WriteLine (“Khong co viec gi kho”); sw.WriteLine (“Chi so long khong ben”); sw.WriteLine (“Dao nui va lap bien”); sw.WriteLine (“Quyet chi at lam nen”); for (int i=0; i < 10; i++) { sw.Write ( i ); } // đóng luồng (file thực sự được lưu) sw.Close();
Đọc tập tin văn bản • Bước 1: Mở tập tin • Dùng lớp File (để tạo ra đối tượng StreamReader) • Ex: StreamReader fsr= File.OpenText (“D:\\myText.txt”); • Bước 2: Thiết lập một luồng đọc từ tập tin • Dùng lớp StreamReader • Ex: StreamReader sr = fsr ; • Bước 3: Đọc dữ liệu từ tập tin • Dùng Read(), ReadLine() method của StreamReader • Ex: string s = sr.ReadLine() ; • Bước 4: Đóng lập tin lại • Dùng Close methods • Hàm ReadLine(): mỗi lần chỉ đọc 1 đoạn (đến dấu xuống dòng thì ngưng), khi hàm đọc được giá trị null thì hết tập tin • Hàm Read(): đọc 1 số
Ghi tập tin văn bản Tạo tập tin và luồng đọc Đọc dữ liệu vào biến string Đóng tập tin sr.ReadLine(…) sr.Read(…) sr.Close() StreamReader sr (File.OpenText)
Ví dụ: Đọc tập tin văn bản string buffer; // mở luồng đọc tập tin StreamReader sr = File.OpenText (“D:\\myText.txt”); // đọc nội dung tập tin cho đến khi nào không đọc được nữa while ( (buffer = sr.ReadLine()) !=null) { // do something Console.WriteLine (buffer); } // đóng luồng sr.Close();
Ghi dữ liệu từ chuỗi vào file bool writeFile (string path, string content) { try{ StreamWriter sw = File.CreateText (path); // ghi nội dung tập tin sw.WriteLine(content); // file thực sự được lưu sw.Close(); returntrue; } catch(IOException ex) { MessageBox.Show(ex.Message); return false; } }
Đọc dữ liệu từ file vào chuỗi (c1) Ví dụ stringreadFile (string path) { try{ string buffer, content=""; StreamReader sr = File.OpenText (path); while( (buffer = sr.ReadLine()) != null){ content += buffer + "\n";; } sr.Close(); return content; } catch(IOException ex){ MessageBox.Show(ex.Message); return ""; } }
Đọc dữ liệu từ file vào chuỗi (c2) stringreadFile (string path) { try{ string content = ""; StreamReader sr = File.OpenText (path); content = sr.ReadToEnd(); // đọc toàn bộ nội dung tập tin sr.Close(); return content; } catch(IOException ex){ MessageBox.Show(ex.Message); return ""; } }
Ghi dữ liệu từ mảng vào file (c1) bool writeFile (string path, string[] arr) { try{ StreamWriter sw = File.CreateText (path); // ghi nội dung tập tin for (int i=0; i<arr.Length; i++) sw.WriteLine (arr[i]); // file thực sự được lưu sw.Close(); returntrue; } catch(IOException ex) { MessageBox.Show(ex.Message); return false; } }
Ghi dữ liệu từ mảng vào file (c2) bool writeFile (string path, string[] arr) { try{ StreamWriter sw = File.CreateText (path); // ghi nội dung tập tin sw.WriteLine (arr.Length); // ghi số phần tử mảng for (int i=0; i<arr.Length; i++) sw.WriteLine (arr[i]); // file thực sự được lưu sw.Close(); returntrue; } catch(IOException ex) { MessageBox.Show(ex.Message); return false; } }
Đọc dữ liệu từ file vào mảng 4 Câu hỏi 1 … Câu hỏi 2 … Câu hỏi 3 … Câu hỏi 4 … 4 Đáp án câu 1-A Đáp án câu 1-B Đáp án câu 1-C Đáp án câu 1-D Đáp án câu 2-A Đáp án câu 2-B Đáp án câu 2-C Đáp án câu 2-D Đáp án câu 3-A Đáp án câu 3-B Đáp án câu 3-C Đáp án câu 3-D Đáp án câu 4-A Đáp án câu 4-B Đáp án câu 4-C Đáp án câu 4-D string[] readFileToArray (string path) { try{ string buffer; string[] content; StreamReader sr = File.OpenText (path); // doc dong dau tien de lay so luong phan tu intsopt; buffer = sr.ReadLine(); sopt = Convert.ToInt32 (buffer); content = newstring[sopt]; // cấp phát mảng inti=0; while( (buffer = sr.ReadLine()) != null){ content[i++] = buffer ; } sr.Close(); return content; } catch … }
Ví dụ string[] arrCauhoi; string[] arrTraloi; frmTracNghiem_Load (…) { arrCauhoi = readFileToArray ("D:\\DsCauHoi.txt"); … }
Đọc dữ liệu từ file vào mảng (2 chiều) 3 Câu hỏi 1 … Đáp án câu 1-A Đáp án câu 1-B Đáp án câu 1-C Đáp án câu 1-D Câu hỏi 2 … Đáp án câu 2-A Đáp án câu 2-B Đáp án câu 2-C Đáp án câu 2-D Câu hỏi 3 … Đáp án câu 3-A Đáp án câu 3-B Đáp án câu 3-C Đáp án câu 3-D string[,] readFileToArray (string path) { try{ string buffer; string[,] content; StreamReader sr = File.OpenText (path); // doc dong dau tien de lay so luong phan tu intsopt; buffer = sr.ReadLine(); sopt = Convert.ToInt32 (buffer); // cấp phát mảng content = newstring[?, ?]; inti=0; while( (buffer = sr.ReadLine()) != null){ content[?, ?] = buffer ; buffer = sr.ReadLine(); content[?, ?] = buffer ; … i++; } sr.Close(); return content; } catch … }
Đọc dữ liệu từ file vào mảng (2 chiều) 3 TCTH30A Trung cấp tin học 30A TCTH30B Trung cấp tin học 30B CDTH7K Cao đẳng tin học 7K string[,] readFileToArray (string path) { try{ string buffer; string[,] content; StreamReader sr = File.OpenText (path); // doc dong dau tien de lay so luong phan tu intsopt; buffer = sr.ReadLine(); sopt = Convert.ToInt32 (buffer); content = newstring[??, ??]; // cấp phát mảng inti=0; while( (buffer = sr.ReadLine()) != null){ content[?, ?] = buffer ; buffer = sr.ReadLine(); content[?, ?] = buffer ; i++; } sr.Close(); return content; } catch … }
Ví dụ • Đưa dữ liệu bảng Lớp vào Listview • Đưa dữ liệu bảng Lớp (cột tên lớp) vào ComboBox, ListBox phục vụ cho thao tác Thêm 1 SV CONTROLS (Textbox, ListBox, ComboBox, ListView, TreeView, RadioButton, CheckBox,… LỚP ĐỐI TƯỢNG (Chuỗi, Mảng 1 chiều, Mảng 2 chiều, Danh sách mảng) TẬP TIN (Văn bản, Nhị phân)
Ví dụ: Đưa bảng lớp vào ListView string[,] arrLop; frmSV_Load (…) { // đọc dữ liệu từ file vào mảng arrLop arrLop = readFileToArray ("D:\\DsLop.txt"); // đưa dữ liệu bảng arrLop vào ListView ShowToListview (arrLop, lvwLop); }
Ví dụ: Đưa bảng lớp vào ListView void ShowToListview (string[,] arr, ListView lvw) { // duyet tung dong trong mang arr cho hien len ListView lvw.Items.Clear(); ListViewItem item = new ListViewItem(); for(inti = 0; i < arr.Length; i++) { item = lvw.Items.Add (????); item.SubItems.Add (????); } }
Ví dụ: Đưa bảng lớp vào ComboBox (cột tên lớp) string[,] arrLop; frmSV_Load (…) { // đọc dữ liệu từ file vào mảng arrLop …. // đưa dữ liệu bảng arrLop vào ComboBox ShowToComboBox (arrLop, cboLop); }
Ví dụ: Đưa bảng lớp vào ComboBox (cột tên lớp) void ShowToComboBox (string[,] arr, ComboBox cbo) { // duyet tung dong trong mang arr cho hien len ComboBox cbo.Items.Clear(); for(inti = 0; i < arr.Length; i++) { cbo.Items.Add (????); } }
Đọc dữ liệu từ file vào ArrayList TCTH30A Trung cấp tin học 30A TCTH30B Trung cấp tin học 30B CDTH7K Cao đẳng tin học 7K using System.Collections; ArrayListreadFileToArrayList (string path) { try{ string buffer; ArrayList list; StreamReader sr = File.OpenText (path); while( (buffer = sr.ReadLine()) != null){ string malop = buffer; buffer = sr.ReadLine(); string tenlop = buffer; Clop lop = newClop (malop, tenlop); list.Add (lop); } sr.Close(); return list; } catch… } } • Viết class cho đối tượng Lớp • Mỗi phần tử trong ArrayList là một đối tượng Lớp
Ghi dữ liệu từ ArrayList vào file using System.Collections; void writeArrayListToFile (string path, ArrayList list) { try{ StreamWriter sw = File.CreateText (path); // ghi nội dung tập tin … } catch … }
Ghi tập tin nhị phân • Bước 1: Tạo mới tập tin • Dùng lớp FileStream • Bước 2: Thiết lập một luồng ghi từ tập tin • Dùng lớp BinaryWriter • Bước 3: Ghi dữ liệu lên tập tin • Dùng Write method của BinaryWriter • Bước 4: Đóng lập tin lại • Dùng Close methods
Ghi tập tin nhị phân Tạo tập tin và luồng ghi Ghi dữ liệu vào tập tin Đóng tập tin FileStream fs BinaryWriterbw (FileMode.Create) bw.Close() fs.Close() bw.Write(…)
Ghi thông tin vào tập tin nhị phân FileStream fs = newFileStream (“d:\\myFile.txt”, FileMode.Create); BinaryWriter bw = newBinaryWriter (fs); for (int i=0; i < 100; i++) { bw.Write(i); } bw.Close(); fs.Close();
Ghi thông tin vào tập tin nhị phân BinaryWriter bw = newBinaryWriter (newFileStream (“d:\\myFile.txt”, FileMode.Create)); for (int i=0; i < 100; i++) { bw.Write(i); } bw.Close(); fs.Close();