추상클래스와 인터페이스
추상메서드를 하나 이상 포함한 클래스
클래스와 추상메서드에 abstract 붙여야 함
객체를 만들 수 없다.
❓ 왜 사용해 ❓
하위클래스에서 다양하게 구현하라고 → 다형성 구현
상속받은 클래스에 적합하게 오버라이딩 하도록 제공되는 클래스
하위 클래스에 아웃라인 제공.
이 말은 무슨 의미인가?
객체를 생성하려면 적어도 이 메서드들은 꼭 구현하라고 아웃라인을 제공하는 것이다.
완전 추상클래스 abstract 키워드 사용 안 함
추상 메소드와 상수로만 구성됨
객체를 만들 수 없다.
❓ 왜 사용해 ❓
→ 잭 역할. 다형성 구현. 컴포넌트 베이스 개발 가능
인터페이스는 부품을 연결하는 면
집합 데이터를 편하게 처리하도록 제공된 api이다.
ArrayList<타입> lsit = new ArrayLisf<>();
list.add(값);
list.get(방번호);
list.size();
Iterator iter = list.iterator();
iter.hasNext(); // 읽을 요소가 있나? true/false
iter.next(); // 다음 요소를 추출
for(타입 var:list){
System.out.println(var);
}
키와 값을 함께 저장. 빠른 검색 지원
HashMap<String, String> map=new HashMap<String, String>();
map.put(키, 값);
map.get(키);
map.keySet().iterator() // 키 집합에서 키를 하나씩 꺼냄
map.values().iterator() //값 묶음에서 값을 하나씩 꺼냄
런타임시 예외가 발생했을 때 프로그램이 중단되지 않도록 처리하는 코드
try{
예외 발생할 코드
} catch(예외 객체1) {
// try 블록에서 발생한 예외 객체 중 타입이 일치하는 것만 받음
} catch(예외 객체2) {
} catch(Exception e) {
// 위 catch 블록들에서 받지 못한 예외를 여기서 처리
} finally {
// 무조건 실행. 필수는 아니다.
// 중단되더라도 꼭 실행
// 자원 해제
}
이 메서드를 호출하는 쪽에서 예외 처리를 요함
내 프로그램 내에서 특수한 예외 상황을 구현하고자 할 때 직접 예외 발생시킴
InputStream & OutputStream (1바이트씩)
Reader & Writer (2바이트씩)
int read() : 1B 읽어서씩 int 형태로 반환
int read(byte[]) : 배열 크기만큼 읽어서 배열에 저장. 반환값은 읽은 바이트 수만큼 반환
int read(byte[], offs, size)
세개 중 첫 번째와 두 번째가 더 많이 사용이 된다.
void write(int ch) : int 값 하나 출력
void wirte(byte[]) : 배열 크기만큼 배열의 내용을 출력
void write(byte[], offs, size)
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class FileCopy2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
String src="src/입출력스트림/files/a.txt";
String des="src/입출력스트림/files/z.txt";
try {
FileReader fr=new FileReader(src);
FileWriter fw=new FileWriter(des);
int ch;
while((ch=fr.read())!=-1) {
fw.write(ch);
}
fw.close();
fr.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
이렇게 간단하게로도 할 수 있다.
모든 파일은 텍스트로 이루어져있다고 생각하면 된다.
이미지 파일도 문자로 이루어져 있기 때문에 파일을 읽을 때 문자를 읽는다고 생각하면 된다.
FileInputStream fi = new FileInputStream("file path");
BufferedInputStream bi = new BufferedInputStream(fi);
❓ Buffered 왜 써 ❓
빠르게 하려고
InputStreamReader & OutputStreamWriter
System.in : 표준 입력.
InputStream : 하위 객체로 1바이트씩 읽는다.
그래서 한글이 깨진다.
❓ 그럼 어떻게 해야 돼 ❓
InputStreamReader로 감싸줘야 한다.
InputStreamReader 보조 스트림 연결해서 사용하면 바이트씩 읽은 것을 2바이트씩 묶어서 문자 단위로 변환해주기 때문에 한글이 깨지지 않는다.
InputStreamReader ir = new InputStreamReader(System.in);
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class InputStreamReaderTest {
public static void main(String[] args) {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int ch;
try {
while ((ch = br.read()) != '\n') {
System.out.print((char)ch);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
위는 2개의 보조스트림을 연결한 것이다.
2바이트씩 뭉쳐주면 한글도 입력이 가능해진다.
new InputStreamReader이 2바이트씩 뭉쳐준다.
ObjectInputStream & ObjectOutputStream
이걸 사용하려면 직렬화를 알아야 한다.
직렬화 : 객체 전달시 참조값을 전달하는 것이 아니라 멤버변수 하나 하나를 줄 세워서 전달하는 방법.
직렬화 처리 복잡한거 아닌가..? NoNo~
그냥 상속 받으면 끝임~
→ 구현은 Serializable 인터페이스 상속받는 것으로 함
import java.io.Serializable;
class Member implements Serializable{
}
위처럼 implements Serializable을 써주면 된다.
파일엣서 랜덤한 위치로 접근해서 그것을 읽고 쓰는 것
RandomAccessFile : 파일에 랜덤 위치로 접근.
FileInputStream을 기본 스트림으로 갖고 있어서 기본 스트림을 따로 만들 필요가 없다.
RandomAccessFile acc = new RandomAccessFile(파일경로, 모드);
모드- "r" : 읽기 / "w" : 쓰기 / "rw" : 읽고 쓰기 / "a" : 이어쓰기
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
public class RandomAccessTest {
public static void main(String[] args) {
try {
RandomAccessFile acc = new RandomAccessFile("src/입출력스트림/files/b.txt", "r");
byte[] buf = new byte[10];
int size = acc.read(buf); // read(byte[]) : 배열 크기만큼 읽음
System.out.println(new String(buf)); // abcdefghi
System.out.println("읽은 크기 : " + size); // 읽은 크기 : 10
System.out.println("현재 위치 : " + acc.getFilePointer()); // 현재 위치 : 10
System.out.println("현재 위치의 문자 : " + (char) acc.read()); // 현재 위치의 문자 : k
System.out.println("현재 위치 : " + acc.getFilePointer());// 현재 위치 : 11
acc.seek(acc.getFilePointer() + 5);
System.out.println("현재 위치 : " + acc.getFilePointer());// 현재 위치 : 16
System.out.println("현재 위치의 문자 : " + (char) acc.read());// 현재 위치의 문자 : q
acc.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
getFilePointer() : 현재 커서 위치 반환
seek(위치) : 읽고 쓸 위치 변경
File 클래스 : 파일에 대한 정보를 제공하고 파일을 (생성 or 삭제 등등) 제어할 수 있는 기능을 제공하는 클래스
파일 존재 : f.exists()
파일 절대 경로 : f.getAbsolutePath()
파일명 : f.getName()
파일 크기 : f.length()
파일 읽기 가능 : f.canRead()
파일 쓰기 가능 : f.canWrite()
파일 실행 가능 : f.canExecute()
파일인가요? : f.isFile()
숨김파일인가요? : f.isHidden()
파일 생성 : f.createNewFile()
파일 삭제 : f.delete()
디렉토리인가요? : dir.isDirectory()
디렉토리생성 : dir.mkdir()
package 입출력스트림;
import java.io.File;
import java.io.IOException;
public class FileTest {
public static void main(String[] args) {
// 파람으로 지정한 경로의 파일이 없어도 File 객체는 정상적으로 생성됨
File f = new File("src/입출력스트림/files/a.txt");
System.out.println("파일 존재 : " + f.exists()); // 파일 존재 : true
System.out.println("파일 경로 : " + f.getAbsolutePath()); // 파일 경로 : C:\Users\KOSTA\eclipse-workspace\prj2_2\src\입출력스트림\files\a.txt
System.out.println("파일 이름 : " + f.getName()); // 파일 이름 : a.txt
System.out.println("파일 길이 : " + f.length()); // 파일 길이 : 61
System.out.println("파일 읽기 가능 : " + f.canRead()); // 파일 읽기 가능 : true
System.out.println("파일 쓰기 가능 : " + f.canWrite()); // 파일 쓰기 가능 : true
System.out.println("파일 실행 가능 : " + f.canExecute()); // 파일 실행 가능 : true
System.out.println("파일이니? : " + f.isFile()); // 파일이니? : true
System.out.println("숨김 파일이니? : " + f.isHidden()); // 숨김 파일이니? : false
File f2 = new File("src/입출력스트림/files/xxx1.txt");
if(!f2.exists()) {
try {
f2.createNewFile();
System.out.println("파일 생성됨");
} catch (IOException e) {
e.printStackTrace();
}
}
f2.delete(); // 파일 삭제
}
}
디렉토리도 파일인데 특수 파일에 속한다.
package 입출력스트림;
import java.io.File;
public class DirTest {
public static void main(String[] args) {
File dir = new File("src/입출력스트림/files");
System.out.println("디렉토리 존재 : " + dir.exists()); // 디렉토리 존재 : true
System.out.println("디렉토리 맞나요 : " + dir.isDirectory()); // 디렉토리 맞나요 : true
System.out.println("현재 작업 디렉토리 : " + dir.getAbsolutePath()); // 현재 작업 디렉토리 : C:\Users\KOSTA\eclipse-workspace\prj2_2\src\입출력스트림\files
System.out.println("파일 목록"); // 파일 목록
String[] files = dir.list();
for (String f : files) {
System.out.print(f+"\t");
}
// a.txt b.txt c.txt d.txt data.dat e.txt z.txt
File dir2 = new File("src/입출력스트림/files/memo");
if (!dir2.exists()) {
dir2.mkdir();
}
}
}
dir.list() : 디렉토리에 속한 파일 목록의 파일명들
dir.mkdir() : 디렉토리 생성
dir2.delete() : 디렉토리 삭제
ArrayList에 Member 객체 3개 저장
리스트의 모든 객체를 파일에 저장
파일의 모든 객체 읽어서 출력
프로그램이 실행되면 하위에 memo라는 디렉토리가 있는지 확인 : 없으면 한 번만 생성
- 읽기 2. 쓰기 3. 삭제 4. 종료
읽기
memo 디렉토리의 파일 목록 출력
그러면 사용자가 읽고 싶은 파일명 입력 받기
그 파일을 읽어서 화면에 출력
쓰기
쓰기 작업할 파일명 입력
있는 파일 → 덮어쓰기 / 이어쓰기
없는 파일 → 파일 새로 생성하여 쓰기 수행
파일 내용 입력받음. 무한반복. /stop 입력하면 종료
파일에 저장
삭제
memo 디렉토리의 파일 목록 출력
그러면 사용자가 삭제하고 싶은 파일명 입력 받기
종료