티스토리 뷰
CHAPTER 01 바이트 입출력 스트림 | InputStream OutputStream
군포망나니 2025. 6. 18. 22:23

CHAPTER 01 바이트 입출력 스트림
CHAPTER 02 필터 입출력 스트림
CHAPTER 03 파일처리 클래스
CHAPTER 04 문자 입출력 스트림
CHAPTER 05 인터넷 주소 처리
CHAPTER 06 URL 클래스를 이용하여 데이터 읽기
CHAPTER 07 TCP/IP 서버 소켓
CHAPTER 08 TCP/IP 클라이언트 소켓
CHAPTER 09 서버와 클라이언트 통신 프로그램
CHAPTER 10 채팅 프로그램 작성
CHAPTER 11 UDP 프로토콜
CHAPTER 12 URLConnection 클래스
CHAPTER 13 IP 멀티캐스팅 소켓
채팅 프로그램의 꽃은 아무래도 문.자.열 !! 그래서 Chapter01 ~ 04까지 주구장창 스트림과 클래스에 대해서 배우나 보다.
스트림은 순서가 있는 일련의 데이터를 의미하는데 키보드, 파일, 네트워크, 단말기과 같은 모든 입출력 장치에 스트림을 전달하여 입출력을 수행한다.
자바 스트림 클래스가 처리하는 데이터는 2가지로 나뉜다고 한다.
- Byte 단위이냐 (파일을 2진수 데이터로 취급) - chapter 01 ~ 03
- 문자 단위이냐 - chapter 04
바이트 입출력 스트림 클래스는 바이트 단위로 시스템의 메모리 - 주변 장치 데이터 전송을 하고 서버 - 클라이언트 간 데이터 전송 등을 처리한다.
스트림 클래스들 중에 가장 최상위 출력 클래스는 무엇일까?
바로 OutputStream 클래스이다. 그러면 최상위 입력 클래스는 InputStream 클래스이겠다.
그렇다면 즉, 이 클래스들 안에 있는 하위 클래스들은 다양한 역할과 기능을 수행할 수 있다는 것이다!!

실행도중에 IOException 예외가 발생할 수 있으니 적어준다.
| 파일이 존재하지 않음 | 읽으려는 파일이 존재하지 않을 때 |
| 디스크 공간 부족 | 파일을 쓰는 도중 디스크 용량이 부족할 때 |
| 권한 문제 | 파일을 읽거나 쓸 권한이 없을 때 |
| 연결 끊김 | 네트워크 스트림에서 연결이 끊겼을 때 |
| 하드웨어 오류 | 저장 장치의 물리적 문제 발생 시 |
| 스트림이 닫힌 후 작업 수행 | 닫힌 스트림에 대해 read/write를 시도할 경우 |
OutputStream 클래스
메모리에 있는 바이트 데이터를 파일이나 다른 컴퓨터와 같은 특정 미디어로 전송하는 데 필요하다.
* write(int b) 메서드 : 가장 기본적인 메소드이며 b는 32 비트를 가지지만, 8비트는 전송하고 24비트는 전송하지 않는다.
why only 8bit? OutputStream 클래스는 바이트 기반 스트림이기 떄문이다. (하위 수준 I/O 시스템과 일치시켜야 하기 때문에 )
why int? byte의 범위는 -128 ~ 127 이다. write() 메소드는 0 ~ 255 값을 표현해야 한다. 그리하여 int 로 받고 하위 8비트만 사용한다.
outputStream.write(200); // byte로는 표현 불가능, int로 받아서 처리
200의 2진수 : 00000000 00000000 00000000 11001000
8비트만 사용하면 -> 11001000 (200)
값 달라지는 건 없습니다!
전송의 효율을 위해서 배열로 저장된 여러 바이트 데이터를 한 번에 전송할 수 있는 write(byte[] data) 메소드가 있다.
public static void main (String args[]) throws java.io.IOException {
byte[] b = new byte[(127-31)*2];
int index = 0;
for (int i = 32; i <127; i++){
b[index++] = (byte) i;
}
b[index++] = (byte) '\n';
System.out.write(b);
}
문자데이터 (4byte) 를 바이트 데이터로 변환시키는 코드는 아래와 같다.
public static void main (String args[]) throws java.io.IOException {
byte[] buffer;
for (int i = 0; i <args.lengh; i++){
buffer = args[i].getBytes();
System.out.write(buffer);
}
}
args[0] = "An"
args[1] = "young"
args[2] = "Hwa"
- "An".getBytes() → {65, 110}
- "young".getBytes() → {121, 111, 117, 110, 103}
- "Hwa".getBytes() -> {72, 119, 97}
public void flush() throws IOException {} // 버퍼의 내용이 채워지지 않아도 강제로 버퍼 내용을 전송한다.
public void close() throws IOException {} // 현재 실행중인 스트림이 사용하는 파일 핸들 또는 포트 같은 자원을 해지한다. 닫혀진 스트림에 데이터 전송시에 IOException 예외가 발생한다.
InputStream 클래스
파일이나 다른 컴퓨터로부터 바이트 데이터를 읽어서 메모리로 저장하는 기능이다.
public static void main(String args[]) throws IOException {
int data;
while((data = System.in.read()) >= 0) System.out.write(data);
}
Read() 메소드 : 1바이트의 양의 정수 값을 읽어서 4바이트 정수 값으로 반환한다.
System.in.read(); // 한 바이트씩 입력도 받고 출력도 시켜줌
read() 보다 더 효율적인 메소드는 ? public int read(byte[] data) throws IOException
public static void main(String args[]) throws IOException {
byte[] buffer = new byte[80];
int numberRead; //바이트 데이터수를 저장한다. 최대 80바이트이다.
while((numberRead = System.in.read(buffer)) >= 0)
System.out.write(buffer, 0, numberRead); //버퍼에 있는 데이터를 처음부터 numberRead 개수만큼 화면에 출력한다.
}
Read(byte[] data) 메소드는 enter 키까지 입력된 하나의 문장만을 바이트 배열에 저장할 수 있지만, read(byte[], int, int) 메소드를 사용하면 enter 키로 구분된 다수의 문장을 버퍼에 저장할 수 있다.
public int read(byte[] data, int offset, int length) throws IOException
public static void main(String args[]) throws IOException {
try{
int bufferSize = 80;
int size = 0;
int dataRead;
byte buffer[] = new byte[bufferSize];
while((dataRead = System.in.read(buffer, size, bufferSize-size)) >= 0) {
size += dataRead;
}
System.out.write(buffer, 0, size);
} catch(IOException e) {
System.err.println("스트림으로부터 데이터를 읽을 수 없습니다."); //System.err 라는 것도 있네요?
}
}
input 데이터
| 1 | internet programming | enter |
| 2 | java programming | enter |
| 3 | fighting | enter |
| 4 | Crtl + Z |
Ouput 데이터
| 1 | internet programming |
| 2 | java programming |
| 3 | fighting |
버퍼 크기 80만 가능한 상태인데 크기를 늘려주려면 어떻게 작성해야 하는가?
static int bufferSize = 80;
static int size = 0;
static byte buffer[] = new byte[bufferSize];
public static void main(String args[]) throws IOException {
try{
int dataRead;
while((dataRead = System.in.read(buffer, size, bufferSize-size)) >= 0) {
size += dataRead;
if(size == bufferSize)
increaseBufferSize();
}
System.out.write(buffer, 0, size);
} catch(IOException e) {
System.err.println("스트림으로부터 데이터를 읽을 수 없습니다.");
}
}
static void increaseBufferSize(){
bufferSize += 80;
byte[] newBuffer = new byte[bufferSize];
System.arraycopy(buffer, 0, newBuffer, 0, size);
buffer = newBuffer;
}
| public int available() 메소드 | 블록킹없이 (작업 완료가 안되어도 프로그램 계속 진행) 데이터의 수를 읽고 반환합니다. |
| public long skip(long n) 메소드 | 입력 스트림으로부터 인수로 주어진 n 바이트 수만큼을 읽지 않고 스킵할 수 있는 기능을 제공합니다. |
입력스트림으로부터 데이터를 읽고 있을 때, 현재 읽고 있는 데이터에 마킹을 하고
계속 그 후의 데이터를 읽는 도중에 마킹을 리셋하면 이전에 마킹한 데이터로부터 다시 데이터를 읽는 기능이 필요한 경우가 있다.
| 1 | mark (int readlimit) | 현재 읽고 있는 데이터 마크 (단, 하나의 마크만 가능하며, readlimit 이후의 데이터 읽으면 예외 발생 ) |
| 2 | reset() | 이전에 마이크 마크한 위치의 데이터부터 다시 읽기 |
public static void main(String args[]) throws IOException {
try{
copy(System.in, System.out); }
catch(IOException e) {
System.out.println("스트림으로부터 데이터를 읽을 수 없습니다.");
}
}
public static void copy(InputStream in, OutputStream out) throws IOException {
int bytesRead;
byte[] buffer = new byte[256];
synchronized(in){
synchronized(out){
while((bytesRead = in.read(buffer)) >= 0){
out.write(buffer, 0, bytesRead);
}
}
}
}
입출력 결과
| 1 | 입력 | this is a simple data |
| 2 | 출력 | this is a simple data |
| 3 | 입력 | my name is db |
| 4 | 출력 | my name is db |
| 5 | 입력 | Ctrl + Z |
다음 글에서는 Chapter01 의 마지막 FileOutputStream 과 FileInputStream 클래스에 대해서 알아보겠습니다 - !
'자바 | JAVA > JAVA | 채팅 프로그래밍' 카테고리의 다른 글
| CHAPTER 01 | 연습문제 1번 (0) | 2025.06.18 |
|---|---|
| CHAPTER 01 | 연습문제 (1) | 2025.06.18 |
| CHAPTER 01 | FIileOutputStream FileInputStream (1) | 2025.06.18 |
| 자바 | 채팅 프로그래밍 목차부터 보기 (01 - 13) (1) | 2025.06.18 |
| 자바 채팅 프로그래밍 | 추억의 버디버디를 떠올리며 (3) | 2025.06.17 |