유블로그

[Java] Java IO 본문

Java

[Java] Java IO

yujeong kang 2020. 8. 13. 10:44

File을 읽고 쓰는 것은 JVM이 읽고 다시 파일로 쓰는 과정이다. Java는 이것을 Stream으로 표현한다.

데이터의 시작과 끝이 있고 양쪽사이에 데이터의 이동이 생기는데 양쪽을 Node라고 하고,

데이터의 흐름을 Stream이라고 한다.

 

Stream은 문자(Character)와 비문자(Binary)로 나누어서 생각해야 한다.

문자 처리 Stream은 데이터 읽는 Reader, 데이터 쓰는 Writer로 구분된다.

비문자는 데이터를 읽는 InputStream과 데이터를 쓰는 OutputStream으로 나눠진다.

아래는 이를 표로 나타낸 것이다. IO와 관련된 객체 생성을 할 수 없는 추상화된 클래스들이다.

자식클래스가 상속을 받아 사용할 수 있다.

  입력 출력
byte 단위 InputStream OutputStream
char 단위 Reader Writer

ex > FileInputStream, FileOutputStream, FileReader, FileWriter ....

 


Node Stream이 구성되지만 Node Stream의 시작과 끝 사이에서 다른 기능을 수행하는 Stream들이 있다.

  Input / Reader Output / Writer 처리단위 기능
Buffered~ BufferdInputStream BufferedOutputStream Byte Buffer를 활용해서 속도 향상.

BufferedReader BufferedWriter Character
Object~ ObjectInputStream ObjectOutputStream Binary 메모리의 객체 상태를 파악.

Buffered~ 는 일정 공간에 데이터를 쌓아놓고 꽉 차면 한꺼번에 처리한다.(flush) -> 속도↑

꽉 차지 않아도 처리해야 하는 경우는 마지막 데이터일 경우! -> close()

buffered~로 파일에 썼는데 안에 실제 내용이 없을 때는 buffer가 비워지지 않은 것.

 

+

속도를 올리고 싶은데 문자로 입력 받고 싶다 -> BufferReader

속도를 올리고 싶은데 Byte단위로 입력 받고 싶다 -> BufferedInputStream

 

이런식으로 그 때 상황에 맞게 클래스 선택

 

.java 파일을 읽어야 하는데 빠른 속도로 읽고 싶다 -> BufferedReader  br = new BufferedReader(new FileReader());

 

public class BufferPerformanceTest {
	public static void main(String[] args) {
		
		File src = new File("c:/Windows/explorer.exe");
		File target = new File("c:/Temp/copied_explorer.exe");
		
		try (FileInputStream fi = new FileInputStream(src);
			 FileOutputStream fo = new FileOutputStream(target);
			 BufferedInputStream bi = new BufferedInputStream(fi);
			 BufferedOutputStream bo = new BufferedOutputStream(fo);) {
			
			 copy("노드", fi, fo);
			 copy("보조", bi, bo);
			
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void copy(String type, InputStream input, OutputStream output) throws IOException {
		long start = System.nanoTime();
		byte[] cart = new byte[1024];	// 최대 1024개 읽을 수 있음. 대상이 InputStream과 OutputStream 이니까 byte 배열 선언한 거임.
		// 만약 매개변수가 Reader 와 Writer 였다면 char 배열 선언했을 것.
		int read = -1;
		while ((read = input.read(cart)) > 0) {	// cart의 크기만큼 최대한으로 꽉 채워라. read가 -1 이 되면 읽을 게 없다는 뜻. read에는 실제 읽은 개수 저장됨.
			output.write(cart, 0, read);	// cart 내용을 0부터 read 만큼 쓰겠다.
		}
		long end = System.nanoTime();
		System.out.println(type + ", 소요 시간: " + (end - start) + "ns");
	}
}

< Separator >

물리적인 file과 folder를 모두 표현할 수 있는 File Class는 OS 마다 다른 경로 구분자 (ex- '/' '\') 로 File.Separator를 사용할 수 있다.

 

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
	
public class FileTest {
	public static void main(String[] args) throws IOException, URISyntaxException {
		
		String dirName = "c:"+File.separator+"Users"+File.separator+"mydir";
		
		File file1 = new File(dirName);
		file1.mkdir();
		
		File file2 = new File(dirName, "test2.txt");
		file2.createNewFile();
		
		File file3 = new File(new URI("file:///C:/Users/mydir/test3.txt"));	// URI : 네트워크에서 사용하는 주소 개념... 실제 주소 X
		file3.createNewFile();
		
//		file3.delete();
	}
}

 


 

< 객체 읽고 쓰기 >

public class ObjectStreamTest {
	
		public static void main(String[] args) {
			File target = new File("c:" + File.separator + "Users" + File.separator + "objPerson.dat");
			Person person = new Person("홍길동", 20, "111111-2222222", "hong", "1234");
			try {
				//객체 저장
//				ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream(target));
//				oos.writeObject(person);
//				oos.close();
				
				// 객체 로딩
				ObjectInputStream ois = new ObjectInputStream(new FileInputStream(target));
				Object readed = ois.readObject();
				if (readed != null && readed instanceof Person) {
					Person casted = (Person) readed;
					System.out.println(casted);
				}
				ois.close();
				
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
}

class Person implements Serializable {	// 직렬화 : Serializable 인터페이스 사용(+ 추상 메서드 없음. flag 형태로 직렬화 대상이다 / 아니다 만 구분)
					// Serializable 인터페이스 implements 해줘야 객체 읽고 쓰기 가능
	private static final long serialVersionUID = 1L;	// 객체 직렬화 과정에서 사용되는 고유의 id 개념
	private String name;
	private int age;
	private transient String ssn;	// 직렬화에서 빠질 요소
	
	public Person(String name, int age, String ssn, String userId, String userPass) {
		this.name = name;
		this.age = age;
		this.ssn = ssn;
	}
	
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + ", ssn=" + ssn	+ "]";
	}
}

 

- 객체를 읽어서 csv 파일 만들고 가져오기

excel 열고 데이터탭 -> 텍스트 클릭 -> 파일 선택 -> 구분기호로 분리됨 선택 후 다음 -> 구분 기호 기타 선택 후 맞는 구분기호 입력 -> 열 데이터 서식을 텍스트로 -> 확인 하면 데이터가 칸 별로 잘 나옴

'Java' 카테고리의 다른 글

[Java] Lambda  (0) 2020.08.13
[Java] XML  (0) 2020.08.13
[Java] 내부 클래스  (0) 2020.08.12
[Java] final  (0) 2020.08.12
[Java] Abstract, Interface  (0) 2020.08.12