23.03.27 : java ( io 마무리, 직렬화, JXL, 파일 포인터, nio 등)

이준영·2023년 3월 27일
0

데이터 - 프로그램 +> 처리(방법)

임시 데이터

  • 변수 / 상수

영구 데이터

(CRUD 중요 : Create(생성), Read(읽기), Update(갱신), Delete(삭제)를 묶어서 일컫는 말, 데이터 가공)

1. 로컬 데이터

  • 일반 파일
    메모장에서 내용을 볼 수 있는 파일(text)
    oracle에서 제공

  • 일반 파일 접근 방법

  1. 파일이나 디렉토리 정보를 알아야 함(java.io.File - NIO => 탐색기, dir 명령 만들기 가능)

  2. 파일(txt) 내용에 접근

1차 스크림 - interface
(InputStream, OutputStream)
(Reader / Writer)
I/O
InputStream / Reader
OutputStream / Writer


=> 구현 : FileInput(Output)Stream / FileReader(Writer)
2차 스크림
BufferedInput(Output)Stream
BufferedReader(Writer)
  • 바이너리 파일
    특별한 프로그램이 존재해야 함(image, sound, doc, xls, ppt, hwp)
    third party (외부 업체에서 제공 받아야 함)

2. 원격 데이터

데이터베이스
OpenAPI



해당 동의 정보만 출력하기

package buffer2;

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

public class Address2 {

	public static void main(String[] args) {
		//입력값 검사
		if(args.length != 1) {
			System.out.println("동이름 형식으로 입력하세요");
			System.exit(0);
		}
		if(args[0].length() < 2) {
			System.out.println("동이름을 두 자이상 입력하세요.");
			System.exit(0);
		}
		
		String strDong = args[0];
		
		BufferedReader br = null;
		
		try {
			br = new BufferedReader(
					new FileReader("./zipcode_seoul_utf8_type2.csv"));
			String str = null;
			while((str = br.readLine()) != null) {
				String strArr[] = str.split(","); 
				//equals(여기서는 문자를 똑같이 써줘야 하기 때문에 안됨), contains / startsWith / indexOf 로 검색하여 찾아주기
				if(strArr[3].contains(strDong)) {
					System.out.println("[" + strArr[0] + "] " + strArr[1] + " " + strArr[2]
							+ " " + strArr[3] + " " + strArr[4] + " " + strArr[5]);
				}
			}
		} catch (FileNotFoundException e) {
			System.out.println("[에러]" + e.getMessage());
		} catch (IOException e) {
			System.out.println("[에러]" + e.getMessage());
		} finally {
			try {if(br != null) br.close();} catch (IOException e) {}
		}
		
	}

}



데이터의 자료형 그대로 넣기(int, float ...)

출력후 새로고침 하고 텍스트 에디터로 보면 숫자들은 잘려서 나온다

import java.io.DataOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class DataOutputStream1 {

	public static void main(String[] args) {
		DataOutputStream dos = null;
		
		try {
			dos = new DataOutputStream(
					new FileOutputStream("./value.dat"));
			
			dos.writeInt(2023);
			dos.writeUTF("UTF-8 형식으로 저장");
			dos.writeFloat(1.8f);
			
			System.out.println("출력 컴플리~뜨");
		} catch (FileNotFoundException e) {
			System.out.println("[에러] : " + e.getMessage());
			e.printStackTrace();
		} catch (IOException e) {
			System.out.println("[에러] : " + e.getMessage());
		} finally {
			if(dos != null) try { dos.close();} catch(IOException e) {}
		}
	}

}

이것을 read메서드들을 통해서 형식 그대로 읽어온다.
입력된 순서대로 읽어와야 함! 바뀌면 이상한 값 나온다.

import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class DataInputStream1 {

	public static void main(String[] args) {
		DataInputStream dis = null;
		
		try {
			dis = new DataInputStream(
					new FileInputStream("./value.dat"));
			
			System.out.println(dis.readInt());
			System.out.println(dis.readUTF());
			System.out.println(dis.readFloat());
			
			System.out.println("입력 완료");
		} catch (FileNotFoundException e) {
			System.out.println("[에러] : " + e.getMessage());
		} catch (IOException e) {
			System.out.println("[에러] : " + e.getMessage());
		} finally { 
			if(dis != null) try { dis.close(); } catch (IOException e ) {}
		}
	}

}



객체 방식의 저장 : ObjectOutputSream

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

public class ObjcectOutputStream1 {

	public static void main(String[] args) {
		ObjectOutputStream oos = null;
		
		try {
			oos = new ObjectOutputStream( new FileOutputStream("./object.dat"));
			
			String[] names = {"홍길동", "박문수", "이몽룡"};
			int[] ages = { 55, 23, 47 };
			double[] number = {3.5, 2.23, 7.91};
			
			oos.writeObject(names);
			oos.writeObject(ages);
			oos.writeObject(number);
			
			System.out.println("출력완료");
		} catch (FileNotFoundException e) {
              System.out.println("[에러] : " + e.getMessage());
		} catch (IOException e) {
			System.out.println("[에러] : " + e.getMessage());
		}
         finally { 
              if(oos != null) try { oos.close(); } catch (IOException e ) {}
          }
	}
	}



위 코드 input으로 읽기

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.Arrays;

public class ObjectInputStream1 {

	public static void main(String[] args) {
		ObjectInputStream ois = null;

		try {
			ois = new ObjectInputStream(new FileInputStream("./object.dat"));

			String[] names = (String[])ois.readObject();
			int[] ages = (int[])ois.readObject();
			double[] number = (double[])ois.readObject();
			
			System.out.println(Arrays.toString(names));
			System.out.println(Arrays.toString(ages));
			System.out.println(Arrays.toString(number));


		} catch (FileNotFoundException e) {
			System.out.println("[에러] : " + e.getMessage());
		} catch (ClassNotFoundException e) {
              System.out.println("[에러] : " + e.getMessage());
		} catch (IOException e) {
			System.out.println("[에러] : " + e.getMessage());
          } finally {
              if (ois != null)try {ois.close();} catch (IOException e) {}
          }

	}

}



직렬화 / 역직렬화

직렬화 : ObjectOutputStream은 객체 직렬화시켜 노드로 출력
역직렬화 : ObjectInputStream은 직렬화된 정보 다시 객체화시킴

직렬화 시킨 모습과 / (transient) 이용하여 역직렬화 한 것


Person 클래스 (생성자와 게터 메서드 생성)


output으로 생성해주고 input 이용하여 읽음 ( Transient 적혀있는 구문은 null출력)




try ~ catch ~ resource

finally문 대체하는 문( 잘 사용하지 않음)



byte 기반 스트림을 char 기반 스트림으로 변경하는 스트림


바이트 기반으로 입 출력하기(scanner 전통적 버전)

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

public class System1 {

	public static void main(String[] args) {
		// 키보드 입력
		InputStream is = null; //  Stream이기 때문에 1바이트만 가능(다국어 불가)
		
		try {
			is = System.in;
			System.out.println("데이터 입력 : ");
			//아스키코드로 나와서 char 형변환 해주기, 한 자만 나옴(여러 개 써줘서 여러 자 나오게 하기)
			System.out.println((char)is.read()); 
			System.out.println((char)is.read()); 
			System.out.println((char)is.read()); 
			
			System.out.println("입력 완료");
		} catch (IOException e) {
			System.out.println("[에러] : " + e.getMessage());
		} finally {
			if(is != null)try {is.close();} catch (IOException e) {}
		}
	}
}


char 기반으로 입 출력하기

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

public class System2 {

	public static void main(String[] args) {
		// 키보드 입력
		//InputStream is = null; //  Stream이기 때문에 1바이트만 가능(다국어 불가)
		InputStreamReader isr = null;
		
		try {
			//is = System.in;
			isr = new InputStreamReader(System.in); //축약
			
			System.out.println("데이터 입력 : ");
			//아스키코드로 나와서 char 형변환 해주기, 한 자만 나옴(여러 개 써줘서 여러 자 나오게 하기)
			System.out.println((char)isr.read()); 
			System.out.println((char)isr.read()); 
			System.out.println((char)isr.read()); 
			
			System.out.println("입력 완료");
		} catch (IOException e) {
			System.out.println("[에러] : " + e.getMessage());
		} finally {
			if(isr != null)try {isr.close();} catch (IOException e) {}
		}
	}
}


buffer 이용하여 업그레이드 하기(성능 ↑)

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

public class System3 {

	public static void main(String[] args) {
		// 키보드 입력
		BufferedReader br = null;
		
		try {
			br = new BufferedReader(new InputStreamReader(System.in)); // 축약
			
			System.out.println("데이터 입력 : ");
			//아스키코드로 나와서 char 형변환 해주기, 한 자만 나옴(여러 개 써줘서 여러 자 나오게 하기)
			System.out.println((char)br.read()); 
			System.out.println((char)br.read()); 
			System.out.println((char)br.read()); 
			
			System.out.println("입력 완료");
		} catch (IOException e) {
			System.out.println("[에러] : " + e.getMessage());
		} finally {
			if(br != null)try {br.close();} catch (IOException e) {}
		}
	}
}


위 코드 한 줄 통으로 읽기(제일 많이 쓰는 형태)

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

public class System3 {

	public static void main(String[] args) {
		// 키보드 입력
		BufferedReader br = null;
		
		try {
			br = new BufferedReader(new InputStreamReader(System.in));
			
			System.out.println("데이터 입력 : ");
			
			//한 줄 통으로 읽기
			System.out.println(br.readLine());
			
			System.out.println("입력 완료");
		} catch (IOException e) {
			System.out.println("[에러] : " + e.getMessage());
		} finally {
			if(br != null)try {br.close();} catch (IOException e) {}
		}
	}
}



응용 - system.in / BufferedReader 등 사용하여 구구단 출력하기

Scanner 사용하지 않고 입력하게 만드는 코드

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

public class System1 {

	public static void main(String[] args) {
		// 키보드 입력
		BufferedReader br = null;
		
		try {
			br = new BufferedReader(new InputStreamReader(System.in));
			
			System.out.println("시작 단수 : ");
			String startDan = br.readLine();
			System.out.println("끝 단수 : ");
			String endDan = br.readLine();
			
			for(int i = Integer.parseInt(startDan) ; i <= Integer.parseInt(endDanS); i++) {
				for(int j = 1; j<= 9; j++) {
					System.out.println(i + " X " + j + " = " + (i*j));
				}
			}
		} catch (IOException e) {
			System.out.println("[에러] : " + e.getMessage());
		} finally { 
			if(br != null) try { br.close(); } catch (IOException e ) {}
		}
	}
}




엑셀

2003버전 xls -> JXL 라이브러리 사용 (https://jexcelapi.sourceforge.net) : 자바 엑셀 전용 API
이후 xlsx -> Apache POI 사용 (https://poi.apache.org/)
=> ObjectStream 형식으로 저장 = > 공개 후 Open Source Library 저장

이클립스에서 JXL 확인하기

자바 프로젝트만들기 -> NEXT에서 Libraries -> Classpath -> Add External 클릭하여



이클립스 workBook(excel)의 다양한 메서드


선언 밑 버전 출력 : getVersion()


시트 개수, 이름, 해당 시트 이름 출력

getNumberSheet : 해당 워크시트 개수
getSheetNames = 워크시트 이름
getSheet() / getName = ()번째 시트의 이름 출력


행과 열 총 수 구하기 : getRows(행) / getColumns(열)


(x,y) 위치의 내용 읽어오기 : getCell(x,y)



응용 - 로또 엑셀파일의 내용들 이클립스에서 출력하기

집에서 고치기(미완성)

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

import jxl.Cell;
import jxl.Sheet;
import jxl.Workbook;
import jxl.read.biff.BiffException;

public class ChangeText {

	public static void main(String[] args) {
		Workbook wrkBook = null;
		
		try {
			wrkBook = Workbook.getWorkbook(new FileInputStream("./lotto(1~1060).xls"));
			Sheet sheet = wrkBook.getSheet(0);
			
			int cell[] = new int[10];
			
				for(int j = 3; j<sheet.getRows(); j++) {
					Cell cell1 = sheet.getCell(1, j); //열, 행
					Cell cell2 = sheet.getCell(2, j); 
					Cell cell13 = sheet.getCell(13, j);
					Cell cell14 = sheet.getCell(14, j);
					Cell cell15 = sheet.getCell(15, j);
					Cell cell16 = sheet.getCell(16, j);
					Cell cell17 = sheet.getCell(17, j);
					Cell cell18 = sheet.getCell(18, j);
					Cell cell19 = sheet.getCell(19, j);
					System.out.print(cell1.getContents() + "  " + cell2.getContents() +
							" " + cell13.getContents() + " " + cell14.getContents() + 
							" " + cell15.getContents() + " " + cell16.getContents() +
							" " + cell17.getContents() + " " + cell18.getContents() +
							" " + cell19.getContents());
					
					System.out.println();
			}
	
		} catch (BiffException e) {
			System.out.println("[에러] : " + e.getMessage());
		} catch (FileNotFoundException e) {
			System.out.println("[에러] : " + e.getMessage());
		} catch (IOException e) {
			System.out.println("[에러] : " + e.getMessage());
		} finally {
			if(wrkBook != null) wrkBook.close();
		}
		
	}

}

일부분 사진



메모리 기반의 입/출력 처리 :CharArrayReader(Writer)

메모리에서 스트림 기능이 가능하다.

CharArrayReader

import java.io.CharArrayReader;
import java.io.IOException;
import java.util.Arrays;

public class CharArrayReader1 {

	public static void main(String[] args) {
		//메모리에서 스트림 기능이 가능
		char[] memory = {'안', '녕', ' ', 'j', 'a', 'v', 'a' };
		
		try( CharArrayReader charArry = new CharArrayReader(memory) ) {
			
			char[] buffer = new char[5];
			
			int read = 0;
			while((read = charArry.read(buffer)) > 0) {
				System.out.println(Arrays.toString(buffer));
			}
		} catch(IOException e) {
			System.out.println("[에러] : " + e.getMessage());
		}
	}

}


CharArrayWriter

import java.io.CharArrayReader;
import java.io.CharArrayWriter;
import java.io.IOException;
import java.util.Arrays;

public class MemoryIOTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		char[] memory = "안녕 Java World".toCharArray();
		char[] buffer = new char[5];
		int read = 0;
		try(CharArrayReader cReader = new CharArrayReader(memory)) {
			CharArrayWriter cWriter = new CharArrayWriter();
			
			while((read = cReader.read(buffer)) > 0) {
				cWriter.write(buffer, 0, read);
			}
			System.out.println(Arrays.toString(cWriter.toCharArray()));
		} catch (IOException e) {
			System.out.println("[에러]");
		}
	}

}



RandomAccessFile

파일에 대해 내가 위치를 지정하면서 읽을 수 있다.
객체 하나로 읽기 쓰기 둘 다 가능하다.(DataInput, DataOutput를 implements했기 때문)

선언


파일포인터

파일포인터를 옮겨가며 읽고 쓰기가 가능하며 현재 내 위치를 알거나 정할 수 있다.



getFilePointer

파일 포인터 위치를 얻는다.(처음에 그냥 사용할 시 0)


seek()

해당()위치로 옮긴다, 내가 읽고 싶은 위치 정하기 가능(자기가 설정한 자료형에 대한 값으로만 이동 가능하다, int로 했는데 3,5,7 등 사용하면 이상한 수 출력)





Properties<k,v> :

애플리케이션 환경설정 파일에 데이터를 읽고 쓰는 기능 가지고 있음
load : reader을 이용해 속성 읽어옴
store :writer 이용해 속성을 파일에 저장, comment 추가 가능



NIO

기존의 I/O를 대체하는 개념이 아니라 다른 특성을 가진 I/O
(좀 향상된 I/O)

BasicFileAttributes :

파일 시스템의 파일과 관련된 기본 속성

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
import java.sql.Date;
import java.util.concurrent.TimeUnit;


public class Files1 {

	public static void main(String[] args) {

		File file = new File("./score.dat");
		Path filePath = file.toPath();
		
		BasicFileAttributes attributes = null;
		
		try {
			//파일 속성 불러오기
			attributes = Files.readAttributes(filePath, BasicFileAttributes.class);
			
			//파일의 생성일자 조회
			long creationTime = attributes.creationTime().to(TimeUnit.MILLISECONDS);
			
			//데이트 객체 생성
			Date date = new Date(creationTime);
			//한글로 시간 출력
			System.out.println(date.toLocaleString());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}



Path로 전체 읽기

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;

public class File2 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Path target = Paths.get("./test1.txt");
		
		try {
			List<String> lines = Files.readAllLines(target);
			for(String line : lines) {
				System.out.println( line );
			}
		} catch (IOException e) {
			System.out.println("[에러] : " + e.getMessage());
		}
	}

}

profile
끄적끄적

0개의 댓글