| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 | 31 |
- 선형대수학
- 운영체제
- 개발자
- Java
- Android
- 알고리즘
- 앱
- Flutter
- 최대우도법
- qq플롯
- 행렬
- Eigenvalue
- 상대 엔트로피
- f비
- 군내
- 잔차
- 평균로그우도
- 논리회로 #컴퓨터
- 파스칼삼각형
- 군간
- pintos
- 자바
- 개발
- ios
- AIC
- Eigenvector
- 비둘기집원리
- 앱개발
- 일반화오차
- 조건부정리
- Today
- Total
Dev_bob
[JAVA]입출력 스트림과 파일 입출력 본문
8.1 자바의 입출력 스트림
스트림 - 연속적인 데이터 흐름 혹은 데이터를 전송하는 소프트웨어 모듈
스트림 입출력 - 버퍼를 갖고 순차적으로 이루어지는 입출력
입력 스트림 - 입력 장치로부터 자바 프로그램으로 데이터를 전달
출력 스트림 - 출력 장치로 데이터 출력
입출력 스트림 특징
-스트림은 단방향 입니다. 입력과 출력을 동시에 하는 스트림은 없습니다.
-스트림의 양 끝에는 입출력 장치와 자바 응용프로그램이 연결됩니다.
자바 프로그램은 입력 스트림과 출력 스트림과만 연결하고 입출력 스트림이 입출력 장치를 제어합니다.
-스트림을 통해 흘러가는 기본단위는 바이트나 문자 입니다.
-스트림은 선입선출, 즉 FIFO(first in first out) 구조이다.
--------------------------------------------------------------------------------------------------------------------
입출력 스트림
-바이트 스트림
-문자 스트림
-버퍼 스트림
-바이트 버퍼 스트림
-문자 버퍼 스트림
입출력 스트림 기본 단위
| 바이트 스트림 | 문자스트림 |
| -바이트 스트림의 경우 : 바이트 입출력되는 데이터를 단순 바이트로 처리 클래스 이름이 공통적으로Stream으로 끝남 바이트를 단위로 다루는 스트림, 스트림에 들어오고 나가는 단순 바이너리(비트들)로 다룸. 문자이든 이미지 바이트든 상관 없음 |
-문자 스트림의 경우 : 문자(자바에서는 문자 1개-> 2바이트) 문자만! 입출력하는 스트림 문자가 아닌 바이너리 데이터는 스트림에서 처리 못함 클래스 이름이 공통적으로 Reader/Writer로 끝남 유니코드(2바이트) 문자를 입출력하는 스트림 문자로 표현되지 않은 데이터는 다루지 못함. 이미지, 동영상과 같은 바이너리 데이터는 입출력 불가 |
| <바이트 스트림 클래스> InputStream/OutputStream 추상클래스 바이트 스트림을 다루는 모든 클래스의 슈퍼 클래스 FileInputStream/FileOutputStream 파일로부터 바이트 단위로 읽거나 저장하는 클래스 바이너리 파일의 입출력 용도 DataInputStream/DataOutputStream 자바 기본 데이터 타입의 값을 바이너리 값 그대로 입출력 문자열도 바이너리 형태로 입출력 |
<문자 스트림을 다루는 클래스> Reader/Writer InputStreamReader/OutputStreamWriter FileReader/FileWriter |

스트림 연결
InputStreamReader rd = new InputStreamReader(System.in);

System.in - 표준 입력 스트림 (? s 1 입력) / System.in은 사용자 키 입력 받고 바이트 정보를 내보냅니다.
rd(InputStreamReader)-InputStreamReader의 객체인 rd는 바이트 스트림을 문자로 구성하여 프로그램으로 전달합니다.
문자 스트림 클래스
문자스트림 - 2바이트의 유니코드 문자 단위로 입출력하는 스트림
FileReader를 통한 텍스트 파일 읽기
FileReader 클래스 생성자, 메소드 : 텍스트 파일을 읽는데 사용됨
file과 스트림 연결
FileReader fin = new FileReader("c:\\test.txt");
FileReader 파일 입력 스트림 생성 , FileReader로 스트림을 파일(c:\test.txt)과 연결
FileReader의 생성자는 C:\test.txt파일을 찾아서 열고, 파일과 스트림을 연결한다.
위에서 언급했듯이, c:\test.txt파일은 문자들로만 구성된 텍스트 파일이다.
fin.read()
fin.read()는 연결된 파일로 부터 문자를 하나 읽어 리턴하며, 파일의 끝을 만나면 -1을 리턴한다.
fin.read()로 파일 전체를 읽어 화면에 출력하는 코드는 다음과 같다.
int c;
while((c=fin.read())!=-1){
System.out.print((char)c);
}
근데 이상한 점이 있다. char타입의 값을 읽어야하는데 왜 int타입의 변수 c를 사용하는 것일까?그 이유는 파일의 끝 (EOF)을 처리하는 과정에 있다.스트림이나 파일에 -1값이 있을 수 있다. 그렇다면 c=fin.read()!=-1에서 혼돈이 올 수 있다고 생각된다.하지만 이것은 아니다!int 타입의 -1 : 0xFFFFFFFF char 타입의 -1: 0x000000FF
블록read()
char [] buf=new char [1024]//1024는 1KB이다.
int n=fin.read(buf);//한번에 1024개의 문자를 읽어 buf[]에 저장하고 실제 읽은 문자수 리턴
파일의 큰 경우에 fin.read()를 사용하게 되면 읽는 속도가 너무 느리다. 이럴때는 fin.read(블록) 하여 블록만큼 읽는 read()를 활용하면 된다.
버퍼란 읽고 쓸 데이터를 저장하는 배열을 부르는 용어다. 문자의 개수가 1024개보다 작을때, read()는 읽은 문자의 개수를 리턴한다.
스트림 닫기 close()
파일 읽기가 필요 없으면 다음과 같이 close 메소드를 호출해 입력 스트림을 닫는다.
fin.close();
파일 입출력과 예외 처리
파일의 경로명이 틀린경우-FileNotFoundException 발생
파일 읽기,쓰기,닫기를 하는 동안 입출력 오류가 발생한 경우 - IOException 발생
import java.io.*; // 입출력 관련 클래스를 사용하기 위해 java.io 패키지를 임포트
public class FileReaderEx {
public static void main(String[] args) {
FileReader fin = null; // FileReader 타입의 변수 fin을 선언하고 초기화
try {
// "c:\\windows\\system.ini" 파일을 읽기 위해 FileReader 객체를 생성하고 fin 변수에 할당
fin = new FileReader("c:\\windows\\system.ini");
int c; // 파일에서 읽은 문자를 저장할 변수 c를 선언
// 파일 끝까지 한 문자씩 읽어서 c에 저장, -1이면 파일 끝을 의미
while ((c = fin.read()) != -1) {
// 읽은 문자를 출력, (char)c로 캐스팅하여 문자로 출력
System.out.print((char) c);
}
// 파일 읽기가 끝나면 파일을 닫음
fin.close();
}
// 입출력 과정에서 예외가 발생하면 이를 처리
catch (IOException e) {
// 예외가 발생하면 "입출력오류" 메시지를 출력
System.out.println("입출력오류");
}
}
}
try catch문에서 IOException e만 다루는 이유는 FileNotFoundException이 IOException의 하위 클래스이기 때문입니다. IOException을 캐치할 때 FileNotFoundException도 함께 처리됩니다.
문자 집합과 InputStreamReader를 이용한 텍스트 파일 읽기
InputStreamReader - 스트림에 입력되는 바이트 데이터를 문자 집합을 통해 문자로로 변환한다.
따라서 문자집합을 지정해야 한다. 만약 읽어 들인 바이트들이 문자 집합에 속하지 않는 경우 해독할 수 없는 글자가 된다.
| 생성자 | 설명 |
| InputStreamReader(InputStream in) | in으로부터 읽는 기본 문자 집합의 InputStreamReader생성 |
| InputStreamReader(InputStream in,Charset cs) | in으로부터 읽는 cs 문자 집합의 InputStreamReader생성 |
| InputStreamReader(InputStream in,String charsetName) | in으로부터 읽는 charsetName 문자 집합의 InputStreamReader 생성 |
InputStreamReader로 문자 입력 스트림 생성
//텍스트 파일 읽기
FileInputStream fin = new FileInputStream("c:\\Temp\\hangul.txt");
//객체 생성하기
InputStreamReader in = new InputStreamReader(fin,"Ms949");
fin으로 읽어 들인 바이트들을 '한글 확장 완성형 문자 집합'에 있는 코드로 저장 -> MS949
MS949는 한글 문자를 표현하기 위해 사용되었던 인코딩 방식 중 하나로, 주로 윈도우 환경에서 사용되었습니다. 현재는 유니코드(UTF-8)로 대부분 전환되었지만, MS949로 인코딩된 기존 데이터나 문서를 처리할 필요가 있을 때 사용됩니다.

import java.io.*;
public class FileReadHangulSuccess {
public static void main(String[] args) {
InputStreamReader in=null; //문자 스트림을 다루는 클래스 InputStreamReader
FileInputStream fin = null;//바이트 스트림을 다루는 모든 클래스의 슈퍼클래스
try {
fin=new FileInputStream("C:\\Temp\\hangul.txt");//파일 가져오기
in=new InputStreamReader(fin,"MS949");//fin으로부터 읽어들인 바이트를 문자집합 "MS949"를 통해 한글문자를 리턴함
int c;
System.out.println("인코딩 문자 집합은"+in.getEncoding()); //getEncoding은 in 객체의 문자집합의 이름을 리턴합니다.
while((c=fin.read())!=-1) {//문자 값이 EOF가 아닐때까지 한글자씩 읽기
System.out.print((char)c); //문자 하나씩 출력
}
in.close();//InputStreamReader 스트림 닫기
fin.close();//FileInputStream 스트림닫기
}catch(IOException e) {
System.out.println("입출력오류"); //입출력오류 예외처리
}
}
}
FileWriter를 이용한 텍스트 파일 쓰기
파일 출력 스트림 생성
FileWriter fout=new FileWriter("c:\\Temp\\test.txt");
FileWriter 생성자는 c:\Temp\test.txt 파일을 열어 스트림과 연결한다. 파일이 없다면 빈 파일 생성한다. 이미 파일이 있는 경우 덮어쓰기를 진행한다.
파일쓰기
fout스트림의 write() 메소드를 이용하면 문자 단위로 파일에 저장할 수 있다.
fout.write('A');
한글자씩 저장할 수도 있지만, 문자 단위로 파일에 저장할 수도 있다. (한블록씩)
char [] buf=new char[1024]
fout.write(buf,0,buf.length);//buf[] 배열의 처음부터 배열 크기 (1024개 문자)만큼 쓰기
스트림닫기
fout.close();
예제 키보드 입력을 파일로 저장하기
import java.io.*; //입출력을 위한 클래스를 사용하기 위해 java.io.패키지를 임포트
import java.util.*; // 유틸리티 클래스를 사용하기 위해 java.util. 패키지를 임포트
public class FileWriterEx {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);//사용자로부터 입력을 받기 위해 객체 생성
FileWriter fout=null;//FileWriter 타입 변수 fout 선언 및 초기화
try {
fout=new FileWriter("c:\\Temp\\test.txt");//지정된 파일에 쓰기위한 FileWriter 객체 생성
while(true) {//무한루프
String line=scanner.nextLine();//사용자로부터 한줄 입력받기
if(line.length()==0)//Enter를 치면 입력된 문자열의 길이가 0이됨
break;//루프종료
fout.write(line,0,line.length());//입력된 문자열을 파일에 씀, 0부터 문자열의 길이만큼
fout.write("\r\n",0,2);//윈도우 방식 줄바꿈 문자를 파일에 씀
}
fout.close();//FileWriter 객체 닫기
}catch(IOException e) {
System.out.println("입출력 오류");
}
scanner.close();
}
}
버퍼 스트림
버퍼
컴퓨팅에서 버퍼(buffer, 문화어: 완충기억기)는 데이터를 한 곳에서 다른 한 곳으로 전송하는 동안 일시적으로 그 데이터를 보관하는 메모리의 영역이다. 버퍼링(buffering)이란 버퍼를 활용하는 방식 또는 버퍼를 채우는 동작을 말한다.
| 바이트 버퍼 스트림 | 문자 버퍼 스트림 |
| 바이트 단위의 바이너리 데이터를 처리하는 버퍼 스트림 | 유니코드의 문자 데이터만 처리하만 처리하는 버퍼 스트림 |
| BufferedInputStream/BufferedOutputStream | BufferedReader/BufferedWriter |
버퍼 출력 스트림 생성
BufferedOutputStream out=new BufferedOutputStream(System.out,5);
스트림 출력
fin=new FileReader("C:\\Temp\\test2.txt"); //파일 읽어오기
BufferedOutputStream out=new BufferedOutputStream(System.out,5);//버퍼의 크기를 5로 설정 바이트 단위로 5만큼 읽어 문자 출력
while ((c=fin.read())!=-1) {//fin.read()로 한글자씩 있는데 EOF가 나올 떄까지 반복
out.write(c);//c에서 읽은 값을 out(버퍼 스트림)에 쓴다.
}
버퍼에 남아있는 데이터 출력
out.flush();//버퍼에 남아있는 문자 모두 출력
스트림 닫기
fin.close();//문자스트림 클래스 FileReader 닫기
out.close();//바이트 스트림 BufferedOutputStream 닫기
적용예제
import java.io.*;
import java.util.Scanner;
public class BufferedIOEx {
public static void main(String[] args) {
FileReader fin=null;//FileReader 변수 fin 선언
int c;
try {
fin=new FileReader("C:\\Temp\\test2.txt"); //파일 읽어오기
BufferedOutputStream out=new BufferedOutputStream(System.out,5);//버퍼의 크기를 5로 설정 바이트 단위로 5만큼 읽어 문자 출력
//BufferedOutputStream out=new BufferedOutputStream(new OutputStreamWriter(System.out),5); 한글을 출력하려면 다음과 같이 하면 됨.
while ((c=fin.read())!=-1) {//fin.read()로 한글자씩 있는데 EOF가 나올 떄까지 반복
out.write(c);//c에서 읽은 값을 out(버퍼 스트림)에 쓴다.
}
//파일 데이터가 모두 출력된 상태
new Scanner(System.in).nextLine();//Enter키를 누른다면
out.flush();//버퍼에 남아있는 문자 모두 출력
fin.close();//문자스트림 클래스 FileReader 닫기
out.close();//바이트 스트림 BufferedOutputStream 닫기
}catch(IOException e) {
e.printStackTrace();
}
}
}
File 클래스
File 클래스
파일 관리 작업을 지원하는 클래스, File 클래스의 경로명은 java.io.File이다.
java.io경로에 있다고 해서 입출력 기능이 있지는 않다.
getName(),getPath(),getParent()
String filename = f.getName(); // "system.ini"
String path = f.getPath(); // "c:\\windows\\system.ini"
String parent = f.getParent(); // "c:\\windows"
isFile(), isDirectory()
if(f.isFile()) // 파일인 경우
System.out.println(f.getPath() + "는 파일입니다.");
else if(f.isDirectory()) // 디렉터리인 경우
System.out.println(f.getPath() + "는 디렉터리입니다.");
관련 예제
import java.io.File;
public class FileEx {
public static void listDirectory(File dir) {//디렉토리에 포함된 파일,서브디렉토리이름, 크기, 수정시간 출력 메소드
System.out.println("-----"+dir.getPath()+"의 서브리스트입니다.-----");
File[] subFiles=dir.listFiles();//디렉토리에 포함된 파일과 디렉토리 이름의 리스트 얻기
for(int i=0;i<subFiles.length;i++) {
File f=subFiles[i];
long t=f.lastModified();//마지막으로 수정된 시간
System.out.print(f.getName());
System.out.print("\t파일크기:"+f.length());
System.out.printf("\t수정한시간:%tb %td %ta %tT\n",t,t,t,t);//포멧출력
}
}
public static void main(String[] args) {
File f1=new File("C:\\windows\\system.ini");//파일 받아오기
System.out.println(f1.getPath()+", "+f1.getParent()+", "+f1.getName());//path는 경로, getParent는 부모경로,getName은 파일 이름
String res="";//String 변수 res 빈칸으로 초기화
if(f1.isFile()) res="파일";//파일인지 확인하고 초기화
else if(f1.isDirectory()) res="디렉토리";//디렉토리인지 확인하고 초기화
System.out.println(f1.getPath()+"는 "+res + "입니다.");
File f2=new File("c:\\Temp\\java_sample");//새로 만들고자 하는 디렉토리 생성
if(!f2.exists()) {
f2.mkdir();//존재하지 않으면 디렉토리 생성
}
listDirectory(new File("c:\\Temp")); //c:\Temp에 있는 파일 리스트 출력
f2.renameTo(new File("C:\\Temp\\javasample")); //이름 변경
listDirectory(new File("c:\\Temp"));
}
}
'전공수업정리 > Java' 카테고리의 다른 글
| [JAVA]자바 GUI기초, AWT와 스윙(Swing) (4) | 2024.06.02 |
|---|---|
| [JAVA]StringBuffer 클래스 (0) | 2024.05.16 |
| [JAVA]String 클래스 (2) | 2024.05.15 |
| [JAVA]Object class,프로세스,스레드,toString(),equal() (1) | 2024.05.15 |
| [JAVA] 모듈 (2) | 2024.05.10 |