3. C++ Stream Input/Output C++ 에서파일 : 바이트의나열 파일의끝에는 End-of-file fil 표시가존재 파일이 open될때stream이생성되며, 파일은 stream의 subclass 로정의 ios istream ostream ifstream iostream ofstream fstream 파일처리 Headers <iostream.h> and <fstream.h> class ifstream - input class ofstream - output class fstream - either input or output 영남대학교데이터베이스연구실 Algorithm: Chapter 3 (Page 25)
파일읽기와쓰기 파일에서읽기 파일에출력하기 파일객체생성 ifstream 객체이름 ; 파일객체생성 ofstream 객체이름 ; 파일열기객체이름.open( 파일이름 ); 파일열기객체이름.open( 파일이름 ); if ( 객체이름 ==NULL) 파일열기오류 if ( 객체이름 ==NULL) 파일열기오류 파일작업 객체이름 >> 변수 파일작업 객체이름 << 변수 파일닫기객체이름.close(); 파일닫기객체이름.close(); 영남대학교데이터베이스연구실 Algorithm: Chapter 3 (Page 26)
Example #include <iostream> using std::cerr; using std::cin; using std::cout; using std::ios; using std:endl; #include <fstream> // file stream using std::ofstream; // output file stream int main() { ofstream outclientfile; outclientfile.open( "clients.dat", ios::out ); if (!outclientfile ) { cerr << "File could not be opened" << endl; return 0; cout << "Enter the account, name, and balance." << endl << "Enter EOF to end input. n? "; int account; char name[ 30 ]; double balance; while ( cin >> account >> name >> balance ) { return 0; outclientfile << account << ' ' << name << ' ' << balance << endl; cout << "? "; // ofstream destructor closes file 영남대학교데이터베이스연구실 Algorithm: Chapter 3 (Page 27)
fstream 클래스 fstream 클래스 = ofstream + ifstream 파일모드정의 : open() 함수의인자로지정 파일모드설명예 ios::in 파일에서읽어오기파일객체.open( 파일이름, ios::in); ios::out 파일에출력하기파일객체.open( 파일이름, ios::out); ios::app 파일에추가하여출력하기파일객체.open( 파일이름, ios::app); ios::trunc ios::binary 파일이이미존재하는경우삭제하고새로운파일로생성하여출력이진파일로처리하기 파일객체.open( 파일이름, ios::trunc); 파일객체.open( 파일이름, ios::in ios::binary); 파일객체.open( 파일이름, ios::out ios::binary); 영남대학교데이터베이스연구실 Algorithm: Chapter 3 (Page 28)
File 의 read & write << 나 >> 연산자사용 : text 단위의입출력 read 정해진바이트만큼입력스트림에서 read 사용방법 : integer를읽을경우 ifile.read(reinterpret_cast<char *>(&number), sizeof(int)); First argument: pointer of type char * Second argument: number of bytes to read write 정해진바이트만큼해당메모리주소에서출력스트림에 write 사용방법 : integer 를출력할경우, ofile.write(reinterpret_cast<const char *>(&number), sizeof(int)); First argument: pointer of type const char * Second argument: number of bytes to write 영남대학교데이터베이스연구실 Algorithm: Chapter 3 (Page 29)
File 에서읽고쓰는위치변경 seekg (seek get) for istream and seekp (seek put) for ostream fileobject.seekg( n ) 파일의 n 번째바이트로이동 (ios::beg 을가정 ) fileobject.seekg( n, ios::cur ) 현재위치에서 n 바이트앞으로이동 fileobject.seekg( y, ios::end ) 파일의끝에서 y 바이트만큼이동 fileobject.seekg( 0, ios::end ) 파일의끝으로이동 tellg and tellp return current location of pointer location o = fileobject.tellg() //returns long fstream에서는동일한값을가짐 영남대학교데이터베이스연구실 Algorithm: Chapter 3 (Page 30)
Example: e:clientdata.h #include <string> using std::string; class ClientData { public: ClientData( int = 0, string = "", string = "", double = 0.0 0 ); // constructor void setaccountnumber( int ); int getaccountnumber() const; void setlastname( string ); string getlastname() const; void setfirstname( string ); string getfirstname() const; void setbalance( double ); double getbalance() const; // accessor functions for accountnumber // accessor functions for lastname // accessor functions for firstname // accessor functions for balance private: int accountnumber; char lastname[ 15 ]; char firstname[ 10 ]; double balance; ; 영남대학교데이터베이스연구실 Algorithm: Chapter 3 (Page 31)
Example: TransactionProcessing.cpp ocess (1) #include <iostream> using std::cerr; using std::cin; using std::cout; using std::endl; using std::fixed; using std::ios; using std::left; using std::right; using std::showpoint; t #include <fstream> using std::ofstream; using std::ostream; using std::fstream; #include <iomanip> using std::setw; using std::setprecision; #include <cstdlib> using std::exit; #include "ClientData.h" // ClientData class definition int enterchoice(); void createtextfile( fstream& ); void updaterecord( fstream& ); void newrecord( fstream& ); void deleterecord( fstream& ); void outputline( ostream&, const ClientData & ); int getaccount( const char * const ); enum Choices { PRINT = 1, UPDATE, NEW, DELETE, END ; 영남대학교데이터베이스연구실 Algorithm: Chapter 3 (Page 32)
Example: TransactionProcessing.cpp ocess (2) int main() { ft fstream inoutcredit( dit(" "credit.dat", ditd t" ios::in i ios::out ); // open for read and write if (!inoutcredit ) { cerr << "File could not be opened." << endl; exit ( 1 ); int choice; // store user choice while ( ( choice = enterchoice() )!= END ) { // enable user to specify action switch ( choice ) { case PRINT: // create text file from record file createtextfile( inoutcredit ); break; case NEW: // create record newrecord( inoutcredit ); break; case UPDATE: // update record updaterecord( inoutcredit ); break; case DELETE: // delete existing record deleterecord( inoutcredit ); break; default: // display error if user does not select valid choice cerr << "Incorrect choice" << endl; break; inoutcredit.clear(); // Clears all error flags including eofbit return 0; 영남대학교데이터베이스연구실 Algorithm: Chapter 3 (Page 33)
Example: TransactionProcessing.cpp ocess (3) int enterchoice() { // display available options cout << " nenter your choice" << endl << "1 - store a formatted text file of accounts" << endl << " called "print.txt " p for printing" << endl << "2 - update an account" << endl << "3 - add a new account" << endl << "4 - delete an account" << endl << "5 - end program n? "; int menuchoice; cin >> menuchoice; return menuchoice; // input menu selection from user 영남대학교데이터베이스연구실 Algorithm: Chapter 3 (Page 34)
Example: TransactionProcessing.cpp ocess (4) void createtextfile( fstream &readfromfile ) { ofstream outprintfile( tfil ("print.txt", t t" ios::out t) ); // create text t file if (!outprintfile ) { cerr << "File could not be created." << endl; exit( 1 ); outprintfile << left << setw( 10) <<"Account" << setw( 16) <<"Last Name" << setw( 11 ) << "First Name" << right << setw( 10 ) << "Balance" << endl; readfromfile.seekg( 0 ); // set file-position pointer to beginning of readfromfile ClientData client; // read first record from record file readfromfile.read( reinterpret_cast< char * >(&client), sizeof(clientdata)); while (!readfromfile.eof() ) { // copy all records from record file into text file // write single record to text file if ( client.getaccountnumber()!= 0 ) // skip empty records outputline( outprintfile, client ); // read next record from record file readfromfile.read( reinterpret_cast< char * >(&client), sizeof(clientdata)); 영남대학교데이터베이스연구실 Algorithm: Chapter 3 (Page 35)
Example: TransactionProcessing.cpp ocess (5) void newrecord( fstream &insertinfile ) { int accountnumber = getaccount( t( "Enter new account number" "); // account # 입력 insertinfile.seekg((accountnumber - 1) * sizeof(clientdata)); ClientData client; // read record from file insertinfile.read(reinterpret_cast<char read(reinterpret *>(&client) >(&client), sizeof(clientdata ); if ( client.getaccountnumber() == 0 ) { char lastname[ 15 ], firstname[ 10 ]; double balance; // 기존에레코드가없을경우, 추가 cout << "Enter lastname, firstname, balance n? "; cin >> setw( 15 ) >> lastname >> setw( 10 ) >> firstname >> balance; client.setlastname( lastname ); client.setfirstname( firstname ); client.setbalance( balance ); client.setaccountnumber( accountnumber ); insertinfile.seekp( ( accountnumber - 1 ) * sizeof( ClientData ) ); insertinfile.write(reinterpret_cast<constconst char *>(&client), sizeof(clientdata)); else // display error if account already exists cerr << "Account #" << accountnumber << " 이미저장됨." << endl; 영남대학교데이터베이스연구실 Algorithm: Chapter 3 (Page 36)
Example: TransactionProcessing.cpp ocess (6) void updaterecord( fstream &updatefile ) { int accountnumber = getaccount( t( "Enter account tto update" "); // account # 입력 updatefile.seekg( ( accountnumber - 1 ) * sizeof( ClientData ) ); ClientData client; // read first record from file updatefile.read( reinterpret_cast< char * >( &client ), sizeof( ClientData ) ); if ( client.getaccountnumber()!= 0 ) { // update record, if record exists in file outputline( cout, client ); // display the record cout << " nenter charge (+) or payment (-): "; double transaction; cin >> transaction; // 뭘할지를사용자에게질의 double oldbalance = client.getbalance(); // update record balance client.setbalance( oldbalance + transaction ); outputline( cout, client ); // write updated record over old record in file updatefile.seekp( ( accountnumber - 1)* sizeof( ClientData )); ); updatefile.write( reinterpret_cast< const char * >( &client ), sizeof(clientdata)); else // display error if account does not exist cerr << "Account #" << accountnumber << " has no information." << endl; 영남대학교데이터베이스연구실 Algorithm: Chapter 3 (Page 37)
Example: TransactionProcessing.cpp ocess (7) void deleterecord( fstream &deletefromfile ) { int accountnumber = getaccount( t( "Enter account tto delete" "); deletefromfile.seekg( ( accountnumber - 1 ) * sizeof( ClientData ) ); ClientData client; deletefromfile.read( read( reinterpret_cast< char* >( &client ), sizeof( ClientData )); ); if ( client.getaccountnumber()!= 0 ) { // delete record, if record exists in file ClientData blank; // create blank record // replace existing record with blank record deletefromfile.seekp( ( accountnumber - 1 ) * sizeof( ClientData ) ); deletefromfile.write(reinterpret_cast<const char *>(&blank), sizeof(clientdata)); cout << "Account #" << accountnumber << " deleted. n"; else cerr << "Account #" <<accountnumber << " is empty. n"; 영남대학교데이터베이스연구실 Algorithm: Chapter 3 (Page 38)
4. Streams and Files at Java Class Hierarchy FileReader/FileWriter i vs. FileInputStream/FileOutputStream 추가적인 Class 들 java.io.randomaccessfile Class Memory-mapped Files 영남대학교데이터베이스연구실 Algorithm: Chapter 3 (Page 39)
4.1 Class Hierarchy ( 대표적인것만 ) class java.lang.object class java.io.inputstream class java.io.fileinputstream class java.io.filterinputstream class java.io.bufferedinputstream class java.io.datainputstream (implements java.io.datainput) class java.io.objectinputstream (implements java.io.objectinput, ) class java.io.outputstream class java.io.fileoutputstream class java.io.filteroutputstream class java.io.bufferedoutputstream class java.io.dataoutputstream (implements java.io.dataoutput) class java.io.objectoutputstream (implements java.io.objectoutput, ) class java.io.randomaccessfile (implements java.io.datainput, java.io.dataoutput) class java.io.reader class java.io.bufferedreader class java.io.inputstreamreader class java.io.filereader class java.io.writer class java.io.bufferedwriter class java.io.outputstreamwriter class java.io.filewriter 영남대학교데이터베이스연구실 Algorithm: Chapter 3 (Page 40)
4.2 Reader/Writer vs. InputStream/OutputStream (1) FileReader/FileWriter char(unicode) 타입의데이터입출력 예 : FileReader reader = new FileReader("data data.txt txt"); int data = reader.read(); // 오류처리위해 int 반환 if (data!= -1) char ch = (char) data; 여러개의문자를읽을경우 char arr[] = new char[100]; int num = reader.read(arr); close 방법 : reader.close() 영남대학교데이터베이스연구실 Algorithm: Chapter 3 (Page 41)
4.2 Reader/Writer vs. InputStream/OutputStream (2) FileInputStream/FileOutputStream byte 타입의데이터입출력 read 와 write member function 은 Reader/Writer 와동일 import java.io.*; class OutputStreamExample1 { public static void main(string args[]) { FileOutputStream out = null; try { out = new FileOutputStream("./output.dat"); byte arr[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 ; for (int cnt = 0; cnt < arr.length; cnt++) out.write(arr[cnt]); catch (IOException ioe) {System.out.println( println(" 파일로출력할수없습니다."); finally { try { out.close(); catch (Exception e) { 영남대학교데이터베이스연구실 Algorithm: Chapter 3 (Page 42)
4.3 추가적인 Class 들 Class 이름 Description DataInputStream Java primitive type의데이터 DataOutputStream 입출력 ObjectInputStream ObjectOutputStream BufferedReader BufferedInputStream BufferedWriter BufferedOutputStream Object 단위의데이터입출력 데이터를한꺼번에읽어서버퍼에저장해두는 class 데이터를버퍼에저장한후, 한꺼번에출력하는 class 영남대학교데이터베이스연구실 Algorithm: Chapter 3 (Page 43)
DataInputStream/DataOutputStream ataoutputst DataInputStream: byte stream primitive data type DataOutputStream: primitive i i data type byte stream 파일의입출력기능없음 : FileInputStream 등과연동 FileInputStream in1 = new FileInputStream("input input.dat dat"); DataInputStream in2 = new DataInputStream(in1); 주요 member function 들 DataInputStream DataOutputStream byte readbyte() void writebyte(int v) short readshort() void writeshort(int t(i t v) char readchar() void writechar(int v) int readint() void writeint(int v) long readlong() void writelong(long v) float readfloat() void writefloat(float v) double readdouble() void writedouble(double v) boolean readboolean() void writeboolean(boolean v) 영남대학교데이터베이스연구실 Algorithm: Chapter 3 (Page 44)
Example: DataOutputStream import java.io.*; class DataOutputExample1 { public static void main(string args[]) { DataOutputStream out = null; try { out = new DataOutputStream(new FileOutputStream("output.dat")); int arr[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ; for (int cnt = 0; cnt < arr.length; cnt++) out.writeint(arr[cnt]); catch (IOException ioe) {System.out.println(" 파일로출력할수없습니다."); finally y{ try { out.close(); catch (Exception e) { 영남대학교데이터베이스연구실 Algorithm: Chapter 3 (Page 45)
ObjectInputStream/ObjectOutputStream ea ea ObjectInputStream: stream object ObjectOutputStream: O object stream 파일의입출력기능없음 : FileInputStream 등과연동 FileOutputStream in1 = new FileOutputStream("input input.dat dat"); ObjectOutputStream in2 = new ObjectOutputStream(in1); in2.writeobject(obj); obj가 serializable object일경우에만출력가능 class 선언시 java.io.serializable 을구현하도록선언 직렬화대상 : static이아닌필드들 ( 생성자, 메소드 x) 영남대학교데이터베이스연구실 Algorithm: Chapter 3 (Page 46)
Example: e:objectinputstream ea import java.io.*; import java.util.gregoriancalendar; import java.util.calendar; l class ObjectInputExample1 { public static void main(string args[]) { ObjectInputStream in = null; try { in = new ObjectInputStream(new FileInputStream("output.dat")); while (true) { GregorianCalendar calendar = (GregorianCalendar) in.readobject(); int year = calendar.get(calendar.year); int month = calendar.get(calendar.month) + 1; int date = calendar.get(calendar.date); System.out.println(year + "/" + month + "/" + date); catch (FileNotFoundException fnfe) {System.out.println( println(" 파일없음 "); catch (EOFException eofe) { System.out.println(" 끝 "); catch (IOException ioe) {System.out.println(" 파일을읽을수없습니다."); catch (ClassNotFoundException cnfe) {System.out.println(" 해당클래스가없음."); finally { try { in.close(); catch (Exception e) { 영남대학교데이터베이스연구실 Algorithm: Chapter 3 (Page 47)
Buffered ed Input(Output)Stream, Reader FileReader, FileWriter, File Input(Output)Stream read/write method 를호출할때마다 disk access 성능저하 Buffered Input(Output)Stream, Reader/Writer disk access 의단위를버퍼크기로제한 FileInputStream in1 = new FileInputStream("input.dat"); BufferedInputStream in2 = new BufferdInputStream(in1, 1024); 두번째인자를생략하면 default 크기의버퍼생성 나머지 member function 들은 FileInputStream 등과동일 영남대학교데이터베이스연구실 Algorithm: Chapter 3 (Page 48)
4.4 RandomAccessFile e Class Cass 앞에서보았던 IO class들은순차적인 access만지원 seek() 의개념이없음 RandomAccessFile File 에대한 random access 지원 FileInput(Output)Stream과별개의 class Object 의직속 subclass 로파일처리에관한모든기능들을독자적으로구현 Constructor/Method t th Description RandomAccessFile(String name, String mode) mode: "r" for read, "rw" for read and write long getfilepointer() lseek(fd, 0, 1) void seek(long pos) lseek(fd, pos, 0) long length() lseek(fd, 0, 2) 영남대학교데이터베이스연구실 Algorithm: Chapter 3 (Page 49)
Example: RandomAccessAccountRecord ccou eco d import java.io.*; public class RandomAccessAccountRecord A d extends AccountRecord { public static final int SIZE = 72; public void read( RandomAccessFile file ) throws IOException { setaccount(file.readint()); setfirstname(readname(file)); setlastname(readname(file)); setbalance(file.readdouble()); private String readname( RandomAccessFile file ) throws IOException { char name[] = new char[ 15 ], temp; for ( int count = 0; count < name.length; count++ ) { temp = file.readchar(); name[ count ] = temp; return new String( name ).replace( ' 0', ' ' ); public void write( RandomAccessFile file ) throws IOException { file.writeint( getaccount() ); writename( file, getfirstname() ); writename( file, getlastname() ); file.writedouble( getbalance() ); 영남대학교데이터베이스연구실 Algorithm: Chapter 3 (Page 50)
Example: RandomAccessFile e (1) import java.io.*; public class FileEditor { RandomAccessFile file; // reference to the file public FileEditor( File filename ) throws IOException { file = new RandomAccessFile(fileName, "rw"); public RandomAccessAccountRecord getrecord( int accountnumber ) throws IllegalArgumentException, gu NumberFormatException, o IOException { RandomAccessAccountRecord record = new RandomAccessAccountRecord(); // seek appropriate record in file file.seek( ( accountnumber - 1 ) * RandomAccessAccountRecord.SIZE ); record.read(file); return record; public void closefile() throws IOException { if ( file!= null ) file.close(); 영남대학교데이터베이스연구실 Algorithm: Chapter 3 (Page 51)
Example: RandomAccessFile e (2) public void updaterecord( int accountnumber, String fname, String lname, double bal) throws IllegalArgumentException, IOException { RandomAccessAccountRecord record = getrecord(accountnumber); if ( record.getaccount() == 0 ) throw new IllegalArgumentException( "Account does not exist" ); file.seek( ( accountnumber - 1 ) * RandomAccessAccountRecord.SIZE ); record = new RandomAccessAccountRecord( accountnumber, fname, lname, bal); record.write( file ); public void newrecord( int accountnumber, String fname, String lname, double bal) throws IllegalArgumentException, IOException { RandomAccessAccountRecord record = getrecord( accountnumber ); if ( record.getaccount()!= 0 ) throw new IllegalArgumentException( "Account already exists" ); file.seek( ( accountnumber - 1)* RandomAccessAccountRecord.SIZE ); record = new RandomAccessAccountRecord( accountnumber, fname, lname, bal); record.write( file ); 영남대학교데이터베이스연구실 Algorithm: Chapter 3 (Page 52)
4.5 Memory-mapped Files File을 memory 주소에 mapping한후, 배열을액세스하는것처럼 file 을액세스 RandomAccessFile 보다실행시간이매우빠름 사용방법 (java.nio.*, java.nio.channels.* 등이용 ) MappedByteBuffer 의 instance 획득 RandomAccessFile db = new RandomAccessFile("student.dat", "rw"); MappedByteBuffer mbb = db.getchannel().map(filechannel.mapmode.read_write, 0, db.getchannel().size()); // size 대신에파일크기입력가능 MappedByteBuffer의 method를이용하여데이터액세스 mbb.position((student.getid() - 1) * RandomAccessStudentRecord.SIZE); write: mbb.putint(), mbb.putdouble(), mbb.putchar() 등 read: mbb.getint(), mbb.getdouble(), mbb.getchar() 등 영남대학교데이터베이스연구실 Algorithm: Chapter 3 (Page 53)