2022-07-12-IO

onnbi·2022년 7월 26일
0

java-tutorial

목록 보기
12/13
post-thumbnail

IO

Input / Output

프로그램 상 전역변수를 넘어 컴퓨터 내부 외부 장치와 데이터를 주고 받는 것 (후에 컴퓨터와 컴퓨터를 네트워크로 연결)

Stream

  • 데이터를 입출력하기 위한 통로
  • 스트름을 얻어와 사용하고 난 다음에는 반드시 반환해야 한다
  • 스트림은 단방향이다
    입력과 출력이 동시에 일어나야 하는 경우 입력용 출력용 스트림을 따로 만들어야 한다

입출력 절차

  1. 외부자원과 스트림을 연결
    • 외부자원과의 데이터 이동통로를 생성
    • 스트림 클래스에 대한 객체 생성
  2. 데이터를 읽고 쓴다
    • 레퍼런스. 읽기 메서드(): 또는 레퍼런스.쓰기 메서드(); 호출
  3. 데이터를 읽고 쓰기가 끝나면 스트림 반납

스트림 분류

  1. 전송 방향에 따른 분류
    1. 입력 스트림 : 읽어오기
      InputStream, Reader
    2. 출력 스트림 : 내보내기
      OutputStream, Writer
  2. 전송 단위에 따른 분류
    1. 바이트 스트림
      InputStream, OutputStream
    2. 문자 스트림
      Reader, Writer
  3. 보조 스트림
    • 단독으로 사용할 수 없음
    • 속도나 기능을 향상시키거나 새로운 기능을 추가

ByteStream

사용순서대로 진행

  1. 스트림 생성 : FileOutputStream(바이트) / Reader, Writer(char)
    • 바이트는 Stream으로 끝나며 바이트 배열로 변환해야 한다
    • 텍스트 보다 이미지 전송할 때 사용
  2. 메서드를 통한 입출력 : .write() / .readLine()
  3. 자원반환 : .close()
public void primaryStream() {
	System.out.print("저장할 파일명 입력 : ");
	String filename = sc.nextLine();
		
	// 나가는 방향 스트림과 연결
	FileOutputStream fos = null;
	try {
		// 입력받은 파일명으로 파일 생성
		// 생성된 파일과 프로그램이 stream연결
		fos = new FileOutputStream("C:\\Users\\greys\\Desktop"+filename);
		System.out.println("["+filename+"]에 저장될 내용을 입력하세요");
		System.out.println("종료는 exit를 입력하세요");
		// 파일로 데이터를 내보내는 역할
		while(true) {
			System.out.print("내용 입력 : ");
			String str = sc.nextLine()+"\r\n";
			if(str.equals("exit\r\n")) {
				break;
			}
			byte[] arr = str.getBytes(); //문자열을 바이트 배열로 변환
			// 이유 : write메서드의 매개변수가 byte[]타입이기 때문
			fos.write(arr);
		}
 	} catch (FileNotFoundException e) {
		e.printStackTrace();
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} finally {
		try {
			fos.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

보조스트림

FileInputStream fis = new FileInputStream ("text.txt")
  // 주스트림
BufferedInputStream bis = new BufferedInputStream (fis)
  // 보조스트림에 주스트림을 넣어 성능 향상
bis.read;
  • 데이터를 단독으로 전송하는 역할이 아닌 워터슬라이드의 물처럼 전송을 돕는 역할
  • 직접 입출력 할 수 없고 기능을 향상시키거나 새로운 기능을 추가하기 위해 사용

BufferWrite 외부로 데이터를 내보내기

public void subStream() {
	System.out.print("저장할 파일명 입력 : ");
	String filename = sc.nextLine();
  	// 파일 이름을 입력받는다
  
  	BufferedWriter bw = null;
	// 보조스트림 생성
	
	try {
	FileWriter fw = new FileWriter(filename);
    // 주스트림 생성
	bw = new BufferedWriter(fw);
    // 주스트림에 보조스트림 추가
      
	System.out.println("["+filename+"]에 저장할 내용 입력 ");
	System.out.println("종료는 exit");
	while(true) {
		System.out.print("입력 : ");
		String str = sc.nextLine(); //엔터 안씀
		if(str.equals("exit")) {
			break;
		}
		bw.write(str); //보조스트림을 통한 데이터 전송
		bw.newLine(); // 보조스트림에 존재하는 줄 개행 기능
	}
	}catch(IOException e ){
		e.printStackTrace();
	} finally {
	try {
		// 보조스트림 반환 시 주스트림은 자동으로 반환
		bw.close();
	} catch (IOException e) {
		e.printStackTrace();
	}
  }
}	

BufferReader 외부에 저장된 데이터를 읽어오기

public void charStreamReader() {
	//1. 스트림 생성하고 2. 메서드를 통한 입력 3. 자원반환
	System.out.println("로드할 파일명 입력 : ");
	String filename = sc.nextLine();
	// 데이터를 읽어올 보조스트림
	BufferedReader br = null;	
	// 주스트림
	try {
		FileReader fr = new FileReader(filename);
		br = new BufferedReader(fr);
		// 보조스트림 안에 주스트림을 넣는 것은 똑같다
		while(true) {
			try {
				// readLine() : 스트림이 연결된 파일에서 1줄 읽어옴
				// 더이상 읽어올 내용이 없는 경우 null 리턴
				String str = br.readLine(); //2. 메서드를 통한 입력
				if(str == null) {
					break;	//nu11이면 멈춘다
				}
				System.out.println(str); // null이 아니면 화면에 출력
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
    } catch (FileNotFoundException e) {
		e.printStackTrace();
	} finally {
		try {
			br.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

File객체

파일 시스템의 파일을 표현하는 클래스
파일크기, 파일속성, 파일이름 등 정보를 제공하며 파일 생성 및 삭제 기능 제공

  • file.getName() : 파일명
  • file.getAbsolutePath() : 파일의 절대경로 (실주소)
    • 내 컴퓨터부터 찾아가는 경로
      C:\Users\greys\eclipse-workspace\inputOutput\test.gif
      상대경로 (우리집 기준으로 설명)
    • 현재 위치 기준으로 찾아가는 경로
      inputOutput 파일에 있으면 자기 자신의 위치부터 찾아가는 것
  • delete() : 파일 삭제

직렬화

객체를 스트림으로 전송하기 위해 바이트 단위로 잘라주는 것
java.io.Serializable을 implements 해서 사용

  • implements가 붙을 수 있는지로 객체 직렬화 가능여부 판단
  • transient : 객체 직렬화 시 제외할 필드 앞에 붙여 해당 필드의 직열화를 예외로 하는 키워드
// 내보낼 객체(직렬화 할 클래스에 implements Serializable)
public class User implements Serializable {
  	private String id;
	private transient String pw;
  // 직렬화 할 때 빼고 하라는 명령어
	private String name;
	private int age;
}


// 객체를 내보내기 위한 코드 : ObjectOutputStream
public void test1() {
  //회원정보Scanner로 입력받아
  User u = new User(id, pw, name, age);
  //User타입 객체 생성
  ObjectOutputStream oos = null;
try {
	FileOutputStream fis = new FileOutputStream("object.txt");
	oos = new ObjectOutputStream(fis);

	oos.writeObject(u); //매개변수= 최고조상인 object

} catch (FileNotFoundException e) {
	e.printStackTrace();
} catch (IOException e) {
	e.printStackTrace();	
	}finally {
	try {
		oos.close();
    } catch (IOException e) {
		e.printStackTrace();
	}
}

이렇게 내보낸 객체는 자바가 알아볼 수 있는 언어로 저장된다 > 해당 파일을 다시 불러오기 위해서는 FileInputStream을 사용한다 >

 //직렬화를 통해 내보낸 데이터를 불러오기
public void test2() {
 // 보조스트림 먼저 생성
 // 보조스트림은 finally에서도 사용하기 때문에
 // try전에 생성하여 null값을 넣는다
 	ObjectInputStream ois = null;
	try {
	FileInputStream fis = new FileInputStream("object.txt");
	ois = new ObjectInputStream(fis);
	try {
		User u = (User)ois.readObject();
      	// Object타입으로 반환되기 때문에 downcasting
		System.out.println(u.getId());
		System.out.println(u.getPw());
		System.out.println(u.getName());
		System.out.println(u.getAge());
	} catch (ClassNotFoundException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	} catch (FileNotFoundException e) {
	// TODO Auto-generated catch block
	e.printStackTrace();
	} catch (IOException e) {
	// TODO Auto-generated catch block
	e.printStackTrace();
	}finally {
	try {
		ois.close();
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
		}
	}
}

ArrayList API

Class ArrayList<E>
java.lang.Object
java.util.AbstractCollection<E>
java.util.AbstractList<E>
java.util.ArrayList<E>
All Implemented Interfaces:
**Serializable**, Cloneable, Iterable<E>, Collection<E>, List<E>, RandomAccess

API문서를 통해 ArrayList도 직렬화가 가능하다는 것을 알 수 있다

profile
aelatte coding journal

0개의 댓글