[자바/JAVA/SCJP]자바 IO (입출력)

자바/JAVA/SCJP 자바/JAVA/SCJP 자바/JAVA/SCJP 자바/JAVA/SCJP 자바/JAVA/SCJP 자바/JAVA/SCJP 자바/JAVA/SCJP 자바/JAVA/SCJP 자바/JAVA/SCJP 자바/JAVA/SCJP 자바/JAVA/SCJP 자바/JAVA/SCJP 자바/JAVA/SCJP 자바/JAVA/SCJP 자바/JAVA/SCJP

바이트의 연속을 스트림(stream)이라고 한다. 자바에서는 스트림을 이용해서 입출력을 한다.
입력을 하는 스트림을 입력스트림(input stream)이라고 하고, 출력하는 스트림을 출력 스트림(output stream)이라고 한다.
입출력 스트림은 java.io 패키지에 만들어져 있다.
화면에 출력하고, 키보드로 부터 입력을 받아들이기 위해서는 System 클래스의
out 과 in 을 사용했다. System 클래스의 out은 PrintStream 타입의 멤버 필드이고,
in은 InputStream 타입의 멤버 필드이다. 자바에서 입력 스트림 클래스들은
InputStream 클래스로부터 상속된 클래스이다. 출력 스트림 클래스들은 OutputStream
클래스로부터 상속된 클래스이다.

9.2.1 InputStream 클래스


System 클래스의 in 멤버필드는 대표적인 InputStream 타입이다. InputStream은 입력을
위해 다음과 같은 메소드들을 이용할 수 있다.
       int read()
       int read(byte[])
       int read(byte[], int, int)
read() 메소드를 이용하는 경우에 바이트 값을 읽어오거나 파일의 끝인 경우에는
-1을 리턴한다. read(byte[]) 메소드는 읽은 내용을 바이트 배열에 채우고, 읽은 바이트의
수를 리턴한다. read(byte[], int, int) 메소드는 바이트 배열에서 시작 위치와 끝 위치를
지정한 뒤에 내용을 읽어오고, 읽은 바이트의 수를 리턴한다.


inOut.java 파일
     1  import java.io.*;
     2
     3  class inOut {
     4      public static void main (String args[]) throws IOException {
     5          int b, count = 0;
     6          while ((b = System.in.read()) != -1) {
     7              count++;
     8              System.out.print((char)b);
     9          }
    10          System.out.println();
    11          System.err.println("total bytes = " + count);
    12      }
    13  }

결과
% java inOut
Hello
Hello
한글
??±?
^D
total bytes = 11

설명
     6          while ((b = System.in.read()) != -1) {
System.in.read() 메소드를 이용해서 키보드로부터 입력을 받는다. read() 메소드는
바이트 입력을 리턴하고, 입력이 종료되면(Cntl-D) -1을 리턴한다.

     8              System.out.print((char)b);
System.out.print() 메소드를 이용해서 읽어온 바이트를 문자 타입으로 변환해서
출력한다.

    11          System.err.println("total bytes = " + count);
System 클래스의 err 멤버 필드를 이용해서 출력하였다. err 멤버필드는 표준 에러
출력을 위해 사용된다.

total bytes = 11
유닉스 시스템에서 테스트 하였기 때문에 영어 문자당 1개의 바이트와 한글에 2바이트
가 사용되었다. 따라서, 영어 5개 문자(5 바이트), 한글 2개 문자(4 바이트), 리턴값
(1 바이트 x 2), 총 11 바이트가 된다.



9.2.2 InputStreamReader 클래스


JDK 1.0의 입출력 스트림은 JDK 1.1에서 Reader 와 Writer 클래스로 대체되었다.
입력을 위해서는 Reader 클래스를 이용하고, 출력을 위해서는 Writer 클래스를
이용할 수 있다. Reader 클래스는 입력을 위해 다음과 같은 메소드들을 이용할 수 있다.
         int read()
         int read(char[])
         int read(char[], int, int)

InputStreamReader 클래스는 InputStream 을 아규먼트로 만들어진다.
InputStreamReader 클래스의 getEncoding() 메소드는 스트림에서 사용된 인코딩 이름을 리턴한다.

BufferedReader 클래스는 Reader 클래스를 아규먼트로 만들 수 있다. BufferedReader 클래스
는 다음과 같은 메소드를 이용해서 입력을 받을 수 있다.
          int read()
          String readLine()
read() 메소드는 한문자를 읽어서 리턴하는 메소드이고, readLine() 메소드는 한 줄을
읽어서 문자열을 리턴하는 메소드이다.


CharInput.java 파일
     1  import  java.io.*;
     2
     3  public class CharInput {
     4
     5      public static void main(String args[]) {
     6          String  s;
     7          BufferedReader     in;
     8          in = new BufferedReader(new InputStreamReader(System.in));
     9
    10          try {
    11              System.out.print("Put characters:");
    12              while((s = in.readLine()) != null) {
    13                  System.out.println("\tCharacters from console :" + s);
    14                  System.out.print("Put characters:");
    15              }
    16          } catch (IOException ex) { }
    17      }
    18  }

결과
% java CharInput
Put characters:Hello ?
        Characters from console :Hello ?
Put characters:안녕하세요 ?
        Characters from console :안녕하세요 ?
Put characters:^D

설명
     8          in = new BufferedReader(new InputStreamReader(System.in));
키보드로 부터 입력을 받는 BufferedReader 클래스를 만들기 위해, InputStreamReader
클래스와 System.in 을 이용했다.

    12              while((s = in.readLine()) != null) {
BufferedReader 클래스의 readLine() 메소드를 이용해서 한줄을 읽어들였다.



9.2.3 FileOutputStream 클래스


FileOut.java 파일
     1  import java.io.*;
     2
     3  public class FileOut {
     4      private FileOutputStream fout;
     5      private byte msg[];
     6      private int  len;
     7
     8      FileOut(String fname) throws IOException {
     9          msg = new byte[1024];
    10          len = 0;
    11          fout = new FileOutputStream(fname);
    12          int b =0;
    13
    14          System.out.print("Put characters:");
    15          b = System.in.read();
    16          while(b != 10) {
    17              msg[len++] = (byte)b;
    18              b = System.in.read();
    19          }
    20          write(msg);
    21          System.out.println("Total "+ len + " bytes.");
    22      }
    23
    24      public void write(byte[] m) throws IOException{
    25          for(int i=0; i < len; i++)  {
    26              fout.write(m[i]);
    27          }
    28      }
    29
    30      public void close() {
    31          try {
    32              fout.close();
    33          } catch(IOException ex) { }
    34      }
    35
    36
    37      public static void main(String[] args) throws IOException{
    38          FileOut o = new FileOut("temp");
    39          o.close();
    40      }
    41
    42  }

결과
% java FileOut
Put characters:Hello ? 안녕하세요 ?
Total 20 bytes.

% more temp
Hello ? 안녕하세요 ?

설명
    11          fout = new FileOutputStream(fname);
파일 이름을 아규먼트로 갖고 FileOutputStream 클래스를 만든다.

    15          b = System.in.read();
키보드로부터 입력을 받아들인다.

    26              fout.write(m[i]);
FileOutputStream 클래스를 이용해서 파일에 기록한다.

    32              fout.close();
close() 메소드를 이용해서 파일을 닫는다.



9.2.4 RandomAccessFile 클래스


RandomAccessFile 클래스는 seek() 메소드를 이용해서 입출력 포인터의 위치를
이동할 수 있다. 포인터를 이동시킨뒤에 파일에 기록하거나 내용을 읽을 수 있다.
RandomAccessFile 클래스는 다음과 같은 생성자를 이용해서 만들 수 있다.
      RandomAccessFile(String filename, String openmode)
첫번째 아규먼트는 파일의 이름을 의미하고, 두번째 아규먼트는 파일을 오픈할 때
읽기 전용인가 아니면 읽기/쓰기 가능한지를 나타낸다. 두번째 아규먼트는 읽기
전용인 경우에는 "r", 읽기/쓰기 인 경우에는 "rw" 이다.
RandomAccessFile 클래스는 파일의 길이를 알아볼 수 있는 length() 메소드, 각 자료
타입을 읽을 수 있는 readBoolean(), readByte(), readChar(), readDouble(), readFloat(),
readInt(), readLong(), readShort() 등의 메소드들이 있다. 마찬가지로 각 자료 타입을
기록할 수 있는 writeBoolean(boolean), writeByte(int), writeBytes(String), writeChar(int),
writeChars(String), writeDouble(double), writeFloat(float), writeInt(int), writeLong(long),
writeShort(int) 등의 메소드들이 있다.

EmployeeDB.java 파일 예제는 자바에서 C 언어에서 레코드를 어떻게 사용하는가를 보여준다.
자바는 레코드가 없기 때문에 클래스를 레코드로 사용한다. Record 클래스는 레코드를 표현하기
위해 사용된 클래스이다. Table 클래스는 레코드를 처리하기 위해 사용된 클래스이다.
Table 클래스에서 레코드를 읽거나 기록하기 위한 루틴들을 포함하고 있다. EmployeeDB 클래스는
주로 GUI를 위한 코드가 들어 있다.

EmployeeDB.java 파일
     1  import java.awt.*;
     2  import java.awt.event.*;
     3  import java.io.*;
     4
     5
     6  public class EmployeeDB extends Frame implements ActionListener {
     7      static final int NONE   = 0;
     8      static final int ADD    = 1;
     9      static final int TOTAL  = 2;
    10      static final int SEARCH = 3;
    11      static final int REMOVE = 4;
    12      static final int ESC    = 5;
    13      Panel             left, bottom;
    14      LabeledTextField  name, number, dept, phone;
    15      TextArea          display;
    16      Button            addB, totalB, searchB, removeB, escB, exitB;
    17      Table             table;
    18      int               action;
    19
    20
    21      public EmployeeDB() {
    22          setLayout(new BorderLayout());
    23          action = NONE;
    24          left = new Panel();
    25          bottom = new Panel();
    26          display = new TextArea();
    27          display.setEditable(false);
    28          name = new LabeledTextField("이 름");
    29          name.setEditable(false);
    30          number = new LabeledTextField("사 번");
    31          number.setEditable(false);
    32          dept = new LabeledTextField("부 서");
    33          dept.setEditable(false);
    34          phone = new LabeledTextField("전 화");
    35          phone.setEditable(false);
    36          left.setLayout(new GridLayout(4,1));
    37          left.setSize(400, 300);
    38          left.add(name);
    39          left.add(number);
    40          left.add(dept);
    41          left.add(phone);
    42
    43          addB = new Button("추 가");
    44          addB.addActionListener(this);
    45          addB.setActionCommand("add");
    46          totalB = new Button("전체 보기");
    47          totalB.addActionListener(this);
    48          totalB.setActionCommand("total");
    49          searchB = new Button("검 색");
    50          searchB.addActionListener(this);
    51          searchB.setActionCommand("search");
    52          removeB = new Button("삭 제");
    53          removeB.addActionListener(this);
    54          removeB.setActionCommand("remove");
    55          escB = new Button("취 소");
    56          escB.addActionListener(this);
    57          escB.setActionCommand("esc");
    58          exitB = new Button("종 료");
    59          exitB.addActionListener(this);
    60          exitB.setActionCommand("exit");
    61          exitB.setBackground(Color.red);
    62          bottom.setLayout(new GridLayout(1,6));
    63          bottom.add(addB);
    64          bottom.add(totalB);
    65          bottom.add(searchB);
    66          bottom.add(removeB);
    67          bottom.add(escB);
    68          bottom.add(exitB);
    69
    70          add("Center", display);
    71          add("West", left);
    72          add("South", bottom);
    73
    74          table = new Table();
    75      }
    76
    77      public void initialize() {
    78          action = NONE;
    79          addB.enable();
    80          totalB.enable();
    81          searchB.enable();
    82          removeB.enable();
    83          name.setText("");
    84          number.setText("");
    85          dept.setText("");
    86          phone.setText("");
    87          name.setEditable(false);
    88          number.setEditable(false);
    89          dept.setEditable(false);
    90          phone.setEditable(false);
    91      }
    92
    93      public void actionPerformed(ActionEvent e) {
    94          int    index = 0;
    95          String cmd = e.getActionCommand();
    96          String nameString, num, part, tel;
    97          boolean found = false;
    98          String  msg = "";
    99
   100          if(cmd.equals("add")) {
   101              if(action != ADD) {
   102                  action = ADD;
   103                  name.setEditable(true);
   104                  number.setEditable(true);
   105                  dept.setEditable(true);
   106                  phone.setEditable(true);
   107                  totalB.disable();
   108                  searchB.disable();
   109                  removeB.disable();
   110                  return;
   111              }
   112              nameString = name.getText().trim();
   113              if(nameString == null || nameString.length() == 0)
   114                  return;
   115              num  = number.getText().trim();
   116              if(num == null || num.length() == 0)
   117                  return;
   118              part = dept.getText().trim();
   119              if(part == null || part.length() == 0)
   120                  return;
   121              tel = phone.getText().trim();
   122
   123              display.setText(nameString + num + part + tel);
   124              table.add(nameString, num, part, tel);
   125              display.appendText("\n 등록을 성공적으로 마쳤습니다.");
   126              initialize();
   127          } else if(cmd.equals("total")) {
   128              action = TOTAL;
   129              initialize();
   130              index = table.getIndex();
   131              display.setText("\n 검색 건수 : 총 " + Integer.toString(index+1)+ " 건\n");
   132              display.appendText("\n============================================");
   133              display.appendText("\n 순번  \t성명   \t사번   \t부서명    \t전화번호 ");
   134              display.appendText("\n--------------------------------------------\n\n");
   135              if(index < 0) {
   136                  display.appendText(" 등록된 자료가 없습니다. \n");
   137                  return;
   138              }
   139              for(int i = 0; i <= index; i++) {
   140                  Record rec = table.readRec(i);
   141                  msg = " " + Integer.toString(i+1) + "  \t ";
   142                  msg +=  rec.getName() + " \t";
   143                  msg +=  Integer.toString(rec.getNum()) + " \t";
   144                  msg +=  rec.getPart() + " \t";
   145                  msg +=  rec.getTel() + "\n";
   146                  display.appendText(msg);
   147              }
   148          } else if(cmd.equals("search")) {
   149              if(action != SEARCH) {
   150                  action = SEARCH;
   151                  name.setEditable(true);
   152                  addB.disable();
   153                  totalB.disable();
   154                  removeB.disable();
   155                  return;
   156              }
   157              Record  rec;
   158              index = table.getIndex();
   159              nameString = name.getText().trim();
   160              if(nameString == null || nameString.length() == 0)
   161                  return;
   162              display.setText("\n ## 개인 조회 ###########\n");
   163              display.appendText("\n============================================");
   164              display.appendText("\n 순번  \t성명   \t사번   \t부서명  \t전화번호 ");
   165              display.appendText("\n--------------------------------------------\n\n");
   166              for(int i = 0; i <= index; i++) {
   167                  rec = table.readRec(i);
   168                  if(nameString.equals(table.readName(i, nameString.length()))) {
   169                      found = true;
   170                  }
   171                  if(found) {
   172                      msg = " " + Integer.toString(i+1) + "  \t ";
   173                      msg +=  rec.getName() + " \t";
   174                      msg +=  Integer.toString(rec.getNum()) + " \t";
   175                      msg +=  rec.getPart() + " \t";
   176                      msg +=  rec.getTel() + "\n";
   177                      display.appendText(msg);
   178                      msg = "";
   179                      break;
   180                  }
   181              }
   182              if (!found) {
   183                  display.setText(" 조회하신 성명이나 사번의  직원이 없습니다...");
   184              }
   185              initialize();
   186          } else if(cmd.equals("remove")) {
   187              if(action != REMOVE) {
   188                  action = REMOVE;
   189                  name.setEditable(true);
   190                  addB.disable();
   191                  totalB.disable();
   192                  searchB.disable();
   193                  return;
   194              }
   195              index = table.getIndex();
   196              nameString = name.getText().trim();
   197              if(nameString == null || nameString.length() == 0)
   198                  return;
   199              display.setText("\n ## 삭제 ###########\n");
   200              display.appendText("\n============================================");
   201              display.appendText("\n 순번  \t성명   \t사번   \t부서명  \t전화번호 ");
   202              display.appendText("\n--------------------------------------------\n\n");
   203              for(int i = 0; i <= index; i++) {
   204                  Record rec = table.readRec(i);
   205                  if(nameString.equals(table.readName(i, nameString.length()))) {
   206                      found = true;
   207                  }
   208                  if(found) {
   209                      msg  = rec.getName();
   210                      msg += Integer.toString(rec.getNum());
   211                      msg += rec.getPart();
   212                      msg += rec.getTel();
   213                      display.appendText(msg);
   214                      msg = "";
   215                      found = true;
   216                      display.appendText("\n 위의 자료를 삭제하였습니다....");
   217                      for(int j=i+1; j <= index; j++) {
   218                          rec = table.readRec(j);
   219                          table.writeRec(rec.getName(),rec.getNum(),rec.getPart(),rec.getTel(),j-1);
   220                      }
   221                      table.remove(--index);
   222                      break;
   223                  }
   224              }
   225              if(!found) {
   226                  display.appendText("조회하신 성명의  직원이 없습니다...");
   227              }
   228              initialize();
   229          } else if(cmd.equals("esc")) {
   230              action = NONE;
   231              initialize();
   232          } else if(cmd.equals("exit")) {
   233              table.close();
   234              setVisible(false);
   235              dispose();
   236              System.exit(0);
   237          }
   238      }
   239
   240
   241
   242      class Table {
   243          private RandomAccessFile myRAFile;
   244          private int recordCount;
   245          private int recordLength = 50;
   246          private int recordOffset = 4;
   247
   248          public Table() {
   249              try {
   250                  myRAFile = new RandomAccessFile("employee.db", "rw");
   251                  if(myRAFile.length() ==0) {
   252                      recordCount = -1;
   253                  } else {
   254                      recordCount = myRAFile.readInt();
   255                  }
   256              } catch(IOException e) {
   257                  System.out.println("Can't access employee.dat");
   258              }
   259          }
   260
   261
   262          public int getIndex() {
   263              return recordCount;
   264          }
   265
   266          public void add(String name, String num, String part, String tel) {
   267              writeRec(name, Integer.parseInt(num), part, tel, ++recordCount);
   268          }
   269
   270          public void close() {
   271              try {
   272                  myRAFile.close();
   273              } catch(IOException ioe) {
   274                  System.out.println("IOException during close file");
   275              }
   276          }
   277
   278          public Record readRec(int index) {
   279              String name="", part="", tel="" ;
   280              int    num = -1 ;
   281
   282              try {
   283                  myRAFile.seek(index * recordLength + recordOffset);
   284                  for(int i = 0; i < 5;i++)  {
   285                      name += myRAFile.readChar();
   286                  }
   287                  num = myRAFile.readInt();
   288                  for(int i = 0; i < 6;i++) {
   289                      part += myRAFile.readChar();
   290                  }
   291                  for(int i = 0; i < 8;i++)  {
   292                      tel  += myRAFile.readChar();
   293                  }
   294
   295              } catch(IOException ioe) {
   296                  System.out.println("IOException during read file..");
   297              }
   298              return (new Record(name, num, part, tel));
   299          }
   300
   301          public String readName(int index, int len) {
   302              String name="";
   303              try {
   304                  myRAFile.seek(index * recordLength + recordOffset);
   305                  for(int i = 0; i < len;i++)  {
   306                      name += myRAFile.readChar();
   307                  }
   308              } catch (IOException ioe) {
   309                  System.out.println("IOException :"+ioe.toString());
   310              }
   311              return (name);
   312          }
   313
   314
   315          public void remove(int i) {
   316              recordCount = i;
   317          }
   318
   319
   320          public void writeRec(String name, int num, String part, String tel, int index) {

   321              int len = 0;
   322
   323              try {
   324                  myRAFile.seek(index * recordLength + recordOffset);
   325                  len = name.length();
   326                  for(int i =0;i < 5;i++) {
   327                      myRAFile.writeChar((i < len ? name.charAt(i) : ' '));
   328                  }
   329                  myRAFile.writeInt(num);
   330
   331                  len = part.length();
   332                  for(int i =0;i < 6;i++) {
   333                      myRAFile.writeChar((i < len ? part.charAt(i) : ' '));
   334                  }
   335
   336                  len = tel.length();
   337                  for(int i =0;i < 8;i++) {
   338                      myRAFile.writeChar((i < len ? tel.charAt(i) : ' '));
   339                  }
   340                  myRAFile.seek(0);
   341                  myRAFile.writeInt(recordCount);
   342              } catch(IOException ioe) {
   343                  System.out.println("IOException while writing..");
   344              }
   345          }
   346
   347      }
   348
   349
   350      class Record {
   351          private  String  name;
   352          private  int     num;
   353          private  String  part;
   354          private  String  tel;
   355
   356          public Record(String na, int n, String p, String t) {
   357              name  = na;
   358              num   = n;
   359              part  = p;
   360              tel   = t;
   361          }
   362
   363          public String getName() {
   364              return(name);
   365          }
   366
   367          public int getNum() {
   368              return(num);
   369          }
   370
   371          public String getPart() {
   372              return(part);
   373          }
   374
   375          public String getTel() {
   376              return(tel);
   377          }
   378      }
   379
   380      public static void main(String agrs[]) {
   381          EmployeeDB  db = new EmployeeDB();
   382          db.setSize(550, 300);
   383          db.setVisible(true);
   384      }
   385  }


LabeledTextField.java 파일
     1  import  java.awt.*;
     2
     3  public class LabeledTextField extends Panel{
     4      private  Label     label;
     5      private  TextField field;
     6      private  String    labelPosition;
     7      private  String    fieldPosition;
     8
     9      public LabeledTextField(String labelString) {
    10          this(labelString, "1%, 5%, 25%, 95%", "27%, 5%, 98%, 95%");
    11      }
    12
    13
    14      public LabeledTextField(String labelString, String labelPosition, String fieldPosition) {
    15          super();
    16          setLayout(new PositionLayout());
    17          this.labelPosition = labelPosition;
    18          this.fieldPosition = fieldPosition;
    19          label = new Label(labelString);
    20          field = new TextField(20);
    21          add(labelPosition, label);
    22          add(fieldPosition, field);
    23      }
    24
    25      public String getText() {
    26          return field.getText();
    27      }
    28
    29      public void setText(String m) {
    30          field.setText(m);
    31      }
    32
    33      public void setEditable(boolean t) {
    34          boolean able = field.isEditable();
    35          if(t != able)
    36              field.setEditable(t);
    37      }
    38
    39      public static void main(String args[]) {
    40          Frame f = new Frame();
    41          LabeledTextField lt = new LabeledTextField("Name:");
    42          f.add("South", lt);
    43          f.setSize(400, 200);
    44          f.setVisible(true);
    45      }
    46  }

결과
% java EmployeeDB



설명
   250                  myRAFile = new RandomAccessFile("employee.db", "rw");
employee.db 파일을 읽기/쓰기로 오픈한다.

   251                  if(myRAFile.length() ==0) {
파일의 길이가 0 이면, 즉 파일에 내용이 없으면..

   254                      recordCount = myRAFile.readInt();
파일로부터 정수를 하나 읽어온다.

   283                  myRAFile.seek(index * recordLength + recordOffset);
입출력 포인터를 특정 위치로 이동 시킨다.

   327                      myRAFile.writeChar((i < len ? name.charAt(i) : ' '));
문자를 파일에 기록한다.

출처:
http://www.it-bank.or.kr/prom/java_main.htm

자바/JAVA/SCJP 자바/JAVA/SCJP 자바/JAVA/SCJP 자바/JAVA/SCJP 자바/JAVA/SCJP 자바/JAVA/SCJP 자바/JAVA/SCJP 자바/JAVA/SCJP 자바/JAVA/SCJP 자바/JAVA/SCJP 자바/JAVA/SCJP 자바/JAVA/SCJP 자바/JAVA/SCJP 자바/JAVA/SCJP 자바/JAVA/SCJP

Posted by 김윤석

카테고리

놀며즐기고 공부하기 (685)
 IT 정보 (653)
 재테크 (0)
 엔터테이먼트 (11)
 인터넷마케팅 (0)
 사이트 추천 (1)
사이드바 열기