버글버글

Java 수업 기록 (23) IO - Reader 본문

java/java 수업 기록

Java 수업 기록 (23) IO - Reader

Bugle 2022. 8. 15. 00:00
반응형

▶ IO 

▶ Reader 

▶ FileReader class 

1. file 객체에 등록된 파일이 없으면 FileNotFoundException 발생

    (FileNotFoundException은 IOException이 부모이다. 그래서 IOException을 사용해도 무방하다.)

* java.io.FileReader

* 생성

FileReader fr = new FileReader("");
Exception을 안했기 때문에 위와 같이 하면 오류가 발생한다.
Reader와 Writer는 Exception을 해줘야 한다.

* 입력 데이터

1. 1글자 : int

2. 여러 글자 : char[] (배열임. 주의할 것)

* read() 메소드
1. 읽은 문자를 반환
2. 모두 읽어서 읽은 문자가 없으면 -1 반환

예시) 한 글자씩 읽기

		File file = new File("C:\\storage", "m2.txt");
		FileReader fr = null;
		
		try {
			// FileReader 클래스 생성
			fr = new FileReader(file);
			
			// 입력 데이터
			int c;
			
			// read() 메소드
			while(true) {
				c = fr.read();
				if(c == -1) {
					break;
				}
				System.out.print((char)c);
				// c의 데이터 타입은 int이기 때문에 char로 강제 캐스팅 해줘야 한다.
				// 캐스팅을 안할 경우, c의 아스키 코드가 보여질 것이다.
			}		
		} catch (IOException e) {
			e.getStackTrace();
		} finally {
			try {
				if(fr != null) {
					fr.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
	
		}
        
        	// I am IronMan

* 위 코드를 작업할 때에는 File file = new File의 경로(C드라이브, storage 폴더, m2.txt 파일)에

   파일이 있어야 실행 가능하다. file 객체에 등록된 파일이 없으면 FileNotFoundException 발생


* 위 코드를 Strign str에 파일 내용 정리하기

		File file = new File("C:\\storage", "m2.txt");
		FileReader fr = null;
		
		try {
			fr = new FileReader(file);
			
			int c;
			
			// String str에 파일 내용 저장하기
			String str = "";
			while(true) {
				c = fr.read();
				if(c == -1) {
					break;
				}
				str += ((char)c);
			}
			System.out.println(str);
		} catch (IOException e) {
			e.getStackTrace();
		} finally {
			try {
				if(fr != null) {
					fr.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
	
		}
		// I am IronMan

* 위 코드는 += 연산을 많이 해서 좋지 않은 코드다. 


* 그래서 StringBuilder를 사용한다.

		File file = new File("C:\\storage", "m2.txt");
		FileReader fr = null;
		
			fr = new FileReader(file);
			
			int c;
			
			StringBuilder sb = new StringBuilder();
			while(true) {
				c = fr.read();
				if(c == -1) {
					break;
				}
				sb.append((char)c);
			}
			String str = sb.toString();
			System.out.println(str);
		} catch (IOException e) {
			e.getStackTrace();
		} finally {
			try {
				if(fr != null) {
					fr.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
	
		}
		// I am IronMan

*무한루프 아닌 버전

	
		File file = new File("C:\\storage", "m2.txt");
		FileReader fr = null;
		
		try {

			fr = new FileReader(file);
			int c;
			StringBuilder sb = new StringBuilder();
            
			while((c = fr.read()) != -1) {
				sb.append((char)c);
				
			}
	
			String str = sb.toString();
			System.out.println(str);
			
		} catch (IOException e) {
			e.getStackTrace();
		} finally {
			try {
				if(fr != null) {
					fr.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
	
		}

 

* 여러 글자 읽어보기

5글자를 저장할 배열
char[] cbuf = new char[5];

read(char[] cbuf) 메소드
1. 읽은 글자는 cbuf 배열에 저장
2. 실제로 읽은 글자 수를 반환
3. 읽은 글자가 없으면 -1 반환

만약 13글자가 있을때, 5글자씩 읽어라 러고한다면,
1. 5글자 읽고
2. 5글자 읽고
3. 3글자 읽고 (여기서 실수를 많이 함)4. 읽을 글자가 없으니 -1 반환

 

예시)

		
		File file = new File("C:\\storage", "m3.txt");	// 나는 아이언맨 이다. 너는 타노스냐?
		FileReader fr = null;
		
		try {
			
			fr = new FileReader(file);
			
			char[] cbuf = new char[5];

			while(true) {
				
				int readCnt = fr.read(cbuf);
				// cbuf =  나는 아이 까지 읽히고(길이가 5인 배열, 읽어드림)
				// reaCnt에는 5글자?가 들어간다.
				
				if(readCnt == -1) {
					break;
				}
				
				for(int i = 0; i < readCnt; i++) {
					// (!주의)cbuf.lenght가 아닌 readCnt가 들어가야한다. 읽은 글자 수(readCnt) 만큼 반복.
					System.out.print(cbuf[i]);
				}
								
			}
			
		} catch(IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if(fr != null) {
					fr.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		// 나는 아이언맨이다.
		// 너는 타노스냐?

예시)

apple
mango

를 읽는다고 가정하면

  readCnt cbuf
1 5 a p p l e
2 5 \n m a n g
3 2 o \n
4 -1  

1번째 읽고 덮어쓰기 진행한다.

3번째에서 덮어쓰기 할 문자가 없기 때문에, o \n a n g로 읽힌다. (덮어쓰기를 못한 a n g 가 그대로 내려온다.)

 

예시) m3.txt 읽어서 String str에 저장하기

m3.txt
apple
mango

		File file = new File("C:\\storage", "m3.5.txt");
		FileReader fr = null;
		
		try {
			
			fr = new FileReader(file);
			
			char[] cbuf = new char[5];
			StringBuilder sb = new StringBuilder();
			
			while(true) {
				
				int readCnt = fr.read(cbuf);
				if(readCnt == -1) {
					break;
				}
				sb.append(cbuf, 0, readCnt); // cbuf 배열의 인덱스 0부터 readCnt개만 추가로
								
			}
			String str = sb.toString();
			System.out.println(str);			
			
		} catch(IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if(fr != null) {
					fr.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

 


*무한루프 아닌 버전 (무한루프는 학습용이고 실무에서는 아래 코드를 사용할 것)

		File file = new File("C:\\storage", "m3.5.txt");
		FileReader fr = null;
		
		try {
			
			fr = new FileReader(file);

			char[] cbuf = new char[5];
			StringBuilder sb = new StringBuilder();
			int readCnt;
			while((readCnt = fr.read(cbuf)) != -1) {
				sb.append(cbuf, 0, readCnt);
			}
			String str = sb.toString();
			System.out.println(str);
			
		} catch(IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if(fr != null) {
					fr.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

 

▶ BufferedReader 

1. FileReader는 느리기 때문에 BufferedReader를 추가해서 속도를 향상시킨다.
2. BufferedReader는 readLine() 메소드를 지원한다.
3. readLine() 메소드는 한 줄씩 읽어서 String에 저장한다.
4. 읽은 내용이 없으면 null을 반환한다.

 

예시)

		File file = new File("c:\\storage", "m3.5.txt");
		FileReader fr = null;
		BufferedReader br = null;
		try {
			fr = new FileReader(file);
			br = new BufferedReader(fr);
			StringBuilder sb = new StringBuilder();
			String line = null;
			while((line = br.readLine()) != null) {
				sb.append(line + "\n");
			}
			String str = sb.toString();
			System.out.println(str);
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if(br != null);{
					br.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

 


* try - catch - resources문으로 다시 풀어보기 (최종 코드. 아래 코드만 외우면 된다..)

		try (BufferedReader br = new BufferedReader(new FileReader("c:\\storage\\m3.5.txt"))) {

			StringBuilder sb = new StringBuilder();
			String line = null;
			while((line = br.readLine()) != null) {
				sb.append(line + "\n");
			}		
			String str = sb.toString();
			System.out.println(str);		
		} catch (IOException e) {
			e.printStackTrace();
		}

 

 

▶ CSV Reader 

- c:\\storage폴더 안의 product 파일 읽어보기

예시) procut 클래스

public class Product {
	
	private String number;
	private String name;
	private int price;
	
	public Product() {	
	}
	public Product(String number, String name, int price) {
		super();
		this.number = number;
		this.name = name;
		this.price = price;
	}

	public String getNumber() {
		return number;
	}
	public void setNumber(String number) {
		this.number = number;
	}	
	public String getName() {
		return name;
	}	
	public void setName(String name) {
		this.name = name;
	}	
	public int getPrice() {
		return price;
	}	
	public void setPrice(int price) {
		this.price = price;
	}
	@Override
	public String toString() {
		return "Product [number=" + number + ", name=" + name + ", price=" + price + "]";
	}
}

CSVReader main 메소드)

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class CSVReader {

	public static void main(String[] args) {

		File file = new File("c:\\storage", "product.csv");
		
		try (BufferedReader br = new BufferedReader(new FileReader(file))){
			
			// (사용을 안하면서)첫 행 읽어 버리기 
			br.readLine();
			
			// 한 줄 읽어서 Product 객체 생성하고 ArrayList에 저장하기
			List<Product> products = new ArrayList<Product>();
			String line = null;
			while((line = br.readLine()) != null) {
				String[] arr = line.split(",");
				Product product = new Product();
				product.setNumber(arr[0]);
				product.setName(arr[1]);
				product.setPrice(Integer.parseInt(arr[2]));
				products.add(product);
			}
		
			// ArrayList 확인
			for(Product product : products) {
				System.out.println(product);
			}		
			
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

}

 

 

▶ XML Reader 

- c:\\storage폴더 안의 product 파일 읽어보기

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class XMLReader {

	public static void main(String[] args) {
		
		try {
		
			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
			DocumentBuilder builder = factory.newDocumentBuilder();
			File file = new File("C:\\storage", "product.xml");
			Document document = builder.parse(file);		// product.xml을 파싱(분석)한 document 객체
			
			// 최상위 요소(root)
			Element root = document.getDocumentElement();
			System.out.println("최상위 요소 : " + root.getNodeName());
			
			List<Product> products = new ArrayList<Product>();
			
			// 최상위 요소의 자식 노드들
			NodeList nodeList = root.getChildNodes();
			for(int i = 0; i < nodeList.getLength(); i++) {
				Node node = nodeList.item(i);
				// 줄바꿈(#text)과 <product>태그로 구성
				// 배열이라 nodeList[i] 이게 맞지만 nodeList.item(i)로 써야한다.
				if(node.getNodeType() == Node.ELEMENT_NODE) {
					// 노드가 Element 인가? (줄 바꿈 #text 제외되고 <product> 태그만 남음)
					NodeList nodeList2 = node.getChildNodes();
					// <product> 태그의 자식노드(줄바꿈 #text, <number>, <name>, <price> 태그)
					Product product = new Product();
					for(int j = 0; j < nodeList2.getLength(); j++) {
						Node node2 = nodeList2.item(j); 
						if(node2.getNodeType() == Node.ELEMENT_NODE) {
							switch(node2.getNodeName()) {
							case "number" : product.setNumber(node2.getTextContent()); break;
							case "name" : product.setName(node2.getTextContent()); break;
							case "price" : product.setPrice(Integer.parseInt(node2.getTextContent())); break;
							}
						}
					}
					// ArrayList에 product 추가
					products.add(product);
				}
			}
			
			// ArrayList 확인
			for(Product product : products) {
				System.out.println(product);
			}
			
		} catch(Exception e) {
			e.printStackTrace();
		}
	}

}

▶ JSON Reader 

** 중요

- c:\\storage폴더 안의 product 파일 읽어보기

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONObject;

public class JSONReader {
	
	public static void main(String[] args) {
		
		File file = new File("C:\\storage", "product.json");
		
		try(BufferedReader br = new BufferedReader(new FileReader(file))) {
			
			StringBuilder sb = new StringBuilder();
			String line = null;
			while((line = br.readLine()) != null) {
				sb.append(line);
			}
			String str = sb.toString();
			JSONArray arr = new JSONArray(str);
			
			List<Product> products = new ArrayList<Product>();
			for(int i = 0, length = arr.length(); i < length; i++) {
				JSONObject obj = arr.getJSONObject(i);
				Product product = new Product();
				product.setNumber(obj.getString("number"));
				product.setName(obj.getString("name"));
				product.setPrice(Integer.parseInt(obj.getString("price")));
				products.add(product);
			}
			
			for(Product product : products) {
				System.out.println(product);
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

 

 

 

▶ 기타사항

1. FileReader와 FileInputStream의 차이점

  안녕
FileReader - read()
- read()
안, 녕 - 한 글자씩 읽어온다.
FileInputStream - read()
- read()
- read()
- read()
아, ㄴ, 녀, ㅇ
(이런 느낌)
- 한 바이트씩 읽어온다.

 

반응형