Devlog
article thumbnail
Published 2022. 3. 15. 19:38
[Java] IOStream (Day8) 강의/KOSTA

위 글은 해당 카테고리의 수업 강의 자료를 정리한 것입니다.

 

 

 

1. 개요

1.1 I/O (Input/Output: 입출력) 

  • 프로그램 외부소스 또는 목적지와의 데이터 정보의 교환
  • 입력: 키보드, 파일 등으로 부터 들어오는 데이터
  • 출력: 프로그램으로부터 화면, 파일 등으로 나가는 데이터

1.2 스트림(Stream)

  • 프로그램과 I/O 객체를 연결하여 데이터의 흐름을 연결해주는 통로
  • 스트림은 한방향으로 연결

 

 

  • 바이트 스트림(Bytem Stream): 1과 0으로 구성된 Binary 데이터의 입출력 처리를 위한 스트림 (이미지, 사운드)

  • 문자 스트림(Character Stream): 문자, 텍스트 형태의 데이터 입출력 처리를 위한 스트림 (단순 텍스트, 웹페이지, 키보드)

 

  • JAVA I/O 클래스
    • java.io 패키지에서 I/O를 위한 4개의 추상 클래스
    • 바이트 스트림: InputStream, OutputStream
    • 문자 스트림: Reader, Writter
    • 해당 클래스에서 상속받아 파일에 데이터를 읽고 씀

 

 

 

 

2. 바이트 기반 스트림/보조 스트림

  • InputStream (바이트 스트림: Byte Stream): 1과 0으로 구성된 Binary 데이터의 입력처리를 위한 스트림(이미지, 사운드)

 

 

  • OutputStream (바이트 스트림: Byte Stream): 1과 0으로 구성된 Binary 데이터의 출력 처리를 위한 스트림 (이미지, 사운드)

 

 

 

3. 문자 스트림/보조 스트림

  • Reader (문자 스트림: Character Stream): 문자, 텍스트 형태의 데이터 입력 처리를 위한 스트림(텍스트, 웹페이지, 키보드 등)

 

  • Writer (문자 스트림: Character Stream): 문자, 텍스트 형태의 데이터 출력 처리를 위한 스트림(텍스트, 웹페이지, 키보드)

 

 

4. InputStreamReader, OutputStreamWriter

 

InputStream을 통해 InputStreamReader 객체를 생성, BufferReader을 통해 읽을 수 있음

  • 바이트 기반 스트림을 문자 기반 스트림처럼 쓸 수 있게 해줌
  • 인코딩(encoding)을 변환하여 입출력 할 수 있게 해줌
  • 인코딩 변환하기
InputStream fis = new FileInputStream("C:\\javaStudy\\file\\MS949.txt");
// 맥 사용자들은 /로 경로만 설정해주면 됨
InputStreamReader isr = new InputStreamReader(fis, "MS949");

 

  • 콘솔로부터 라인 단위로 입력 받기
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
String line = br.readLine();

 

 

 

 

관련 문제1

public class Person {
	private String name;
    private String hp;
    private String company;

    public Person() {
    }

    public Person(String name, String hp, String company) {
        this.name = name;
        this.hp = hp;
        this.company = company;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getHp() {
        return hp;
    }

    public void setHp(String hp) {
        this.hp = hp;
    }

    public String getCompany() {
        return company;
    }

    public void setCompany(String company) {
        this.company = company;
    }

    @Override
    public String toString() {
        return "Phone [name=" + name + ", hp=" + hp + ", company=" + company + "]";
    }
    

}
/*
 * 공통기능 메소드로 만들어서 구현
 * static으로 메소드를 만들어야 하는 단점
*/

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class PhoneApp {

  private static List<Person> pList;

  public static void main(String[] args) throws IOException {

    // 스캐너
    Scanner sc = new Scanner(System.in);

    // 파일을 읽어서 리스트에 담는다.
    getList();

    // 시작화면
    System.out.println("******************************************");
    System.out.println("*           전화번호 관리 프로그램             *");
    System.out.println("******************************************");

    // while 시작
    boolean run = true;
    while (run) {
      // 메뉴 출력
      System.out.println("");
      System.out.println("1.리스트  2.등록  3.삭제  4.검색  5.종료");
      System.out.println("------------------------------------------");
      System.out.print(">메뉴번호: ");

      // 메뉴 입력
      int menuNum = sc.nextInt();
      sc.nextLine();

      // switch() 시작
      switch (menuNum) {

      // 1(리스트)
      case 1:
        System.out.println("<1.리스트>");
        showList();
        break;

      // 2(등록)
      case 2:
        System.out.println("<2.등록>");
        // 이름받기
        System.out.print("이름 > ");
        String name = sc.nextLine();
        // 휴대전화 받기
        System.out.print("휴대전화 > ");
        String hp = sc.nextLine();
        // 회사번호받기
        System.out.print("회사번호 > ");
        String company = sc.nextLine();

        // 리스트에 추가하기
        Person person = new Person();
        person.setName(name);
        person.setHp(hp);
        person.setCompany(company);

        pList.add(person);
        saveList();
        System.out.println("[등록되었습니다.]");
        break;

      // 3(삭제)
      case 3:
        System.out.println("<3.삭제>");
        System.out.print(">번호 : ");
        int no = sc.nextInt();

        pList.remove(no - 1);

        // 파일에 저장
        saveList();
        System.out.println("[삭제되었습니다.]");
        break;

      // 4(검색)
      case 4:
        System.out.println("<4.검색>");
        System.out.print(">이름: ");
        String keyword = sc.nextLine();

        showList(keyword);

        break;

      // 5(종료)
      case 5:
        System.out.println("종료");
        run = false;
        break;
      // 없는 번호일때
      default:
        System.out.println("[다시 입력해주세요.]");
        break;

      }// switch() 종료

    } // while 종료
    sc.close();

    // 종료화면
    System.out.println("");
    System.out.println("******************************************");
    System.out.println("*              감사합니다                   *");
    System.out.println("******************************************");
  }

  // 파일을 읽어 리스트에 담아 전달한다.
  public static void getList() throws IOException {
    Reader fr = new FileReader("phoneDB.txt");
    BufferedReader br = new BufferedReader(fr);

    pList = new ArrayList<Person>();

    while (true) {
      String line = br.readLine();
      if (line == null) {
        break;
      }

      String[] data = line.split(",");
      String name = data[0];
      String hp = data[1];
      String company = data[2];

      Person phone = new Person(name, hp, company);

      pList.add(phone);

    }
    br.close();
  }

  // 모든 리스트를 출력한다.
  public static void showList() {
    showList(""); // 아래함수에 키워드를 아무것도 없는 값으로 전달
  }

  // 이름으로 검색된 리스트의 정보를 출력한다.
  public static void showList(String keyword) {
    for (int i = 0; i < pList.size(); i++) {
      String serchName = pList.get(i).getName();
      if (serchName.contains(keyword)) {
        System.out.print(i + 1 + ".   ");
        System.out.print(pList.get(i).getName() + "\t");
        System.out.print(pList.get(i).getHp() + "\t");
        System.out.print(pList.get(i).getCompany() + "\t");
        System.out.println("");
      }
    }
  }

  // 리스트를 파라미터로 받아 파일에 저장한다.
  public static void saveList() throws IOException {
    Writer fw = new FileWriter("phoneDB.txt");
    BufferedWriter bw = new BufferedWriter(fw);

    // 문자열 만들기
    String str = "";
    for (int i = 0; i < pList.size(); i++) {
      str += pList.get(i).getName() + ",";
      str += pList.get(i).getHp() + ",";
      str += pList.get(i).getCompany() + "\n";

    }
    // 문자열 저장
    bw.write(str);
    bw.flush();

    bw.close();
  }

}

 

 

관련 문제2

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;

public class Account {
	private String accountNo; // 계좌번호
	private int balance;      // 현재잔액
	FileWriter fout = null;   // 출력파일
	String[] tmp = null;
	String anum = "", name, pnum, money, ex, path, time, f;
	String regex = "[0-9]{3,6}-[0-9]{2,6}-[0-9]{2,6}-?[0-9]{1,3}";
	String nameregex = "^[가-힣]{1,5}+$"; // ^[가-힣a-zA-Z]{1,5}+$ 한글+영문
	String pnumrepex = "(02|01|[0-9]{3})-([0-9]+)-([0-9]{4})"; // ([0-9]{3,4})-([0-9]{3,4})-([0-9]{4})

	DecimalFormat dc = new DecimalFormat("###,###,###,###");
	Scanner sc = new Scanner(System.in);
	SimpleDateFormat format2 = new SimpleDateFormat("yyyy-MM-dd");
	
	// 계좌번호에 해당하는 파일열기
	public String getF(String anum) {
		try {
			fout = new FileWriter(getPath() + anum + ".txt", true);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return f;
	}
	
	// 현재 시간 얻어오기
	public String getTime() {
		Date time1 = new Date();
		time = format2.format(time1);
		return time;
	}
	
	// 파일 열기위한 경로 지정하고 경로값만 얻어오기
	public String getPath() {
		try {
			path = AccountApp.class.getResource("").getPath();
			path = java.net.URLDecoder.decode(path, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return path;
	}

	public Account(String string) {
		accountNo = string;
		System.out.println(accountNo);
	}

	public Account() {
	}

	public int getBalance() {
		return this.balance;
	}

	public void setBalance(String balance) {
		this.balance = Integer.parseInt(balance);
	}
	
	// 종료 실행
	public boolean shutdown(boolean run) {
//		try {
			System.out.println("종료");
			//getF(anum);
			//fout.write(getTime() + ".\t0.\t0.\t" + dc.format(balance));
			//fout.write("\r\n", 0, 2);
			//fout.close();
//		} catch (IOException e) {
//			e.printStackTrace();
//		}
		return false;
	}
	
	// 예금 실행
	public void deposit() {
		try {
			getF(anum);
			System.out.print("예금액:");

			money = sc.nextLine();
			System.out.println(Integer.parseInt(money));

			if (Integer.parseInt(money) == 0) {
				System.out.println("0원은 예금할 수 없습니다.");
			} else if (Integer.parseInt(money) < 0) {
				System.out.println("금액에 오류가 있습니다.");
			} else {
				balance += Integer.parseInt(money);
				System.out.println("예금되었습니다. 잔액:" + dc.format(balance) + "원");
				fout.write(getTime() + ".\t" + dc.format(Integer.parseInt(money)) + ".\t0.\t" + dc.format(balance));
				fout.write("\r\n", 0, 2);
				fout.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	// 출금 실행
	public void witdraw() {
		try {
			getF(anum);
			System.out.print("출금액:");

			money = sc.nextLine();
			if (Integer.parseInt(money) == 0) {
				System.out.println("0원은 출금할 수 없습니다.");
			} else if (balance >= Integer.parseInt(money) && Integer.parseInt(money) > 0) {
				balance -= Integer.parseInt(money);
				System.out.println("출금되었습니다. 잔액:" + dc.format(balance) + "원");
				fout.write(getTime() + ".\t0.\t" + dc.format(Integer.parseInt(money)) + ".\t" + dc.format(balance));
				fout.write("\r\n", 0, 2);
			} else if (Integer.parseInt(money) > balance) {
				System.out.println("잔액이 부족합니다. 잔액:" + dc.format(balance) + "원");
			} else {
				System.out.println("금액에 오류가있습니다.");
			}

			fout.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	// 잔액 조회
	public void printBalance() {
		try {

			getF(anum);
			System.out.println("잔액조회 :" + dc.format(balance) + "원");
			//fout.write(getTime() + ".\t0.\t0.\t" + dc.format(balance));
			//fout.write("\r\n", 0, 2);
			fout.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	// 조회기간 입력 및 날짜포맷 체크 후 해당 기간의 내역 출력 (새로운 파일접근 사용)  
	public void date_check() {
		Date day1 = null;
		Date day2 = null;

		try {
			System.out.println("※yyyy-mm-dd 방식으로 입력하십시오.");
			System.out.print("시작기간을 입력하세요 : ");
			Date year1 = format2.parse(sc.nextLine());
			System.out.print("종료기간을 입력하세요 : ");
			Date year2 = format2.parse(sc.nextLine());
			System.out.println();
			System.out.println("----------------조회 내역-----------------");
			FileReader filereader = new FileReader(getPath() + anum + ".txt");
			BufferedReader bufReader = new BufferedReader(filereader);
			String temp = "";
			day1 = year1;
			day2 = year2;

			while ((temp = bufReader.readLine()) != null) {
				String t = temp.replace("\t", "").replace(" ", "");
				tmp = t.split("[.]");
				try {
					int compare = day1.compareTo(format2.parse(tmp[0]));
					int compare2 = day2.compareTo(format2.parse(tmp[0]));

					if (compare <= 0 && compare2 >= 0) {
						System.out.print("출력:");
						for (int i = 0; i < tmp.length; i++) {
							System.out.print(tmp[i] + "\t");
						}
						System.out.println();
					} else {
//					System.out.println("아냐");
					}
				} catch (ParseException e) {
					continue;
				}
			}
			bufReader.close();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ParseException e) {
			System.out.println("올바르지 않은 날짜 형식입니다.ex)2020-01-01과 같이 입력해주십시오.");
		}

	}

	public void accountinfo() {
		try {
			String path = AccountApp.class.getResource("").getPath();
			path = java.net.URLDecoder.decode(path, "UTF-8");
			while (true) {
				System.out.print("계좌번호 입력: ");
				anum = sc.nextLine();
				File file = new File(path + anum + ".txt");
				boolean isExists = file.exists();
				
				//파일이 존재한다면 계좌가 이미 개설된 상태
				if (isExists) {
					fout = new FileWriter(file, true);
					System.out.println("보유계좌입니다. 불러오는중...");
					FileReader filereader = new FileReader(path + anum + ".txt");
					BufferedReader bufReader = new BufferedReader(filereader);
					String temp = "";
					while ((temp = bufReader.readLine()) != null) {
						String t = temp.replace("\t", "").replace(",", "");
						tmp = t.split("[.]");
					}
					setBalance(tmp[3]);
					bufReader.close();
//					fout.write("--------------------");
//					fout.write("\r\n", 0, 2);
					break;
				// 파일이 없으므로 신규 계좌 개설 해야함
				} else {
					if (anum.matches(regex)) {
						System.out.println("신규계좌입니다. 계좌생성중...");
						while (true) {
							System.out.print("이름 입력: ");
							name = sc.nextLine();
							if (name.matches(nameregex)) {
								new Account(anum + " | " + name);
								break;
							} else {
								System.out.println("이름 형식이 올바르지 않습니다.");
								continue;
							}

						}
						while (true) {
							System.out.print("연락처 입력: ");
							pnum = sc.nextLine();
							if (pnum.matches(pnumrepex)) {
								new Account(anum + " | " + name + " | " + pnum);
								break;
							} else {
								System.out.println("연락처 형식이 올바르지 않습니다. ex)010-0000-0000과 같이 입력해주세요.");
								continue;
							}

						}
						fout = new FileWriter(file, true);
						fout.write("계좌번호 : " + anum + " 성명 : " + name + " 연락처 : " + pnum);
						fout.write("\r\n", 0, 2);
						fout.write("날짜\t" + "예금\t" + "출금\t" + "잔액");
						fout.write("\r\n", 0, 2);
						break;
					} else {
						System.out.println("계좌번호 형식이 올바르지않습니다. ex)110-000-0000과 같이 입력해주세요.");
						continue;
					}
				}
			}
			fout.close();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (java.lang.ArrayIndexOutOfBoundsException e) {
			System.out.println("파일이 잘못되었습니다. 관리자에게 문의하세요.");
			System.exit(0);
		}
	}

}
import java.io.FileNotFoundException;
import java.util.Scanner;

public class AccountApp {
	public static void main(String[] args) throws FileNotFoundException {
		boolean run = true;
		Scanner sc = new Scanner(System.in);
		Account b = new Account();
		b.accountinfo();

		while (run) {
			try {
				System.out.println("-----------------------------------------");
				System.out.println("1.예금 | 2.출금 | 3.잔고 | 4.기간별조회 | 5.종료");
				System.out.println("-----------------------------------------");
				System.out.print("선택 : ");
				int menuNo = Integer.parseInt(sc.nextLine());
				switch (menuNo) {
				case 1:
					b.deposit();
					break;
				case 2:
					b.witdraw();
					break;
				case 3:
					b.printBalance();
					break;
				case 4:
					b.date_check();
					break;
				case 5:
					run = b.shutdown(run);
					break;
				default:
					System.out.println("잘못누르셨습니다.");
					break;
				}
			} catch (java.util.InputMismatchException | java.lang.NumberFormatException e) {
				System.out.println("잘못누르셨습니다.");
				sc = new Scanner(System.in);
			}
		}
		sc.close();
	}
}
profile

Devlog

@덩이

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!

검색 태그