문자(character) 단위 입출력 스트림 클래스

Agnes Park·2022년 3월 15일
0

JAVA

목록 보기
34/34

1. 문자(character) 단위 입출력 스트림 클래스

package com.lec.java.file11;

import java.awt.Frame;
import java.io.DataOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStream;

/*
문자(character) 단위 입출력 스트림 클래스
 java.io.Reader: 프로그램이 '문자 단위' 데이터를 읽어들이는(read) 통로
  └─ java.io.InputStreamReader
      └─ java.io.FileReader

 java.io.Writer: 프로그램이 '문자 단위' 데이터를 쓰는(write) 통로
  └─ java.io.OutputStreamWriter
      └─ java.io.FileWriter

 FileReader / FileWriter 객체는 '텍스트파일, 즉 문자 단위' 데이터를 읽고/쓰기 할때
 사용하는 기반 스트립 입니다.   따라서 텍스트가 아닌 오디오, 비디오, 등의 파일을 다룰수 없습니다.
 주로 String 이나 char [] 내용을 입/출력 할때 사용합니다.

 텍스트 파일 (Text File) 이란
   사람이 읽을수 있는 글자들이 저장된 파일
   암호화 되지 않은 평범한 텍스트

 이진파일 (Binary File) 이란
   사람이 직접 읽을수는 없슴.

   ★ 문자기반 출력시 꼭 끝에 flush() 해주자 ★
*/


public class File11Main {
	public static void main(String[] args) {
		System.out.println("FileReader / FileWriter");
		
		String src = "temp/FileData.txt";
		String dst = "temp/FileData.txt";
		
//		FileWriter fw = null;
//		FileReader fr = null;
				
		try(
				FileWriter fw = new FileWriter(dst);
				FileReader fr = new FileReader(src);
				
				
				// byte 스트림 방식과 비교
				OutputStream out = new FileOutputStream("temp/FileData.bin");
				DataOutputStream dout = new DataOutputStream(out);
				) {
			
			String str = "안녕하세요";	// 한글 5글자
			char [] charArr = {'J', 'A', 'V', 'A'};	// 알파벳 4글자
			
			// Writer 는 주로 문자열(String) 이나 char [] 의 내용을 출력할때 사용
			
			fw.write(str);	// 저장은 시스템 인코딩 상태에 따라 저장됨.
			fw.write(charArr);	// UTF-8 인코딩의 경우 한글 한글자당 3byte, 영어는 한글자당 1byte
			
			fw.flush();	// flush() 메소드로 출력버퍼의 데이터를 완전히 출력
			
			// 읽기 read
			char [] buff = new char[100];	// 읽어들일 버퍼 준비
			
			int charsRead = fr.read(buff);	// 최대 buff 만큼의 텍스트 읽어들임. 읽은 문자개수 리턴
			
			for(int i = 0; i < charsRead; i++) {
				System.out.print(buff[i]);
			}
			System.out.println();
			System.out.println("읽은 문자 개수: " + charsRead);
			
			
			// byte 스트림으로 저장하기
			dout.writeChars(str);
			for(char ch : charArr) {
				dout.writeChar(ch);
			}
			
			
		} catch (IOException e) {
			e.printStackTrace();
		}
//		finally {
//			try {
//				if(fw!= null) fw.close();
//				if(fr!= null) fr.close();
//			} catch (IOException e) {
//				e.printStackTrace();
//			}
//		}
		
		
		System.out.println("\n프로그램 종료");
		
	} // end main()
} // end class

2. 버퍼사용 문자입출력 : BufferedReader, BufferedWriter

package com.lec.java.file12;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

/*
 * 버퍼사용 문자입출력 : BufferedReader, BufferedWriter
 * 
 * java.lang.Object
 *  └─ java.io.Reader
 *      └─ java.io.BufferedReader
 *       
 * java.lang.Object
 *  └─ java.io.Writer
 *      └─ java.io.BufferedWriter
 *      
 * ★ 문자기반 출력시 꼭 끝에 flush() 해주자 ★     
 *             
*/

/*
 * txt 는 utf-8 로 인코딩 , 영문 텍스트
 */
public class File12Main {
	
	private static final String BIG_TEXT = "temp/big_eng.txt"; 
	
	public static void main(String[] args) {
		System.out.println("FileReader / FileWriter");
		
		try(
				FileReader fr = new FileReader(BIG_TEXT);
				FileWriter fw = new FileWriter("temp/big_eng_copy1.txt");
				
				FileReader fr2 = new FileReader(BIG_TEXT);
				FileWriter fw2 = new FileWriter("temp/big_eng_copy2.txt");
				BufferedReader br = new BufferedReader(fr2);	// 장착!
				BufferedWriter bw = new BufferedWriter(fw2);
				){
			System.out.println("FileReader/Writer 만 사용");
			
			int charRead = 0;
			int charsCopied = 0;
			
			long startTime = System.currentTimeMillis();
//			while(true) {
//				charRead = fr.read();
//				if(charRead == -1) break;
//				fw.write(charRead);
//				charsCopied++;
//			}
			
			while((charRead = fr.read()) != -1) {
				fw.write(charRead);
				charsCopied++;
			}
			
			fw.flush();
			long endTime = System.currentTimeMillis();
			long elapsedTime = endTime - startTime;
			
			System.out.println("읽고 쓴 문자수: " + charsCopied);
			System.out.println("경과시간(ms): " + elapsedTime);
			
			
			System.out.println();
			System.out.println("BufferedReader/Writer + 버퍼 사용");
			
			char [] buf = new char[1024];	// 버퍼 제공
			
			int charsRead = 0;
			charsCopied = 0;
			
			startTime = System.currentTimeMillis();
			
			while((charsRead = br.read(buf)) != -1) {
				bw.write(buf, 0, charsRead);
				charsCopied += charsRead;
			}
			
			fw.flush();
			endTime = System.currentTimeMillis();
			elapsedTime = endTime - startTime;
			
			System.out.println("읽고 쓴 문자수: " + charsCopied);
			System.out.println("경과시간(ms): " + elapsedTime);
			
			
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		System.out.println("\n프로그램 종료");		
		
	} // end main()
} // end class

3. PrintWriter / 인코딩

package com.lec.java.file13;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;

/* PrintWriter / 인코딩 
 * 
 * java.lang.Object
 *  └─ java.io.Writer
 *      └─ java.io.PrintWriter
 *  
 *  텍스트 파일 작성시는 PrintWriter 객체 편리
 *  	println(), print(), printf() ..
 *  텍스트 파일 읽을시는 BufferedReader 객체 편리
 *  	read(), read(버퍼), readLine()..
 *  
 *  PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("파일명" 혹은 File)));
 *  PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream("파일명" 혹은 File))));
 *  
 *  BufferedReader br = new BufferedReader(new FileReader("파일이름" 혹은 File));
 *  BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(new File("파일이름" 혹은 File))));
 *  BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("파일이름" 혹은 File)));
 *  
 *  ★ 문자기반 출력시 꼭 끝에 flush() 해주자 ★
 * 
 *  인코딩 문제 
 *  	FIleReader, FileWriter 는 파일의 인코딩을 무조건 file.encoding 값으로 간주한다.
 * 		(ex: LINUX 는  UTF-8,  MacOS 는 한글상위의 경우 euc-kr, 윈도우즈는 Java 소스코드 인코딩 영향) 
 *  	
 *  인코딩 설정하기
 *  	InputStreamReader, OutputStreamWriter 를 사용해서 인코딩 변경을 해야 한다.
 *  
 *  	BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("파일이름" 혹은 File),"인코딩"));
 *  	BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("파일이름" 혹은 File), "인코딩"));
 *   
 *  인코딩 : "UTF8", "euc-kr"
 *   
*/

public class File13Main {
	
	private static final String FILE1 = "temp/PrintData.txt";
	private static final String FILE2 = "temp/PrintData_euckr.txt";
	
	public static void main(String[] args) {
		System.out.println("PrintWriter / 인코딩 ");
		
		FileWriter fw = null;
		FileReader fr = null;
		
		PrintWriter out = null;
		
		BufferedReader br = null;
		BufferedWriter bw = null;
		
		try {
//			fw = new FileWriter(FILE1);
//			bw = new BufferedWriter(fw);
//			out = new PrintWriter(bw);
			
			out = new PrintWriter(new BufferedWriter(new FileWriter(FILE1)));
			
			test_write(out);
			
			System.out.println();
			
			br = new BufferedReader(new FileReader(FILE1));
			
			test_read(br);
			
			out.close();
			br.close();
			
			System.out.println("현재 인코딩 " + System.getProperty("file.endocing"));
			
			// euc-kr로 인코딩하여 저장
			out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(FILE2), "euc-kr")));
			
			test_write(out);
			
			System.out.println();
			
			// 다른 인코딩으로 읽어오면 텍스트 깨진다
//			br = new BufferedReader(new InputStreamReader(new FileInputStream(FILE2)));

			// 원하는 인코딩으로 텍스트 읽기
			br = new BufferedReader(new InputStreamReader(new FileInputStream(FILE2), "euc-kr"));
			
			test_read(br);
			
			
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			out.close();
			
			try {
				if(br != null) br.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		
		
		System.out.println("\n프로그램 종료");
		
	} // end main()

	private static void test_read(BufferedReader br) throws IOException {
		String line;
		StringBuffer sb = new StringBuffer();
		while((line = br.readLine()) != null) {
			sb.append(line + "\n");
		}
		System.out.println(sb);
		
	}

	private static void test_write(PrintWriter out) {
		out.println("안녕하세요 Java 한글이 잘 보이나요?");
		out.print((2000 + 20) + " " + 3.14);
		out.println();
		out.printf("%d-%d-%d\n", 2020, 3, 2);
		out.flush();
		
	}
	
	// TODO
	
} // end class

4. 시스템 정보 확인

package com.lec.java.file14;

public class File14Main {

	public static void main(String[] args) {
		System.out.println("시스템 정보 확인");
		
		System.out.println();
		System.out.println(System.getProperty("os.name"));
		System.out.println(System.getProperty("os.arch"));
		System.out.println(System.getProperty("os.version"));
		
		System.out.println();
		System.out.println(System.getProperty("java.home"));
		System.out.println(System.getProperty("java.version"));
		
		System.out.println();
		// current working directory
		System.out.println(System.getProperty("user.dir"));
		
		// user home directory("내 문서"가 있는 폴더)
		System.out.println(System.getProperty("user.home"));
		
		System.out.println();
		System.out.println(System.getProperty("file.separator"));

		System.out.println("\n프로그램 종료");
		
	} // end main()

} // end class

5. 디렉토리 정보 확인

package com.lec.java.file15;

import java.io.File;

public class File15Main {

	public static void main(String[] args) {
		System.out.println("디렉토리 정보 확인");
		System.out.println();
		// current working directory : 현재작업경로
		String curWorkingDir = System.getProperty("user.dir");
		System.out.println("현재 작업 폴더: " + curWorkingDir);
		
		System.out.println();
		// 현재 작업 디렉토리의 파일 리스트 출력
		// File 클래스: 파일(txt, doc, ...) 객체 또는 디렉토리(폴더) 객체
		File curDir = new File(curWorkingDir);	// 현재 작업 디렉토리 객체
		File [] list = curDir.listFiles();	// 디렉토리 안에 있는 파일과 디렉토리들을 File[] 배열로 리턴
		
		for (int i = 0; i < list.length; i++) {
			if(list[i].isDirectory()) {
				// isDirectory(): File 객체가 디렉토리이면 true 리턴
				// isFile(): File 개게가 파일이면 true 리턴
				System.out.print("DIR" + "\t");
			} else {
				System.out.print("FILE" + "\t");
			}
			
			System.out.print(list[i].getName() + "\t");	// getName() 파일/디렉토리 이름
			System.out.println(list[i].length()); 	// length() 파일의 크기 (byte)
												// 디렉토리의 경우 length() 값은 의미없다.
		}
		
		System.out.println();
		// 디렉토리의 내용 출력, enhanced for 문 이용
		File tempDir = new File("temp");	// 상대경로 이용한 File 객체 생성
		
		File[] list2 = tempDir.listFiles();
		for(File f : list2) {
			if(f.isFile()) {
				System.out.print("File\t");
			} else {
				System.out.println("DIR\t");
			}
			
			System.out.println(f.getName() + "\t" + f.length());
		}
		
		
		System.out.println();
		// 파일 하나에 대한 정보
		String path = "dummy.txt";
		File f = new File(path);	// 새로운 File 객체 생성
		// new File() 했다 하여, 실제 물리적으로 파일을 생성하는 것이 아니다!!
		System.out.println("파일이름(상대경로): " + f.getName());		// 상대경로
		System.out.println("절대경로: " + f.getAbsolutePath());	// 절대경로
		System.out.println("있냐? " + f.exists());
		
		System.out.println("\n프로그램 종료");
		
	} // end main()

} // end File11Main

6. 디렉토리 정보 확인

package com.lec.java.file16;

import java.io.File;
import java.io.IOException;

public class File16Main {

	public static final String TEST_DIRECTORY = "test";
	public static final String TEMP_DIR = "temp";
	public static final String TEST_FILE = "dummy.txt";
	public static final String TEST_RENAME = "re_dummy.txt";
	
	public static void main(String[] args) {
		System.out.println("폴더/파일 생성, 이름변경, 삭제");
		System.out.println();

		String path = System.getProperty("user.dir")
					+ File.separator // Windows(\), Linux (/)
					+ TEST_DIRECTORY;
		System.out.println("절대경로: " + path);
		
		File f = new File(path);
		
		System.out.println();
		// 폴더 생성: mkdir()
		if(!f.exists()) { 	// 폴더가 존재하는지 체크
			// 폴더가 없다면
			if(f.mkdir()) {
				System.out.println("폴더 생성 성공!");
			} else {
				System.out.println("폴더 생성 실패!");
			}
		} else {
			System.out.println("폴더가 이미 존재합니다.");
		}
		
		System.out.println();
		// 파일 생성 : createNewFile()
		File f2 = new File(f, TEST_FILE);	// File(디렉토르 File객체, 파읾명)
		System.out.println(f2.getAbsolutePath());
		
		if(!f2.exists()) {
			// 파일이 존재하지 않으면 생성
			
			try {
				if(f2.createNewFile()) {	// 물리적으로 파일 생성!
					System.out.println("파일 생성 성공!");
				} else {
					System.out.println("파일 생성 실패!");
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		} else {
			System.out.println("파일이 이미 존재합니다");
		}
		
		
		System.out.println();
		// 파일 이름 변경: renameTo()
		// renameTo()를 이용해서 다른 폴더로 이동(move)를 할 수도 있다.
		
		File f3 = new File(f, TEST_RENAME);	// 변경할 이름
		System.out.println(f3.getAbsolutePath());
		
		if(f2.exists()) {
			// 파일이 존재할 때만 이름 변경
			if(f2.renameTo(f3)) {
				System.out.println("파일 이름 변경 성공!");
			} else {
				System.out.println("파일 이름 변경 실패!");	// 이미 re_dummy.txt 가 있으면 실패한다.
			}
		} else {
			System.out.println("변경할 파일이 없습니다");
		}
		
		
		
		System.out.println();
		// 파일 삭제: delete()
		File f4 = new File(f, TEST_RENAME);	// 삭제할 File 객체
		if(f4.exists()) {
			// 파일이 존재하면 삭제
			if(f4.delete()) {
				System.out.println("파일 삭제 성공!");
			} else {
				System.out.println("파일 삭제 실패!");
			}
		} else {
			System.out.println("삭제할 파일이 없습니다");
		}
		
	
		System.out.println("\n프로그램 종료");

	} // end main()

} // end class

7. 웹데이터 가져오기(텍스트)

package com.lec.java.file17;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

/* HTML 데이터, 웹데이터 (텍스트)
 * Java 에서 웹 연결을 위한 객체 두가지
 * 	URL : 웹 상의 주소, 
 * 	HttpURLConnection : 웹연결
 * 		URLConnection
 * 		 └─ HttpURLConnection
 * 
 * 	java.io.Reader    프로그램이 '문자 단위' 데이터를 읽어들이는(read) 통로
 * 		├─ java.io.InputStreamReader    // 스트림 기반의 reader
 * 		└─ java.io.BufferedReader 		// 문자(character) 기반 reader
 */

public class File17Main {

	public static void main(String[] args) {
		System.out.println("웹데이터 가져오기(텍스트)");
		
		StringBuffer sb = readFromUrl("https://www.daum.net");
		System.out.println(sb);
		
		System.out.println("\n프로그램 종료");
	} // end main()
	
	public static StringBuffer readFromUrl(String url_address) {
		StringBuffer sb = new StringBuffer();
		
		URL url = null;	// java.net.URL
		HttpURLConnection conn = null;
		
		InputStream in = null;
		InputStreamReader reader = null;
		BufferedReader br = null;
		
		char [] buf = new char[512];	// 문자 버퍼 준비

		try {
			url = new URL(url_address);
			conn = (HttpURLConnection)url.openConnection();
			
			if(conn != null) {
				
				// 실제 연결되기 전에
				conn.setConnectTimeout(2000); 	// 2초 이내에 연결이 수립안되면 SoketTimeException 발생
				conn.setRequestMethod("GET");
				conn.setRequestProperty("Content-type", "application/x-www-form-urlencoded; charset-UTF-8");
				conn.setUseCaches(false);	// 캐시 사용안함.
				
				System.out.println("request 시작: " + url_address);
				conn.connect();	// request 발생 --> 이후 response 받을때까지 delay
				System.out.println("response 완료");
				
				int responseCode = conn.getResponseCode();
				System.out.println("responseCode: " + responseCode);
				
					if(responseCode == HttpURLConnection.HTTP_OK) {	// 200
						
//						in = conn.getInputStream();
//						reader = new InputStreamReader(in, "utf-8");
//						br = new BufferedReader(reader);
						
						br = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));
						
						int charsRead;
						while((charsRead = br.read(buf)) != -1) {
							sb.append(buf, 0, charsRead);
						}
						
					} else {
						System.out.println("response 실패");
						return null;
					}
				
			} else {
				System.out.println("conn fail");
				return null;
			} 
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (br != null) br.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			if(conn != null) conn.disconnect();	// 종료 전에 연결 끊기
		}
		
		
		return sb;
	}

} // end class

0개의 댓글