JAVA API
: application programming interface
- 미리 만들어진 기능인 라이브러리
- API안에 많은 패키지들이 존재 (lang, util, IO 등)
메서드 모형 읽는 법
접근제어자 + (매개변수) + ;(결과) 반환 유형 - 클래스가 선언된 위치
접근제어자 구분
public private default protected
java.io 패키지
Input & Output
- java.io 패키지에서 담당
- 디렉토리 구분 기호
Windows: \
Windows 이외: /
직접 지정하면 운영체제 별로 따로 설정 – File.seperator를 이용하면 현재 운영체제의 구분 기호를 사용할 수 있음 - 경로
절대 경로: 루트로부터의 위치
Windows -> 루트드라이브:\디렉토리경로\파일이름
Web -> 프로토콜://자원경로
그 이외의 경우 -> /루트디렉토리/디렉토리경로/파일이름
Windows 경우는 디렉토리 기호가 \ 그 이외의 경우는 /
상대 경로: 현재 위치로부터의 경로
./: 현재 디렉토리
../: 상위 디렉토리 - File 처리는 대부분의 경우 예외 처리를 강제함
File
- 파일에 대한 정보를 제공하는 클래스
생성자
- File(String 파일 경로)
- File(String 부모경로, String 자식경로)
- File(File 부모경로, String 자식경로)
주요 메서드
- delete - 파일, 디렉토리 삭제
- exists - 파일, 디렉토리 존재 여부 확인
- lastModified - 마지막 수정 날짜 (밀리초 단위로 표시)
- length - 파일의 길이
- renameTo - 파일의 이름 바꾸기
클라이언트 서버 시스템에서의 파일 다운로드
- 파일의 존재 여부를 확인해서 다운로드
- 파일의 변경 여부(마지막 수정 날짜 나 크기)를 확인해서 다운로드
MainClass
package _api.io.fileInfomation;
import java.io.File;
import java.util.Date;
public class MainClass {
public static void main(String[] args) {
//파일에 대한 정보 확인
try {
//File 인스턴스 생성
//Windows 에서는 디렉토리 구분 기호가 \인데
//프로그래밍 언어에서는 \가 오고 하나의 문자가 오면 제어문자로 인식
//\를 입력하고자 할 때는 \\이렇게 해야 합니다.
File f = new File("C:\\Users\\user\\Desktop\\지원\\1026강의.txt");
//파일의 존재 여부 확인
System.out.println(f.exists()); // true 존재함
//마지막 수정 날짜
System.out.println(f.lastModified()); //1666857518000
System.out.println(new Date(f.lastModified())); //Thu Oct 27 16:58:38 KST 2022
}catch(Exception e) {
System.out.println(e.getLocalizedMessage());
}
}
}
Stream
- 입출력 할 때의 스트림이 있고,
람다와 스트림에서 처럼 여러 개의 데이터를 순차적으로 처리하기 위한 스트림이 있음 - 입출력에서의 스트림은 데이터를 운반하는데 사용하는 연결 통로
- 입력 스트림
출력 스트림 - 바이트 스트림: 일반적인 파일처리 (텍스트, 이미지, 동영상 등 모든 종류 처리 가능)
문자 스트림: 문자를 읽고 쓰는 경우에만 사용 (문자 스트림을 사용할때는 인코딩에 주의해야 함)
파일 - 통신 | ||||
스트림 생성 | ||||
Byte Stream (텍스트 파일을 제외한 모든 자) |
Character Stream (텍스트 파일) |
|||
ObjectInputStream ObjectOutputStream |
파일을 읽고, 출력 | FileReader | FileWriter | |
FileInputStream | FileOutputStream | |||
▼ | ▼ | ▼ | ▼ | |
버퍼를 하기 위한 | BufferedReader | PrintWriter | ||
BufferedInputStream | PrintStream |
출처: https://simpleis-best.tistory.com/36
Byte Stream
바이트 스트림(Byte Stream)은 데이터를 바이트(byte) 단위로 읽고 쓰는 입출력 스트림입니다. 데이터를 8비트 바이트의 형태로 처리하기 때문에 텍스트, 이미지, 동영상 등 모든 종류의 데이터를 처리할 수 있습니다.
바이트 스트림은 주로 이진 데이터를 처리하는 데 사용됩니다. 이진 파일을 읽고 쓰기 위해 사용되며, 네트워크 통신에서도 주로 바이트 스트림을 사용합니다. 예를 들어, 파일의 내용을 읽어 메모리에 로드하거나, 네트워크를 통해 파일을 전송하고 받을 때 바이트 스트림을 사용합니다.
자바에서는 InputStream과 OutputStream 클래스를 통해 바이트 스트림을 다룰 수 있습니다. FileInputStream과 FileOutputStream은 파일에서 바이트 스트림을 읽고 쓰는 데 사용되며, Socket 클래스의 getInputStream()과 getOutputStream() 메서드를 통해 네트워크 소켓의 입출력 스트림을 얻을 수도 있습니다.
바이트 스트림은 특정 데이터의 내부 구조나 포맷을 신경 쓰지 않고, 단순히 바이트의 연속으로 처리하기 때문에 다양한 종류의 데이터를 다룰 수 있습니다. 그러나 텍스트 데이터를 처리할 때는 문자 인코딩과 관련하여 주의해야 합니다. 텍스트 데이터의 경우 문자 인코딩을 지정하여 올바르게 처리해야 정확한 결과를 얻을 수 있습니다.
출처: 챗 gpt
InputStream과 OutputStream
- 바이트 스트림의 최상위 클래스로 추상 클래스 (인스턴스 생성을 못 함)
- 다른 바이트 스트림들이 가져야 하는 메서드 원형을 소유
InputStream - 파일 읽기
- int available(): 읽을 수 있는 바이트 수 리턴 ▶ 읽어서 저장할 바이트 배열 생성시 크기
- void close(): 닫기
- int read(): 한 바이트를 밁어서 정수로 리턴하고 읽지 못하면 음수(-1)를 리턴
- int read(byte[] b) : byte b배열 만큼 읽어서 b에 저장하고 읽은 개수를 리턴 - 0이나 음수가 리턴되면 읽기 실패
- int read(byte[] b, int offset, int length) : offset부터 length 만큼 읽어서 b에 저장하고 읽은 개수를 리턴
- long skip(long n): n만큼 넘어가기
OutputStream - 파일 작성
- void close(): 닫기
- void write(int n): n을 기록
- void write(byte[] b): b 배열을 기록
- void write(byte[] b, int offset, int length): b 배열에서 offset에서 length 만큼 기록
- void flush(): 버퍼의 내용을 출력
스트림은 열면 반드시 닫아야 함
바이트 단위 파일 입출력
FileInputStream과 FileOutputStream
바이트 단위로 파일에 기록 → 바이트 단위로 파일에 기록을 하는 클래스: FileOutputStream
MainClass
package _api.io.bytefileprocessing;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
public class MainClass {
public static void main(String[] args) {
//바이트 단위로 파일에 기록하기
try {
//오늘 날짜는 문자열로 만들기
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
//기록할 파일 만들기
FileOutputStream fos = new FileOutputStream("C:\\Users\\user\\Desktop\\지원\\" + sdf.format(date) + ".txt", true);
//아무것도 안 쓰면 덮어쓰고, true를 쓰면 이어서 씀
//절대 경로: 지원뒤에 \\역슬래쉬가 있어야 그 안에 파일을 만든다는 이야기가 됨
//경로가 잘못되면 파일 기록 실패
//C:\Users\ user\Desktop\이지원\2022-10-27.txt (지정된 경로를 찾을 수 없습니다) 리턴
//기록할 메세지 생성
String msg = "파일에 덮어쓰기\n";
//파일에 기록
fos.write(msg.getBytes());
//파일을 닫기
fos.close();
}catch(Exception e) {
System.out.println("파일 기록 실패");
System.out.println(e.getLocalizedMessage());
}
//앞에서 작성한 파일 읽기
try {
//읽기 위한 파일 생성
FileInputStream fis = new FileInputStream("C:\\Users\\user\\Desktop\\지원\\2022-10-27.txt");
//읽어서 저장할 바이트 배열을 생성
byte[] b = new byte[fis.available()];
//읽기 - 어디에 덮어쓸지 저장을 해야함
fis.read(b);
//읽은 내용 확인 - 문자로 바꿔줌
System.out.println(new String(b));
// System.out.println(Arrays.toString(b)); //숫자로 보고 싶을 때
fis.close();
}catch(Exception e) {
System.out.println(e.getLocalizedMessage());
}
}
}
- FileOutputStream 생성자의 두 번째 매개변수를 true로 설정하면, 새로운 FileOutputStream 객체가 해당 파일을 덮어쓰기(write) 모드로 열리는 대신에, 기존 파일의 끝에 데이터를 추가하는(append) 모드로 열림
- 기존 파일에 데이터를 추가하는 모드로 열게 되면, 새로운 데이터가 기존 파일의 끝에 이어서 쓰여지게 됨
- 따라서, 기존 파일의 내용을 유지한 채로 새로운 데이터를 추가할 수 있음
Buffering 버퍼링
버퍼를 이용한 입출력
- Java 코드로 입출력하는 작업을 작성하면 실제로는 JVM이 운영체제의 Native Method를 호출해서 처리합니다.
- 자주 입출력을 하는 경우 작업을 할 때 마다 Nation Method를 호출하면 시스템의 성능이 나빠질 수 있습니다.
- 이런 경우에는 버퍼를 이용하여 입출력 횟수를 줄이는 것이 좋습니다.
버퍼를 이용하는 바이트 단위 입출력은 BufferedInputStream(읽기)과 PrintStream(쓰기)을 이용합니다.
버퍼에 기록을 할 때는 write메서드 대신에 print 메서드를 사용할 수 있으면 flush 메서드를 이용해서 버퍼의 내용을 전부 출력할 수 있습니다.
표준 출력 스트림이 System.out 인데 이 스트림의 자료형이 PrintStream
(아무것도 없으면 보통 모니터이고, 모니터없으면 프린터로 바꿈)
표준 입력 스트림 System.in (아무것도 없으면 보통 키보드, 키보드 없으면 바코드로 바꿈)
ByteBufferStream
package _api.io.bufferstream;
import java.io.FileOutputStream;
import java.io.PrintStream;
public class ByteBufferStream {
public static void main(String[] args) {
try {
//버퍼를 이용해서 문자열을 출력하는 스트림 만들기
PrintStream ps = new PrintStream(new FileOutputStream("./buffer.txt"));
ps.print("문자열을 버퍼를 이용해서 출력");
ps.flush();
ps.close();
}catch(Exception e) {
System.out.println(e.getLocalizedMessage());
}
}
}
- ./buffer.txt - 현재 디렉토리에 buffer.txt 파일을 만들어서 그 안에 "문자열을 버퍼를 이용해서 출력" 이라고 생성
BufferedReader vs Scanner
- 문자열을 입력받는데 사용
- BufferedReader:
InputStreamReader는 문자열을 한 글자 단위로 읽어들이므로 비효율적으로 이를 보완하기 위해 사용
버퍼링 기능이 추가된 class로 일정한 크기의 데이터를 한번에 읽어와 버퍼에 보관 후, 사용자의 요청이 있을 때 버퍼에서 데이터를 읽어오는 방식으로 동작
속도가 향상되고, 시간 부하가 적음
라인 단위로 입력 받으므로 공백도 String으로 인식
입력받은 데이터가 String이기 때문에 다른 타입의 데이터일 경우 형변환 필요 - Scanner:
공란과 줄바꿈을 모두 입력값의 경계로 인식
입력 받는 시점에 데이터 타입이 결정되므로 형변환 필요 없음
BufferedReader | Scanner | |
Buffer size | 8192 | 1024 |
Syncronized | O | X |
Parsing | 단순히 읽어 들임 | 문자열 파싱 가능 |
Exception | IOException 던짐 | IOException 숨김 |
Character Stream (문자 스트림)
- Byte Stream을 이용하면 모든 종류의 IO 장치와 데이터를 읽고 쓰기 작업이 가능
- 컴퓨터는 기본적으로 바이트 단위로 작업을 수행하기 때문 - 문자 단위로 데이터를 입출력하는 경우 Byte Stream을 사용하게 되면 변환 작업이 필요
Reader & Writer
- 문자 단위로 읽고 쓰기 위한 메서드를 제공하는 추상 클래스 - 문자 스트림의 최상위 클래스
Reader 메서드 (PrintReader, FileReader)
- void close()
- int read(): 하나의 문자를 읽어오는 메서드로 문자의 코드를 리턴하는데 (읽는데) 실패하면 음수를 리턴
- int read(char[] buf): 문자를 buf의 크기만큼 읽어서 buf에 저장하고 읽은 개수를 리턴 - 리턴 값이 0보다 작거나 같으면 읽기 실패
- int read(char[] buf, int offset, int length): 문자를 offset부터 length 만큼 읽어서 buf에 저장하고 읽은 개수를 리턴 - 리턴 값이 0보다 작거나 같으면 읽기 실패
- int read(CharBuffer target)
- boolean ready()
- long skip(long n)
Writer 메서드 (PrintWriter, FileWriter)
- void close() - 사용한 시스템 자원을 반납하고 출력 스트림 닫음(OutputStream을 더 이상 사용하지 않을 경우에 호출)
- void flush() - 버퍼의 내용 전부 출력, 버퍼를 비우는 역할
- void write(String str)
- void write(String str, int offset, int length)
InputStreamReader & OutputStreamReader
- ByteStream을 CharacterStream으로 변환시켜주는 클래스
- InputStreamReader는 문자열을 한 글자 단위로 읽어들이므로 비효율적 ▶ 보완하기 위해 BufferedReader 사용
- 네트워크 프로그래밍에서 소켓은 ByteStream을 리턴하는데 주고 받는 데이터가 문자열이라면 ByteStream을 InputStreamReader 인스턴스로 변환해서 사용해야 함
new InputStreamReader (ByteStream 인스턴스)
FileReader & FileWriter
- 파일의 문자 단위로 읽고 쓰기 위한 클래스
BurfferedReader & PrintWriter
- BufferedReader는 버퍼를 이용해서 문자 단위로 읽어주는 클래스
이 클래스에는 String readLine() 이라는 메서드가 제공되서 줄 단위로 읽어갈 수 있음.
읽어낸 내용이 없으면 null을 리턴 - 아까 기록 안썼을 때 이거 떴었음 - PrintWriter는 버퍼를 이용해서 문자 단위로 기록하는 클래스
CharacterFileMain - 파일에 문자 단위로 기록하고 읽어오기
package _api.io.characterstream;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.PrintWriter;
//파일에 문자 단위로 기록하고 읽어오기
public class CharacterFileMain {
public static void main(String[] args) {
//파일에 문자열을 문자 단위로 기록하기: FileWriter 와 PrintWriter 이용
try {
//버퍼를 이용해서 파일에 문자열을 기록하는 클래스의 인스턴스를 생성
//한 번 기록하고 두번째 기록할 때 이어서 기록하는 인스턴스
//true를 생략하고 false를 설정하면 파일의 내용을 항상 새로 작성합니다.
PrintWriter pw = new PrintWriter(new FileWriter("ch.txt", true));
//문자열을 기록
//문자열을 기록할 때 , 나 공백 및 탭 등으로 구분이 가능한데 이렇게 만들어진 텍스트를 csv 라고 합니다.
//이 방식은 변하지 않는 고정적인 데이터를 기록할 때 주로 이용
pw.print("naver,한국\n");
pw.print("kakao,한국\n");
pw.print("google,미국\n");
//버퍼의 내용 전부 출력
pw.flush();
//닫기
pw.close();
}catch(Exception e) {
System.out.println(e.getLocalizedMessage());
};
//파일에 문자열을 문자 단위로 읽어오기: FileReader 와 BufferedReader 이용
//줄 단위로 읽어오기
try {
//문서 데이터를 줄 단위로 읽을 수 있는 인스턴스 생성
BufferedReader br = new BufferedReader(new FileReader("./ch.txt"));
//줄 단위로 읽어서 출력하기
while(true) {
//한 줄 읽기
String line = br.readLine();
//읽은 데이터 없으면 종료
if(line == null) {
break;
}
//읽은 데이터 출력
//System.out.println(line);
//읽은 문자열에서 , 를 기준으로 앞의 데이터만 출력
String[] arr = line.split(",");
System.out.println(arr[0]);
//읽은 문자열에서 , 를 기준으로 뒤의 데이터만 출력
String[] arr2 = line.split(",");
System.out.println(arr2[arr2.length-1]);
}
br.close();
}catch(Exception e) {
System.out.println(e.getLocalizedMessage());
}
}
}
WebTextDownload - 웹의 문자열 읽어오기
package _api.io.characterstream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class WebTextDownload {
public static void main(String[] args) {
try {
//읽어올 URL을 생성
URL url = new URL("https://www.naver.com/");
//URL에 연결
HttpURLConnection con = (HttpURLConnection)url.openConnection();
//문자열을 읽기 위한 스트림 생성
BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream()));
while(true) {
String line = br.readLine();
if(line == null) {
break;
}
System.out.println(line);
}
}catch(Exception e) {
System.out.println(e.getLocalizedMessage());
}
}
}
2023.07.05 - [프로그래밍 언어/Java] - [Java] java.io 패키지 - 로그 파일에서 ip 접속 횟수 출력
★★ 문자열을 분할하는 방법 ★★
굉장히 많이 사용해야 함
Incoding & Decoding
1. 특수한 문자를 기준으로 분할
String[] split(String 기준문자열): 기준 문자열을 기준으로 문자열을 분할해서 문자열 배열로 리턴
String msg = "Hello.Java.World";
String[] split = mgs.split(","); // Hellow / Java / World
System.out.println(splits[0]); // Hello
System.out.println(splits[1]); // Java
System.out.println(splits[2]); // World
여기 보고 다시 쓰기
2. 위치를 기준으로 분할
String msg = " Hello,Java,World";
String result = msg.subString(6); // Java World
String result1 = msg.substring(6, 10); // Java
데이터의 분류
하나의 데이터(scala data), Byte, Short, Character, Integer, Long, Float, Double, Boolean, String
여러 개의 데이터(vector data)
배열과 List(Collection): 동일한 종류의 비교 가능한 데이터 - 인덱스를 이용해서 데이터를 구분 (이렇게 주는 것은 없다라고 생각해도 됨)
VO클래스나 Map: 여러 개의 데이터를 하나로 묶을 때 사용 - 이름을 이용해서 데이터를 구분 (특별한 경우가 아니면 이거로 해야 함)
{} 배열, ()Map
맨 바깥은 무조건 (), 절대로 {}로 만들면 안 됨
get, put이라도 열심히 하자! 혹은 DTO나 VO만드는 연습해라~
Serializable(직렬화)
- 여기까지는 외우기
- 인스턴스를 다른 곳에 전송할 수 있도록 해주는 것
- 전송한다는 의미는 파일 단위로 읽고 쓰는 것도 전송으로 간주하고, 컴퓨터와 컴퓨터 또는 Component 와 Component 사이를 왔다갔다 하는 것도 전송한다고 함
- 이럴 때 사용하는 값의 집합을 나타내기 위한 인스턴스를 DTO(Data Transfer Object)
DTO는 왔다 갔다 / VO는 거기서만 사용 - Java 에서는 인스턴스 단위로 데이터를 전송하고자 하면 Serializable 인터페이스를 implements 하면 됨
원래 인터페이스는 implements하면 추상메서드 구현하라고 에러가 뜨는데 Serializable은 안써도 됨(유일) - 응용 프로그램을 만들 때 자신의 저장 형식을 갖고자 하는 경우 사용하고 안드로이드에서 Activity 사이에 데이터 전송하고자 하면 사용
- DataInputStream과 DataOutputStream을 이용해서 사용
- 데이터를 전송하고 전송받을 때 데이터는 항상 하나로 만들어두는 것이 좋음 - 위의 하나의 데이터의 분류 연결
실습
직렬화를 위한 DTO 클래스 생성
- 정수로 된 번호, 문자열로 된 이름, Date로 만들어진 생일 을 저장
SingerDTO
인스턴스 단위로 읽고 쓰기 가능한 클래스 - Serializable 인터페이스 때문
package _api.io.serializable;
import java.io.Serializable;
import java.util.Date;
//인스턴스 단위로 읽고 쓰기가 가능한 클래스 - Serializable 인터페이스 때문
public class SingerDTO implements Serializable{
private int num;
private String name;
private Date birthday;
public SingerDTO() {
super();
}
public SingerDTO(int num, String name, Date birthday) {
super();
this.num = num;
this.name = name;
this.birthday = birthday;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
@Override
public String toString() {
return "SingerDTO [num=" + num + ", name=" + name + ", birthday=" + birthday + "]";
}
}
SerializableMain
Main 클래스를 만들어서 직렬화한 1개의 인스턴스를 파일에 기록하고 읽어오기
package _api.io.serializable;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Date;
public class SerializableMain { //e-mail에 사용가능
public static void main(String[] args) {
try {
//인스턴스 단위로 파일에 기록할 수 있는 객체를 생성
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("serializable.txt"));
//기록할 인스턴스 생성
SingerDTO dto = new SingerDTO(1, "부승관", new Date(98,1-1,16));
//기록
oos.writeObject(dto);
oos.close();
}catch(Exception e) {
System.out.println(e.getLocalizedMessage());
}
// {}가 하나의 stack, 블럭을 만드니까 dto 인스턴스는 이름이 같아도 상관없음
try {
//인스턴스 단위로 파일에 읽어낼 수 있는 객체를 생성
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("serializable.txt"));
//하나의 데이터 읽어오기
SingerDTO dto = (SingerDTO)ois.readObject(); //Object로 들어오니 형변환 해야함
System.out.println(dto);
ois.close();
}catch(Exception e) {
System.out.println(e.getLocalizedMessage());
}
}
}
SerializableMain2
Main 클래스를 만들어서 직렬화한 여러 개의 인스턴스를 파일에 기록하고 읽어오기
package _api.io.serializable;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Date;
public class SerializableMain2 { //e-mail에 사용가능
public static void main(String[] args) {
/*
* try() 안에서 클래스가 AutoCloseable을 implements 하고 있으면, 검색이 끝날 때 자동으로 close()를 호출
*/
try (//인스턴스 단위로 파일에 기록할 수 있는 객체를 생성
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("multiobject.txt"));){
//기록할 인스턴스 생성
SingerDTO dto1 = new SingerDTO(1, "부승관", new Date(98, 1-1, 16));
SingerDTO dto2 = new SingerDTO(2, "버논", new Date(98, 2-1, 18));
//데이터는 하나로 만들기 ex)파워포인트 열 때 한번만 여는 것처럼
//기록할 인스턴스가 여러 개 이므로 하나의 List로 묶어줍니다.
ArrayList<SingerDTO> list = new ArrayList<>();
list.add(dto1);
list.add(dto2);
//기록
oos.writeObject(list);
}catch(Exception e) {
System.out.println(e.getLocalizedMessage());
}
try (//인스턴스 단위로 파일에 읽어낼 수 있는 객체를 생성
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("multiobject.txt"));){
//기록을 할 때 List를 사용했으므로 읽어올 때 List로 읽어와야 합니다.
//만들 때 어떻게 만든지 모르면 읽는게 안 됨
ArrayList list = (ArrayList)ois.readObject();
for(Object obj : list) {
System.out.println(obj);
}
}catch(Exception e) {
System.out.println(e.getLocalizedMessage());
}
}
}
Try - resources
- jdk 1.7에서부터 지원되는 문법
- Stream은 만들면 반드시 close를 해주어야 합니다. 하지 않으면 메모리 누수가 발생합니다.
눈으로 보여지는 효과는 없음!
try (여기서 만든 객체가 AutoCloseable 인터페이스를 implements 하고 있다면 close 하지 않아도 try ~ catch 구문을 벗어나면 자동적으로 close를 호출합니다.) {
} catch(Exception e) {
}
SerializableMain 수정해서 만듦
public class SerializableMain {
public static void main(String[] args) {
try(//인스턴스 단위에 파일에 기록할 수 있는 객체를 생성
ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream("multiobject.txt"));) {
//기록할 인스턴스 생성
StudentDTO dto1 = new StudentDTO(1, "아담", new Date());
StudentDTO dto2 = new StudentDTO(2, "강진축구", new Date());
//기록할 인스턴스가 여러 개 이므로 하나의 List로 묶어줍니다.
ArrayList<StudentDTO> list =
new ArrayList<>();
list.add(dto1);
list.add(dto2);
//기록
oos.writeObject(list);
//oos.close();
}catch(Exception e) {
System.out.println(e.getLocalizedMessage());
}
try (//인스턴스 단위로 파일에서 읽어낼 수 있는 객체를 생성
ObjectInputStream ois = new ObjectInputStream(
new FileInputStream("multiobject.txt"));){
//기록을 할 때 List를 사용했으므로 읽어올 때 List로 읽어와야 합니다.
ArrayList list = (ArrayList)ois.readObject();
for(Object obj : list) {
System.out.println(obj);
}
}catch(Exception e) {
System.out.println(e.getLocalizedMessage());
}
}
}
SerializableMain
오늘 하루
기억에 남는 부분
-
-
어려운 부분
-
-
문제 해결 부분
-
-
'프로그래밍 언어 > Java' 카테고리의 다른 글
[Java] Comparable VS Comparator (0) | 2022.10.29 |
---|---|
[Java] Nested Class, Lambda, Stream API, Optional (0) | 2022.10.28 |
[Java] API_ Collection Framework (List, Set, Map) (0) | 2022.10.26 |
[Java] API_ java.util (Generic, 제네릭)(컬렉션 프레임워크), ArrayList (0) | 2022.10.26 |
[Java] API_ java.util (Arrays 클래스 - search, date, calendar, random) (0) | 2022.10.25 |