java IO패키지

개미Coder
|2024. 5. 9. 12:14
반응형

Java의 IO 패키지는 입력(Input)과 출력(Output)을 다루기 위한 다양한 클래스와 인터페이스를 제공합니다.

 

이 패키지는 java.io 패키지 아래에 위치하며, 데이터를 읽고 쓰는 데 필요한 모든 기능을 포함하고 있습니다. 기본적으로 스트림 기반의 입출력을 지원하며, 스트림은 데이터를 순차적으로 처리합니다.

자바 IO 패키지는 크게 4가지 주요 구분으로 나눌 수 있습니다:

InputStream / OutputStream

바이트 기반의 입력 및 출력 스트림입니다.
파일, 메모리, 프로세스 간 통신 등 다양한 소스로부터 바이트 단위로 데이터를 읽거나 쓸 때 사용됩니다.
예를 들어, FileInputStream, FileOutputStream, BufferedInputStream, BufferedOutputStream 등이 있습니다.

 

Reader / Writer

문자 기반의 입력 및 출력 스트림입니다.
텍스트 데이터를 처리할 때 주로 사용되며, 인코딩 문제를 해결하기 위해 설계되었습니다.
FileReader, FileWriter, BufferedReader, BufferedWriter 등이 이에 해당합니다.


RandomAccessFile

파일에 대한 랜덤 액세스(읽기 및 쓰기) 기능을 제공합니다.
파일의 특정 위치를 지정하여 데이터를 읽거나 쓸 수 있습니다.
이 클래스는 java.io 패키지 내에 있지만, InputStream이나 OutputStream의 하위 클래스가 아니라 독립적인 클래스입니다.
파일 및 디렉토리 다루기

파일 시스템의 파일이나 디렉토리를 생성, 삭제, 검사하는 등의 작업을 할 수 있는 클래스를 제공합니다.
File 클래스가 이러한 기능을 담당합니다.
자바 IO 패키지는 블로킹 입출력을 수행합니다. 즉, 어떤 스레드가 입력을 기다리는 동안(또는 데이터를 쓰는 동안) 해당 스레드는 다른 작업을 수행할 수 없습니다. 이러한 특성 때문에 자바 NIO(Non-blocking IO)가 등장했으며, NIO는 IO와는 다르게 채널과 버퍼를 사용하여 논블로킹 입출력 및 선택기(Selector)를 통한 다중 입출력 처리를 지원합니다.

그러나 여전히 많은 자바 애플리케이션들에서는 전통적인 IO 패키지를 사용하여 데이터를 처리합니다. 특히, 파일이나 네트워크 통신 같은 시스템 리소스와의 상호작용을 구현할 때 주로 사용됩니다.

 

 

 

- 입력장치 키보드, File, Network를 사용하는데 InputStream으로 동일하게 입력받기에, 입력받는 방법이 전체적으로 동일하다. (동일한 방법으로 읽어온다)

 

 

 

- 텍스트를 입력받아서, 입력받은 텍스트로 Input을 받아오는 과정

package InputIO;

import java.io.IOException;
import java.io.InputStream;

public class InputIO {
	
    // for  ? : 반복횟수를 알 때(length)
    // while? : 반복횟수를 모를 때(키보드입력/파일입력)
	public static void main(String[] args) throws IOException {
		int ch;
		InputStream is = System.in; // 미리 입력도구를 만들어놓음(표준입력도구)
		
		System.out.println("데이터를 입력하세요(종료 : Ctrl +Z)");
		
		int count = 0;
		while(true) {
			ch = is.read();	// 키보드 버퍼로 부터 1Byte 읽어오기
			
			// Ctrl+z 누르면 is.read()메소드가 -1값을 반환한다.
			if(ch==-1)break;
			System.out.printf("%c", ch);
			
			count++;
			
		}//end-while
		System.out.printf("반복횟수 : %d\n",count);
		
		System.out.println("---End---");
	}//main-end
}

 

- 텍스트를 입력받아서, 입력받은 텍스트로 Input을 받아오는 과정

- 위의 과정은 한글이 깨지기 때문에 (한글은 2byte) 1byte로 받아오는 과정을 char의 값으로 변환시켜줘서 한글이 깨지지 않게 값을 받아 출력할 수 있다.

package InputIO;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class InputIO2 {
	
    // for  ? : 반복횟수를 알 때(length)
    // while? : 반복횟수를 모를 때(키보드입력/파일입력)
	public static void main(String[] args) throws IOException {
		int ch;
		InputStream is = System.in; // 미리 입력도구를 만들어놓음(표준입력도구)
		
		// byte -> char 변환시킬 객체로 filter(byte로 받은 값을 char값으로 재포장 시켜준다)
		InputStreamReader isr = new InputStreamReader(is);
		
		System.out.println("데이터를 입력하세요(종료 : Ctrl +Z)");
		
		int count = 0;
		while(true) {
			ch = isr.read();	// isr로부터 문자 1개
			
			// Ctrl+z 누르면 is.read()메소드가 -1값을 반환한다.
			if(ch==-1)break;
			System.out.printf("%c", ch);
			
			count++;
			
		}//end-while
		System.out.printf("반복횟수 : %d\n",count);
		
		System.out.println("---End---");
	}//main-end
}

enter는 윈도우가 \r\n으로 글자 수 두개를 포함시킨다.

 

키보드 -> 키보드버퍼(임시저장소) -> 모니터(콘솔)

▶Quece(큐) : FIFO(First in First Out) (선입선출)

▶Stack(스택) : LIFO(Last in First Out) (후입선출)

키보드버퍼(임시저장소)의 데이터 처리는 큐처리로 선입선출 방식이다.

 

- 텍스트 파일을 만들어서, 파일로 Input을 받아오는 과정

package InputIO;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

// 파일로부터 출력 받기
public class _02_FileInput {

	public static void main(String[] args) throws IOException, InterruptedException {
		// 이 파일이 없으면 어떻게 처리할래? 라고 물어본다. 예외처리 해주면 감사.
		InputStream is = new FileInputStream("a.txt");	// 업캐스팅

		int ch;
		
		while(true) {
			
			ch = is.read();
			// File 끝이면 종료 (text 파일의 끝이 -1로 나타나기 때문에, 자동으로 종료된다)
			if(ch==-1) break;
			System.out.printf("%c", ch);
			
			Thread.sleep(500);
			
		}
		
		
		// 파일 열어놨는데 못닫으면 어떻게 할래? 예외처리 해주면 감사. main에게 이관시키는게 주특기
		is.close();
		System.out.println("---End---");

	}//main-end
}

 

▶텍스트로부터 받았거나, 파일로부터 받았거나 입력방식이 똑같다.

 

 

- 네트워크를 읽어서, 네트워크를 Input을 받아오는 과정

package InputIO;

import java.io.InputStream;
import java.net.URL;

public class _03_NetworkInput {

	public static void main(String[] args) throws Exception {
		
		String str_url = "https://www.naver.com/";
		// 예외가 뜨는 것은 너 이 주소 없으면 어떡할래!! 라고 물어보는 것임 main에게 넘기는게 주특기
		URL url = new URL(str_url);
		
		// 이 웹서버에 연결된 주소를 인풋으로 넣겠다.
		InputStream is = url.openStream();
		
		int ch;
		int count = 0;
		
		while(true) {
			ch = is.read();
			// 네이버에 올라와있는것도 문서형태이다. 끝은 결국 -1값이 나온다.
			if(ch==-1)break;
			System.out.printf("%c", ch);
			
			count++;
		}//while-end
		System.out.printf("반복횟수 : %d\n",count);
		System.out.println("---End---");
		
	}//main-end
}

 

- 네트워크를 읽어서, 네트워크를 Input을 받아오는 과정

- 위 버전은 글씨가 깨지기 때문에, char로 변환하여 받아준다.

package InputIO;

import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;

public class _03_NetworkInput2 {

	public static void main(String[] args) throws Exception {
		
		String str_url = "https://www.naver.com/";
		// 예외가 뜨는 것은 너 이 주소 없으면 어떡할래!! 라고 물어보는 것임 main에게 넘기는게 주특기
		URL url = new URL(str_url);
		
		// 이 웹서버에 연결된 주소를 인풋으로 넣겠다.
		InputStream is = url.openStream();
		
		InputStreamReader isr = new InputStreamReader(is);
		
		int ch;
		
		while(true) {
			ch = isr.read();
			// 네이버에 올라와있는것도 문서형태이다. 끝은 결국 -1값이 나온다.
			if(ch==-1)break;
			System.out.printf("%c", ch);
			
		}//while-end
		System.out.println("---End---");
		
	}//main-end
}

'

- CharSet을 euc-kr로 준다면, 네트워크에서 가져온 문서는 UTF-8 방식으로 인코딩 되기 때문에, 글씨가 깨져서 출력하게 된다.

(ASCII 'A' -> 65, 만약 '가'라는게 euc-kr에서는 100이라면, UTF-8에서 '가'는 1000을 받는다면, euc-kr에서 UTF-8에서의 '가'를 받아주면 100으로 받아야 할 '가'를 1000으로 받기에 이상한 문자가 출력되는 것이다)

 

 

 

- 위에는 전부 char로 받아서 한 글자씩 받아오기 때문에 업로드 속도가 느리다.

- 그렇기 때문에, BufferedReader를 사용하면, 버퍼에 데이터를 전부 가져와서, enter로 구분되어 있는 라인을 하나씩 가져오게 되는데, 그 라인 자체를 하나씩 불러오기에, 시간이 정말 단축이 많이 된다.

package InputIO;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;

public class _03_NetworkInput3 {

	public static void main(String[] args) throws Exception {
		
		String str_url = "https://www.naver.com/";
		// 예외가 뜨는 것은 너 이 주소 없으면 어떡할래!! 라고 물어보는 것임 main에게 넘기는게 주특기
		URL url = new URL(str_url);
		
		// 1차적으로 읽는다.
		InputStream is = url.openStream();
		// 2차적으로 읽는다.
		InputStreamReader isr = new InputStreamReader(is,"UTF-8");
		// 성능향상, 3차적으로 읽는다.
		BufferedReader br = new BufferedReader(isr);
		
		String data;
		int line_count = 0;
		// int ch;
		
		while(true) {
			data = br.readLine();	// Enter까지 읽어온다-> 엔터제외하고 넘긴다.
			if(data==null) break;
			System.out.println(data);
			
			line_count++;
		}//while-end
		
		System.out.printf("라인의 갯수 : %d\n", line_count);
		
	}//main-end
}

 

- 반복된 횟수는 14번으로 한 번씩 가져올 때 라인 한 줄을 전체적으로 가져오는 것을 알 수 있다.

 

 

 

 

▶OutputStream 활용해서 출력하기

package output;

import java.io.IOException;
import java.io.OutputStream;

public class _01_MonitorOutput {

	public static void main(String[] args) throws IOException {
		// 입력표준 : System.in
		// 출력표준 : System.out
		OutputStream os = System.out;	// System.out으로 부르는건 System 클래스의 static 변수 호출이다.
		
		// 문자
		char ch = 'A';
		os.write(ch);		// 출력버퍼에 기록
		os.write(66);		// 출력버퍼에 기록
		
		os.flush();		// 출력버퍼를 비워라 -> 모니터로 전송

		// 문자열
		String msg = "안녕하세요";
		// String -> byte []
		byte [] msg_bytes = msg.getBytes();
		os.write(msg_bytes);
		
		// 정수 (String으로 받아서 int로 변환
		int age = 20;		// '0' : 48
		// 모든값을 문자열 변환 : String.valueOf(값)
		os.write(String.valueOf(age).getBytes());
		
		// 실수
		double boy_length = 180.5;
		os.write(String.valueOf(boy_length).getBytes());
		
		boolean bOk = "파리".equals("새");
		os.write(String.valueOf(bOk).getBytes());
		
		
	}//main-end
}

 

package output;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.PrintStream;

public class _02_FileOutput {

	public static void main(String[] args) throws Exception {

		OutputStream os = new FileOutputStream("b.txt");

		// 문자
		char ch = 'A';
		os.write(ch);
		
		// 문자열 출력
		String msg = "아울렛에서 가서 쇼핑을 해봅시다.";
		os.write(msg.getBytes());

		// 앤터
		os.write('\n');
		os.write('\n');
		// 숫자
		os.write(String.valueOf(30).getBytes());
		os.write('\n');
		os.write(String.valueOf(123.56).getBytes());
		
		// 편리하게 사용하기 위해서 filltering
		// 자, 이제부터 내가 format 형식을 정해서 마음껏 출력이 가능하다!
		PrintStream out = new PrintStream(os);
		
		out.println("\n---지금부터는 PrintStream을 이용---");
		
		String name = "홍길동";
		int age = 31;
		String tel  = "010-4040-4040";
		boolean bMarried = true;
		
		out.printf("이름 : %s\n", name);
		out.printf("나이 : %d(살)\n", age);
		out.printf("전화번호 : %s\n", tel);
		out.printf("결혼유무 : %s\n", bMarried ? "기혼" : "미혼");
		
		os.close();	// 파일은 사용했으면 닫아야 한다. 닫아야 다른 사람도 자원을 사용이 가능하다.
		
	}//main-end
}

 

 

-직렬화 : 넘겨줄 때 쭈우우욱 넘겨줍니다. oos.writeObject(p1);

-역직렬화 : 넘어올 때 순서대로 읽어와서 해당타입에 맞는 객체로 조립 레고 조립 (객체명)ois.readObject();

 

-직렬화를 가능하게 해주려면 implements Serializable을 넣어주어야 한다.

-Serializable을 들어가면 인터페이스에 딱히 기능이 없는데, 그냥 식별해주는 표시로 생각하면 된다.

package vo;

import java.io.Serializable;
// PersonVo가 직렬화 가능한 객체로 표현 : Serializable
public class PersonVo implements Serializable{
	
	// alt + shift + s
	// Vo의 구조가 완벽하게 들어맞아야, 역직렬화 할 때 오류가 나지 않는다.
	String name;
	int age;
	String addr;
	
	public PersonVo() {
		// TODO Auto-generated constructor stub
	}
	
	public PersonVo(String name, int age, String addr) {
		super();
		this.name = name;
		this.age = age;
		this.addr = addr;
	}
	
	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return String.format("[%s-%d-%s]", name, age, addr);
	}
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getAddr() {
		return addr;
	}
	public void setAddr(String addr) {
		this.addr = addr;
	}

}
package serial;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;

import vo.PersonVo;

public class _01_Serial_Person {

	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub

		PersonVo p = new PersonVo("차선일", 31, "서울특별시 양천구 목5동");
		// 직렬화로 저장된 파일 : binary 파일 (2진법)
		OutputStream os = new FileOutputStream("person.dat");
		// 객체를 저장할 수 있는 Filter 객체 생성
		ObjectOutputStream oos = new ObjectOutputStream(os);
		// 저장
		oos.writeObject(p);

		// 열린역순으로 닫기 (항상 파일이 열려있으면 닫아줘야 한다. 다른이들이 열어볼 수 있게)
		oos.close();
		os.close();
		
		
	}//main-end
}

 

 

- ArrayList

- Map

 

package note;

import java.util.Scanner;

public class Note {

	public void run() {
		
		while(true) {
			Scanner scanner = new Scanner(System.in);
			
			System.out.println("안녕하세요, 차선일의 메모하고 싶은 날 입니다.");
			System.out.println("1. 메모리스트   2. 메모보기   3. 메모작성   4. 메모수정   5. 메모삭제   6. 종료");
			System.out.println("번호를 입력해주세요.");
			
			int selectedNumber = scanner.nextInt();
			
			if(1 == selectedNumber) {
			} // 메모 전체보기 처리
			else if (2 == selectedNumber) {
			}	// 메모 상세보기 처리
			else if (3 == selectedNumber) {
			}	// 메모 추가하기 처리
			else if (4 == selectedNumber) {
			}	// 메모 수정하기 처리
			else if (5 == selectedNumber) {
			}	// 메모 삭제하기 처리
			else if (6 == selectedNumber) {
				break;
			} else {
				System.out.println("번호를 다시입력해주세요");
			}
		}// while-end
	}// run-edn
	
}

 

- transient를 변수에 넣어주면 직렬화에서 제외가 된다.

 

 

# File 클래스

※ 자바 프로그램 안에서 File을 관리하는 기능

 

- 파일 시스템의 파일을 표현하는 클래스

- 파일 크기, 파일 속성, 파일 이름 등의 정보 제공

- 파일 생성 및 삭제 기능 제공

- 디렉토리 생성, 디렉토리에 존재하는 파일 리스트 얻어내는 기능 제공

 

# 파일 객체 생성

 

 

- 파일 및 디렉토리의 정보를 리턴하는 메서드

File f = new File("d:\\dev"); // 제어문자 :\n \r \t \를 문자로 인식 : \\ 두개로 사용

// "\"" : ""안에 "를 넣고 싶으면 앞에 \를 사용

 

// Directory 생성

File ff = new File(f,"myfolder");

 

// 존재하지 않으면 생성해라

if(ff.exists()==false) // ff.exists : 존재하면 true가 출력된다.

ff.mkdir();

 

// 삭제

ff.delete();

 

 

System.out.println("---[파일목록]----");

for(int i = 0; i<f_array.length;i++) {

File f_local = f_array[i];

 

// StringBuffer vs StringBuilder

// 속도 O

// 쓰레드동기화 O X

StringBuilder sb = new StringBuilder("[");

// String kind = "[";

 

if(f_local.isDirectory())

sb.append("D");

if(f_local.isFile())

sb.append("F");

// 얘는 else 걸면 안된다.

if(f_local.isHidden())

sb.append("H");

 

sb.append("]");

 

String name = f_local.getName();

 

long len = f_local.length();

 

if(f_local.isFile())

System.out.printf("[%d] : %s %s (%d bytes)\n",i , sb.toString(), name, len);

else if(f_local.isDirectory())

System.out.printf("[%d] : %s %s\n",i , sb.toString(), name);

}

 

반응형

'java(2)↗' 카테고리의 다른 글

VO와 DTO와 DAO  (0) 2024.05.12
java 네트워크  (0) 2024.05.10
java 이클립스 템플릿 Template  (0) 2024.05.08
java 람다식(+다형성 추가 설명)  (0) 2024.05.08
java 요약노트  (0) 2024.05.08