용어 정리
본문 정리
자바의 입출력 스트림
컴퓨터 공학에서 스티림이란 데이터의 흐름 혹은 데이터를 전송하는 소프트웨어 모듈을 일컫는다. 자바에서 입출력 스트림은 응용프로그램과 입출력 장치를 연결하는 소프트웨어 모듈이다. 입출력 스트림의 특징은 다음과 같다.
1. 스트림의 양끝에는 입출력 장치와 자바 응용프로그램이 연결된다.(자바 응용프로그램은 입력·출력 스트림과만 연결하고, 입출력 스트림이 입출력 장치를 제어하고 실질적인 입출력을 담당한다.)
2. 스트림은 단방향이다.(입력 스트림은 입력장치에서 응용프로그램으로 데이터 전송을, 출력 스트림은 응용프로그램으로부터 받은 데이터를 출력 장치로 전송을 담당한다. 두 가지 기능을 모두 가진 스트림은 없다.)
3. 스트림을 통해 흘러가는 기본 단위는 바이트나 문자이다.(자바의 스트림 객체는 바이트를 단위로 입출력하는 바이트 스트림과 문자 단위로 입출력하는 문자 스트림으로 나뉜다.)
4. 스트림은 선입선출, FIFO 구조이다.(입력 스트림에서 먼저 들어온 데이터가 응용프로그램에 먼저 전달되고, 응용프로그램이 출력한 순서대로 출력 스트림은 출력장치에 보낸다.)
자바에서 입출력 스트림은 문자 스트림과 바이트 스트림으로 나뉜다. 문자 스트림은 오직 문자만 다루지만, 바이트 스트림은 문자이든 이미지 바이트든 상관이 없다.(정보를 단순 바이너리로 다루기 때문)
바이트 스트림을 다루는 클래스는 공통적으로 이름 뒤에 Stream을 붙이고, 문자 스트림을 다루는 클래스는 Reader/Writer를 붙인다.
스트림은 서로 연결될 수 있다. 예는 다음과 같다.
InputStreamReader rd = new InputStreamReader(System.in);
System.in은 표준 입력 스트림이다. System.in은 사용자의 키 입력을 받아 바이트 스트림으로 내보내며, rd는 들어오는 바이트 스트림을 문자로 구성하여 응용프로그램에 전달한다.
문자 스트림과 파일 입출력
문자 스트림은 2바이트의 유니코드 문자를 단위로 입출력하는 스트림이다. 앞서 말했듯 '문자'만 다룬다. 전달 받은 바이트를 '로컬 문자 집합'에 있는 문자와 비교하여 문자로 변환한다.(찾을 수 없다면 문자가 아니거나 다른 언어의 문자거나 문자 집합이 잘못 설정되어 있는 것)
생성자는 다음과 같다.
FileReader(File file) : file로부터 읽은 FileReader 생성
FileReader(String name) : name 이름의 파일로 부터 읽는 FileReader 생성
메소드는 다음과 같다.
int read() : 한 개의 문자를 읽어 정수형으로 리턴
int read(char[] cbuf) : 문자들을 읽어 cbuf 배열에 저장하고 읽은 개수 리턴
int read(char[] cbuf, int off, int len) : 최대 len 개수의 문자들을 읽어
cbuf 배열의 off 위치부터 저장하고 실제 읽은 개수 리턴
String getEncodiong() : 스트림이 사용하는 문자 집하브이 이름 리턴
void close() : 입력 스티림을 닫고 관련된 시스템 자원 해제
예는 다음과 같다.
FileReader fin = new FileReader("c:\\test.txt");
이 의미는 test.text가 문자들로만 구성된 텍스트 파일이며 FileReader의 생성자가 해당 파일을 찾아 열고, 파일과 스트림을 연결한다.
int c;
while((c=fin.read()) != -1){ // 파일의 끝이라면 -1을 리턴한다.
System.out.print((char)c);
}
문자 하나를 읽어 리턴하는 것을 알려주는 코드이다.
char [] buf = new char [1024];
int n = fin.read(buf); 한 번에 1024개의 문자를 읽어 buf[]에 저장하고 실제 읽은 문자수 리턴
파일이 크다면 위와 같이 하는 방법도 있다.
파일의 경로명이 틀리다면 FileNotFoundException이, 파일 읽기·쓰기·닫기를 하는 동안 입출력 오류가 발생했다면 IOException 예외를 발생 시킨다.
InputStreamReader는 스트림에 입력되는 바이트 데이터를 문자 집합을 통해 문자로 변환한다.
아래는 생성자 이다.
InputStreamReader(InputStream in) : in으로부터 익는 기본 문자 집합의 InputStreamReader 생성
InputStreamReader(InputStream in, Charset cs) :
in으로부터 읽는 cs 문자 집합의 InputStreamReader 생성
InputStreamReader(InputStream in, String charsetName) :
in으로부터 읽는 charsetName 문자 집합의 InputStreamReader 생성
메소드는 FileReader와 같다.
InputStreamReader는 바이트 스트림을 전달받아 문자 정보로 변환하는 스트림 객체이다. 따라서 텍스트 파일을 읽기 위해서는 먼저 바이트 파일 입력 시스템을 생성해야 한다.
FileInputStream fin = new FileInputStream("c:\\Temp\hangul.txt");
InputStreamReader in = new InputStreamReader(fin, "MS949");
MS949는 fin으로부터 읽어 들인 바이트들을 문자로 인코딩하기 위한 문자 집합으로 "한글 확장 완성형 문자 집합"이다.
FileWriter는 텍스트를 파일에 저장하는 방법 중 하나이다. 생성자는 다음과 같다.
OutputStreamWriter(OutputStream out) : out에 출력하는 기본 문자 집합의 OutputStreamWriter 생성
OutputStreamWriter(OutputStream out, Charset cs) :
out에 출력하는 cs 문자 집합의 OutputStreamWriter 생성
OutputStreamWriter(OutputStream out, String charsetName) :
charsetName 문자 집합의 OutputStreamWriter 생성
FileWriter(File file) : file에 데이터를 저장할 FileWriter todtjd
FileWriter(String name) : name 파일에 데이터를 저장할 FileWriter 생성
FileWriter(Fule file, boolean append) : FileWriter생성하며 append가 true이면 파일의 마지막부터
데이터를 저장
FileWriter(String name, boolean append) : FileWriter를 생성하며 append가 true이면 파일의
마지막부터 데이터를 저장
메소드는 다음과 같다.
void write(int c) : c를 char로 변환하여 한 개의 문자 출력
void write(String str) : 문자열 str 출력
void write(String str, int off, int len) : 인덱스 off부터 len개의 문자를 str 문자열에서 출력
void write(char[] cbuf, int off, int len) : 인덱스 off부터 len개의 문자를 배열 cbuf에서 출력
void flush() : 스트림에 남아있는 데이터 문자 출력
String getEncoding() : 스트림이 사용하는 문자 집합의 이름 리턴
void close() : 출력 스트림을 닫고 관련된 시스템 자원 해제
다음은 텍스트를 쓰는 출력 스트림 생성에 관한 예제이다.
FileWriter fout = new FuleWriter("c:\\Temp\\test.txt");
만약 파일이 없는 경우 빈 파일을 생성하며, 있다면 내용을 지우고 처음부터 쓴다.
fout.write('A'); // 문자 'A'를 파일에 저장
char [] buf = new char [1024]; // 한 블록 씩 쓰는 방법
fout.write(buf, 0, buf.length);
바이트 스트림과 파일 입출력
바이트 스트림은 바이트 단위로 바이너리 데이터가 흐르는 스트림이다. 해당 스트림 클래스에는 Input/Ouputstream, fileInput/fileOutputStream, DataInput/DataOutputStream이 있다.
바이너리 데이터를 파일에 저장할 때 FileOutputStream 클래스를 이용한다. 다음은 생성자이다.
FileOutputStream(File file) : file이 지정하는 파일에 출력하는 FilOutputStream 생성
FilOutputStream(String name) : name이 지정하는 파일에 출력하는 FilOutputStream 생성
FilOutputStream(File file, boolean append) : FilOutputStream을 생성하며 append가 true이면
file이 지정하는 파일의 마지막부터 데이터 저장
FilOutputStream(String name, boolean append) : FilOutputStream을 생성하며 append가 true이면
name이름의 파일의 마지막부터 데이터 저장
메소드는 다음과 같다.
void write(int b) : int 형으로 넘겨진 한 바이트를 출력 스트림으로 출력
void write(byte [] b) : 배열 b의 바이트를 모두 출력 스트림으로 출력
void write(byte[] b, int off, int len) : len 크기만큼 off부터 배열 b를 출력 스트림으로 출력
void flush() : 출력 스트림에서 남아 있는 바이너리 데이터 모두 출력
void close() : 출력 스트림을 닫고 관련된 시스템 자원 해제
다음은 파일을 쓰는 예시이다.
FileOutputStream fout = new FileOutputStream("c:\\Temp\\test.out");
byte b[] = {7,51,3,4,-1,24};
for(int i = 0; i < b.length; i++}{ // fout.(write(b))로 한번에 쓰기 가능
fout.write(b[i]);
}
바이트 스트림으로 파일을 읽는 스트림 클래스는 FileInputStream이다. 생성자는 다음과 같다.
FileInputStream(File file) : file이 지정하는 파일로부터 읽는 FileInputStream 생성
FileInputStream(String name) : name이 지정하는 파일로부터 읽는 FuleInputStream 생성
메소드는 다음과 같다.
int read() : 입력 스트림에서 한 바이트를 읽어 int형으로 리턴
it read(byte[] b) : 최대 배열 b의 크기만큼 바이를 읽음, 읽는 도중 EOF를 만나면
실제 읽은 바이트 수 리턴
int read(byte[] b, int off, int len) : 최대 len개의 바이트를 읽어 b배열의 off 위치붙터 저장.
읽는 도중 EOF를 만나면 실제 읽은 바이트 수 리턴
int available() : 입력 스트림에서 현재 읽을 수 있는 바이트 수 리턴
void close () : 입력 스트림을 닫고 관련된 시트림 자원 해제
파일을 읽는 예시는 다음과 같다.
FileInputStream fin = new FileInputStream("c:\\Teamp\\test.out")
byte b[] = new byte[6];
int n =0, c;
while((c = fin.read()) != -1){
b[n] = (byte)c;
n++;
}
버퍼 입출력과 파일 입출력
입출력 스트림은 운영체제 API를 호출하는데 자주 호출하게 되면 효율이 나빠진다. 만약 버퍼를 스트림이 가지게 되면 한 번에 운영체제 API를 호출하므로 효율적이게 된다. 버퍼를 가지는 스트림을 버퍼 스트림이라 한다. 버퍼 스트림도 바이트 버퍼 스트림(BufferedInputStream 과 BufferedOutputStream)과 문자 버퍼 스트림(BufferedReader와 BufferedWriter)으로 구분된다.
바이트 버퍼 스트림 생성자는 다음과 같다.
BufferedInputStream(InputStream in) : in을 연결하는 디폴트 크기의 입력 버퍼 스트림 객체 생성
BufferedInputStream(InputStream in, int size) : in을 연결하는 size크기의 입력 버퍼 스트림
객체 생성
BufferedInputStream(OutputStream out) : out을 연결하는 디폴트 크기의 출력 버퍼 스트림 생성
BufferedInputStream(OutputStream out, int size) : out을 연결하는 size 크기의 출력 버퍼 스트림 생성
문자 버퍼 스트림 생성자는 다음과 같다.
BufferedReader(Reader in) : in을 연결하는 디폴트 크기의 문자 입력 버퍼 스트림 생성
BufferedReader(Reader in, int sz) : in을 연결하는 sz 크기의 문자 입력 버퍼 스트림 생성
BufferedWriter(writer out) : out을 연결하는 디폴트 크기의 문자 출력 버퍼 스트림 생성
BufferedWriter(writer out, int sz) : out을 연결하는 sz 크기의 문자 출력 버퍼 스트림 생성
스트림을 출력하는 예시는 다음과 같다.
BufferedOutputStream bout = new BufferedOutputStream(System.out, 20);
FileReader fin = new FileReader("c:\\windows\\System.ini");
int c;
while((c=fin.read())!=-1){
bout.write((char)c);
}
만약 버퍼가 다 차기 전에 출력시키기 위해선 bout.flush()를 이용하면 된다.
File 클래스
File 클래스는 파일이나 디렉터리에 대해 경로명·크기·타입 등의 속성 정보를 제공하고, 파일 삭제· 디렉터리 생성 등 다양한 파일 관리 작업을 지원한다. File 클래스에는 입출력 기능은 없다. 생성자는 다음과 같다
File(File parent, String child) : parent 디렉터리에child 이름의 서브 디렉터리나 파일을 나타내는
File 객체 생성
File(String pathname) : pathname의 완전 경로명이 나타내는 File 객체 생성
File(String parent, String child) : parent 디렉터리에 child 이름의 서브 디렉터리나 파일을 나타내는
File 객체 생성
File(URI uri) : file:URI를 추상 경로명으로 변환하여 File 객체 생성
메소드는 다음과 같다.
boolean mkdir() : 새로운 디렉터리 생성
String[] list() : 디렉터리 내의 파일과 서브 디렉터리 리스트를 문자열 배열로 리턴
File[] listFiles() : 디렉터리 내의 파일과 서브 디렉터리 리스트를 File[]배열로 리턴
boolean renemeTo(File dest) : dest가 지정하는 경로명으로 파일 이름 변경
boolean delete() : 파일 또는 디렉터리 삭제
long length() : 파일의 크기 리턴
String getPath() : 경로명 전체를 문자열로 변환하여 리턴
String getParent() : 파일이나 디렉터리의 부모 디렉터리 이름 리턴
String getName() : 파일 또는 디렉터리 이름을 문자열로 리턴
boolean isFile() : 일반 파일이면 true 리턴
boolean isDirectory() : 디렉터리면 true 리턴
long lastModified() : 파일이 마지막으로 변경된 시간 리턴
boolean exists() : 파일 또는 디렉터리가 존재하면 true 리턴
본 문제
Q1.
package Javava;
import java.io.*;
import java.util.*;
public class StackManageer {
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
File fi = new File("c:\\Temp\\phone.txt");
FileWriter fw = null;
System.out.println("전화번호 입력 프로그램입니다.");
try {
fw = new FileWriter(fi);
while(true) {
System.out.print("이름 전화번호 >> ");
String k = sc.nextLine();
if(k.equals("그만")) {
break;
}
else {
fw.write(k + "\r\n", 0 , k.length() + 2);
}
}
fw.close();
sc.close();
}
catch(IOException e) {
System.out.println("렉 먹음");
}
System.out.println(fi.getPath() + "에 저장하였습니다.");
}
}
Q2.
package Javava;
import java.io.*;
public class StackManageer {
public static void main(String args[]) {
File f1 = new File("c:\\Temp\\phone.txt");
FileReader f2 = null;
int c;
try {
f2 = new FileReader(f1);
System.out.println(f1.getPath()+"를 출력합니다.");
while((c=f2.read())!=-1) {
System.out.print((char)c);
}
f2.close();
}
catch(IOException e) {
System.out.println("렉");
}
}
}
Q3.
package Javava;
import java.io.*;
public class StackManageer {
public static void main(String args[]) {
File f1 = new File("c:\\windows\\system.ini");
FileReader fr = null;
int c;
try {
fr = new FileReader(f1);
while(( c = fr.read() ) != -1 ){
char k = Character.toUpperCase((char)c);
System.out.print(k);
}
}
catch(IOException e) {
System.out.println("렉");
}
}
}
Q4.
package Javava;
import java.io.*;
import java.util.*;
public class StackManageer {
public static void main(String args[]) {
File f1 = new File("c:\\windows\\system.ini");
Scanner sc = null;
int linenumber = 0;
try {
sc = new Scanner(f1);
while(sc.hasNext()) {
linenumber++;
String line = sc.nextLine();
System.out.printf("%4d: %s\n", linenumber, line);
}
}
catch(IOException e) {
System.out.println("렉");
}
}
}
Q5.
package Javava;
import java.io.*;
import java.util.*;
public class StackManageer {
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
String str1, str2;
System.out.println("전체 경로명이 아닌 파일 이름만 입력하는 경우, 파일은 프로젝트 폴더에 있어야 합니다.");
System.out.print("첫번째 파일 이름을 입력하세요>>");
str1 = sc.next();
System.out.print("두번째 파일 이름을 입력하세요>>");
str2 = sc.next();
System.out.println(str1+"과 "+ str2 +"를 비교합니다.");
File f1 = new File("c:\\Temp", str1);
File f2 = new File("c:\\Temp", str2);
FileInputStream fr1 = null;
FileInputStream fr2 = null;
InputStreamReader isr1 = null;
InputStreamReader isr2 = null;
try {
fr1 = new FileInputStream(f1);
fr2 = new FileInputStream(f2);
isr1 = new InputStreamReader(fr1, "UTF-8");
isr2 = new InputStreamReader(fr2, "UTF-8");
int c1, c2, len = 0;
while( (char)(c1 = isr1.read()) == (char)(c2 = isr2.read()) ) {
len++;
}
if(len == f1.length() && len == f2.length()) {
System.out.println("같은 파일");
}
else {
System.out.println("다른 파일");
}
fr1.close(); fr2.close();
isr1.close(); isr2.close();
}
catch(IOException e) {
System.out.println("렉");
}
}
}
Q6.
package Javava;
import java.io.*;
import java.util.*;
public class StackManageer {
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
String str1, str2;
System.out.println("전체 경로명이 아닌 파일 이름만 입력하는 경우, 파일은 프로젝트 폴더에 있어야 합니다.");
System.out.print("첫번째 파일 이름을 입력하세요>>");
str1 = sc.next();
System.out.print("두번째 파일 이름을 입력하세요>>");
str2 = sc.next();
File f1 = new File("c:\\Temp", str1);
File f2 = new File("c:\\Temp", str2);
try {
FileInputStream fi1 = new FileInputStream(f1);
FileInputStream fi2 = new FileInputStream(f2);
FileOutputStream fo = new FileOutputStream("c:\\temp\\append.txt");
int n;
while( (n = fi1.read()) != -1) {
fo.write((char)n);
}
while((n = fi2.read()) != -1) {
fo.write((char)n);
}
fi1.close();fi2.close();fo.close();
System.out.println("프로젝트 폴더 밑에 append.txt 파일에 저장하였습니다.");
}
catch(IOException e) {
System.out.println("렉");
}
}
}
Q7.
package Javava;
import java.io.*;
public class StackManageer {
public static void main(String args[]) {
File f1 = null;
File f2 = null;
double d[] = {0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1};
try {
f1 = new File("c:\\temp\\dog.jpg");
f2 = new File("c:\\temp\\copy.jpg");
FileInputStream fi = new FileInputStream(f1);
FileOutputStream fo = new FileOutputStream(f2);
int b, n =0, i =0;
double total = f1.length();
System.out.println(f1.getName()+"를 " + f2.getName()+"로 복사합니다.");
System.out.println("10%마다 *를 출력합니다.");
while( (b = fi.read()) != -1) {
fo.write((byte)b);
n +=1;
if( n/total > d[i] ) {
System.out.print("*");
i++;
}
}
}
catch(IOException e) {
System.out.println("렉");
}
}
}
Q8.
package Javava;
import java.io.*;
public class StackManageer {
public static void main(String args[]) {
File f = new File("c:\\Temp");
File listfile[] = f.listFiles();
int big = 0;
File bigfile = listfile[big];
for(int i = 1; i < listfile.length; i++) {
if(bigfile.length() < listfile[i].length()) {
big = i;
bigfile = listfile[big];
}
}
System.out.println("가장 큰 파일은 " + listfile[big].getPath() + "\n"+listfile[big].length());
}
}
Q9.
package Javava;
import java.io.*;
public class StackManageer {
public static void main(String args[]) {
File f = new File("c:\\temp\\");
File listf[] = f.listFiles();
for(int i = 0; i < listf.length; i++) {
File del = listf[i];
String k = del.getName();
if(-1 != k.lastIndexOf(".txt")) {
del.delete();
}
}
}
}
Q10.
package Javava;
import java.io.*;
import java.util.*;
public class StackManageer {
public static void main(String args[]) {
File f = new File("c:\\temp\\phone.txt");
HashMap<String, String> hm = new HashMap<String, String>();
int count = 0;
Scanner sc= new Scanner(System.in);
try {
Scanner fsc = new Scanner(new FileReader(f));
while(fsc.hasNext()) {
String str = fsc.nextLine();
StringTokenizer st = new StringTokenizer(str, " ");
String key = st.nextToken();
String value = st.nextToken();
hm.put(key, value);
count++;
}
System.out.println("총 " + count +"개의 전화번호를 읽었습니다.");
while(true) {
System.out.print("이름>> ");
String name = sc.next();
if(!name.equals("그만")) {
String tel = hm.get(name);
if(tel ==null) {
System.out.println("찾는 이름이 없습니다.");
}
else {
System.out.println(hm.get(name));
}
}
else {
break;
}
}
}
catch(IOException e) {
System.out.println("렉");
}
}
}
이하는 나중에 풀어야지(사실 어려워서 못풀겠다 ㅎ)
Q11.
Q12.
Q13.
Q14.
'java > 학교,기관' 카테고리의 다른 글
자바의 이벤트 처리(프로그래밍 심화)(명품 JAVA Programming ) (0) | 2022.12.04 |
---|---|
자바 GUI 기초, AWT와 스윙(프로그래밍 심화)(명품 JAVA Programming ) (0) | 2022.11.26 |
제네릭과 컬렉션(프로그래밍 심화)(명품 JAVA Programming ) (0) | 2022.11.21 |
모듈과 패키지 개념, 자바 기본 패키지(프로그래밍 심화)(명품 JAVA Programming ) (0) | 2022.11.10 |
상속(프로그래밍 심화)(명품 JAVA Programming ) (0) | 2022.10.22 |
댓글