버글버글
Java 수업 기록 (23) IO - Reader 본문
▶ 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() |
아, ㄴ, 녀, ㅇ (이런 느낌) |
- 한 바이트씩 읽어온다. |
'java > java 수업 기록' 카테고리의 다른 글
Java 수업 기록 (25) IO - InputStream (0) | 2022.08.17 |
---|---|
Java 수업 기록 (24) IO - OutputStream (0) | 2022.08.16 |
Java 수업 기록 (22) IO - Writer (0) | 2022.08.14 |
Java 수업 기록 (21) IO - File (0) | 2022.08.13 |
Java 수업 기록 (20) Collection Framework - Iterator, Collections (0) | 2022.08.12 |