JAVA/Java 기초

기본 타입 스트림.java

john_ 2023. 1. 31. 12:48
728x90

2023.01.30 - [JAVA/Java 기초] - 입출력 스트림-2.java

 

입출력 스트림-2.java

2023.01.30 - [JAVA/Java 기초] - 입출력 스트림.java 입출력 스트림.java 입력 스트림과 출력 스트림 프로그램을 기준으로 데이터가 들어오면 입력 스트림, 데이터가 나가면 출력 스트림 프로그램이 다른

less-go.tistory.com

 

이전글에서부터 계속됩니다

 


기본 타입 스트림

보조스트림
DataInputStream
DataOutputStream

프로그램에서 사용한 데이터 타입 그대로 저장하고 불러올때 사용합니다.
로컬 프로그램에서 로컬파일을 데이터베이스 처럼 이용할때 사용합니다.
  • 바이트 스트림에 보조스트림인 DataInputStream과 DataOutputStream 을 연결하면 기본타입(boolean, char, short, int, long, float, double) 값을 입출력 할수 있습니다.

 

 

import java.io.*;

public class DataInputOutputStreamExam {

	public static void main(String[] args) throws Exception {

		FileOutputStream fos = new FileOutputStream("c:/Temp/privitive.db");
		DataOutputStream dos = new DataOutputStream(fos);
		
		//기본타입 출력
		dos.writeUTF("홍길동");
		dos.writeDouble(95.5);
		dos.writeInt(1);
		
		dos.writeUTF("감자바");
		dos.writeDouble(90.3);
		dos.writeInt(2);
		
		dos.flush();
		dos.close();
		fos.close();
		
		//DataInputStream 데이터 불러오기
		FileInputStream fis = new FileInputStream("c:/Temp/privitive.db");
		DataInputStream dis = new DataInputStream(fis);
		
		for(int i = 0; i<2; i++) {
			String name = dis.readUTF();
			double score = dis.readDouble();
			int order = dis.readInt();
			System.out.println(name + " : " + score + " : " + order);
		}
		
		dis.close();
		fis.close();
	}
}
결과 : 
c:/Temp/privitive.db 에 
홍길동 : 95.5 : 1
감자바 : 90.3 : 2
의 값을 갖게 한후 파일을 생성후

디버그 창에
홍길동 : 95.5 : 1
감자바 : 90.3 : 2
을 출력
DataOutputStream으로 출력한 데이터를 다시 DataInputStream으로 읽어 올때에는 출력한 순서와 동일한 순서로 읽어야 합니다.
예를 들어 출력시의 순서가 int → Boolean → double 이라면, 읽을 때의 순서도 int → Boolean → double 이어야 합니다.

 


PrintStream와 PrintWriter

  • 프린터와 유사하게 출력하는 print(), println(), printf() 메소드를 가진 보조 스트림

 

  • PrintStream은 바이트 출력 스트림과 연결되고, PrintWriter는 문자 출력 스트림과 연결합니다.

 


package IO4;

import java.io.FileOutputStream;
import java.io.PrintStream;

public class PrintStreamExam {

	public static void main(String[] args) throws Exception{

		FileOutputStream fos = new FileOutputStream("c:/Temp/printstream.txt");
		PrintStream ps = new PrintStream(fos);
		
		ps.print("마치 ");
		ps.println("프린터가 출력하는것 처럼");
		ps.println("데이터를 출력합니다.");
		ps.printf("| %6d | %-10s | %10s | \n", 1, "홍길동", "도적");
		// %6d = 6칸 차지
		// %-10s = 10칸짜리 왼쪽정렬/ %10s = 10칸짜리 오른쪽정렬
		ps.printf("| %6d | %-10s | %10s | \n", 2, "감자바", "학생");
		
		ps.flush();
		ps.close();
	}
}
결과 : 
Temp에 printstream.txt 파일 생성

내용 :
마치 프린터가 출력하는것 처럼
데이터를 출력합니다.
|      1 | 홍길동        |         도적 | 
|      2 | 감자바        |         학생 |

 


객체 스트림 :

  • 직렬화 : 자바는 메모리에 생성된 객체를 파일 또는 네트워크로 출력하는데, 객체를 출력하려면 필드값을 일렬로 늘어선 바이트로 변경해야 합니다. (객체 : 필드 → 바이트)
  • 역직렬화 : 직렬화 된 바이트를 객체의 필드값으로 복원하는 것 입니다. (객체 : 필드 ← 바이트)
  • ObjectOutputStream은 바이트 출력 스트림과 연결되어 객체를 직렬화하고, ObjectInputStream은 바이트 입력 스트림과 연결되어 객체로 복원하는 역직렬화.

import java.io.*;
import java.util.Arrays;

public class ObjectInputStreamExam {

	public static void main(String[] args) throws Exception{

		// fos에 oos 보조 스트림 연결
		FileOutputStream fos = new FileOutputStream("c:/Temp/object.dat");
		ObjectOutputStream oos = new ObjectOutputStream(fos);
		
		//객체 생성
		Member m1 = new Member("fall", "단풍이");
		Product p1 = new Product("노트북", 1500000);
		int[] arr1 = {1,2,3};
		
		//객체를 파일에 저장
		oos.writeObject(m1);
		oos.writeObject(p1);
		oos.writeObject(arr1);
		
		oos.flush();
		oos.close();
		fos.close();
		
		// 저장된 객체 타입으로 저장된 파일을 불러오기
		// FileinputStream을 ObjectInputStream 보조 스트림 연결
		FileInputStream fis = new FileInputStream("c:/Temp/object.dat");
		ObjectInputStream ois = new ObjectInputStream(fis);
		
		// 파일을 읽고 같은 타입의 객체에 대입 (역직렬화를 통해 객체로 복원)
		Member m2 = (Member)	ois.readObject();
		Product p2 = (Product)	ois.readObject();
		int[] arr2 = (int[]) ois.readObject();
		
		ois.close();
		fis.close();
		
		System.out.println(m2);
		System.out.println(p2);
		System.out.println(Arrays.toString(arr2));
	}
}
결과 :
fall: 단풍이
노트북: 1500000
[1, 2, 3]                                                                            

Serializable 인터페이스

  • 멤버가 없는 빈 인터페이스이지만, 객체를 직렬화 할수 있다고 표시하는 역할입니다.
  • 인스턴스 필드값은 직렬화 대상입니다.
  • 정적 필드값과 transient로 선언된 필드값은 직렬화에서 제외되므로 출력되지 않습니다.


serialVersionUID 필드

직렬화 할때 사용된 클래스와 역직렬화할 때 사용된 클래스는 동일한 클래스여야 합니다.

클래스 내용이 다르더라도 두 클래스가 동일한 serialVersionUID 상수값을 가지면 역직렬화가 가능합니다.

 


File 클래스

  • File 클래스로부터 File 객체를 생성 합니다.

  • exists() 메소드가 false를 리턴할 경우, 다음 메소드로 파일 또는 폴더를 생성합니다.

  • exists() 메소드의 리턴값이 true 라면 다음 메소드를 사용합니다.


 

package IO6;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
public class FileExam {

	public static void main(String[] args) throws Exception{

		//File 객체 생성
		File dir = new File("c:/Temp/images");// 디렉토리 지정
		File file1 = new File("c:/Temp/file1.txt");	// file1.txt 파일 지정
		File file2 = new File("c:/Temp/file2.txt");	// file2.txt 파일 지정
		File file3 = new File("c:/Temp/file3.txt"); // file3.txt 파일 지정
		
		// 존재유무 exists() : 존재 : T / 존재X : F
		if(dir.exists() == false) {	dir.mkdir();}// 중간 경로가 없는 경우에도 중간 경로를 생성
		if(file1.exists() == false) {file1.createNewFile();}
		if(file2.exists() == false) {file2.createNewFile();}
		if(file3.exists() == false) {file3.createNewFile();}
		
		//Temp 폴더의 내용을 출력
		File temp = new File("C:/Temp");	//경로 지정
		File[] contents = temp.listFiles();	//경로 안의 파일과 디렉토리 목록을 File 형태로 저장
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd a HH:mm");	//날짜출력
		
		for(File file : contents) {	//contents에 있는 파일과 디렉토리 목록을 하나씩 file에 대입
			System.out.printf("%-25s", sdf.format(new Date(file.lastModified())));
			//file 마지막 수정 날짜 출력
			if(file.isDirectory()) { // 파일의 내용이 디렉토리인지 확인
				System.out.printf("%-10s%-20s", "<DIR>", file.getName());
				//디렉토리일 경우 <DIR>을 출력,
				//<DIR>에 좌측정렬로 10칸의 String형 자리 할당 : %-10s -- 첫번째
				//파일의 이름을 좌측정렬로 20칸의 String형 자리 할당 : %-20s -- 두번째
			} else {
				System.out.printf("%-10s%-20s", file.length(), file.getName());
				//디렉토리가 아닐경우 파일의 길이를 출력합니다.
				//파일의 길이를 좌측정렬로 String형 10자리를 할당하여 출력: %-10s -- 첫번째
				//파일의 이름을 좌측정렬로 String형 20자리를 할당하여 출력 : %-20s -- 두번째
			}
			System.out.println();
		}
	}
}
결과 :
2023-01-31 오후 14:24      0         file1.txt           
2023-01-31 오후 14:24      0         file2.txt           
2023-01-31 오후 14:24      0         file3.txt           
2022-12-05 오후 12:29      628       hello2022.class     
2022-12-05 오후 12:28      147       hello2022.java      
2023-01-31 오후 14:24      <DIR>     images              
2022-12-20 오전 08:44      <DIR>     NEO                 
2022-12-30 오후 13:55      <DIR>     NEO2                
2023-01-31 오후 12:35      187       object.dat          
2023-01-31 오후 12:10      171       printstream.txt     
2023-01-31 오전 11:32      46        privitive.db        
2023-01-31 오전 10:35      664489    targetFile1.jpg     
2023-01-31 오전 10:35      664489    targetFile2.jpg     
2022-12-20 오후 15:23      567654    test.jpg            
2023-01-31 오전 09:49      19        test.txt            
2023-01-30 오후 16:24      3         test1.db            
2023-01-30 오후 16:39      3         test2.db            
2023-01-30 오후 17:26      567654    test2.jpg

 


Files 클래스

  • Files 클래스는 정적 메소드로 구성되어 있기 때문에 File 클래스처럼 객체로 만들 필요가 없습니다.
  • Files의 정적 메소드는 운영체제의 파일 시스템에게 파일 작업을 수행하도록 위임합니다.

files.createDirectory = 부모 디렉토리가 없을 경우 디렉토리 생성 실패
files.createDirectories = 부모 디렉토리가 없을 경우 부모 디렉토리까지 생성
  • 위 메소드들은 매개값으로 Path 객체를 받습니다.
  • Path 객체는 파일이나 디렉토리를 찾기 위한 경로 정보를 가지고 있는데, 정적 메소드인 get() 메소드로 다음과 같이 얻을수 있습니다.
Path path = Paths.get(String first, String... more)
  • get()메소드의 매개값은 파일 경로인데, 전체 경로를 한번에 지정할수도 있고, 상위 디렉토리와 하위 디렉토리를 나열해서 지정해도 좋습니다.
  • 다음은 특정 경로를 이용해서 Path 객체를 얻는 방법입니다.
Path path = Paths.get("C:/Temp/dir/file.txt");
Path path = Paths.get("C:/Temp/dir/", "file.txt");
Path path = Paths.get("C:", "Temp", "dir", "file.txt");
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

public class FilesExam {

	public static void main(String[] args) {
		
		try {
			String data = 
					"" + 
					"id: winder\n" + 
					"email : winter@mycompany.com\n" + 
					"tel: 010-123-1234";
			
			Path path = Paths.get("C:/Temp/user.txt");
			
			Files.writeString(Paths.get("C:/Temp/user.txt"), data, Charset.forName("UTF-8"));
			
			System.out.println("파일 유형: " + Files.probeContentType(path));
			System.out.println("파일 크기: " + Files.size(path) + " bytes");
			
			String content = Files.readString(path, Charset.forName("UTF-8"));
			System.out.println(content);
		// 한글에 대한 캐릭터 셋 : UTF-8(4byte), EUC-KR(3Byte)	
		}catch(IOException e) {
			e.printStackTrace();
		}
	}
}

 


 

728x90

'JAVA > Java 기초' 카테고리의 다른 글

서버의 동시 요청 처리.java  (0) 2023.02.01
네트워크 기초(IP, TCP, UDP).java  (0) 2023.01.31
요소 커스텀 집계.java  (0) 2023.01.30
입출력 스트림-2.java  (0) 2023.01.30
입출력 스트림.java  (0) 2023.01.30