250x250
Notice
Recent Posts
Recent Comments
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
Tags more
Archives
Today
Total
관리 메뉴

개린이 개발노트

국비지원 JAVA(자바) 프로그래밍 (입출력 스트림) 본문

국비지원(국비교육) 웹 개발자 과정

국비지원 JAVA(자바) 프로그래밍 (입출력 스트림)

개린이9999 2022. 12. 7. 09:09
728x90

입출력 스트림 (단방향)

큐-> FIFO  (Fisrt IN First Out) 저장장치가 있을 때 들어오고 나가는 것을 저장하는 장치 

먼저들어온것들이 먼저 나가는것

제일 많이 비유하는게 프링글스 통에 밑에 구멍난 경우!

 

스택-> FILO LIFO  (스택쌓는다는 말)

프링글스 통에 넣어서 쌓게함 스택은 밑에 구멍이 안 뚫려있음. 그래서 먼저들어간게 나중에 나옴 

 

단방향  한방향으로만 갈수있음

반이중  동시에 입출력이 안되고 한쪽이 입력중이면 반대쪽은 안됨

전이중  동시에 주고받음 

 

스트림 처리방법

 

바이트 기반 처리 (1byte 단위로 처리(2진수 형태로 되어있음) ): 영상, 음악, 그림 ,사진

InputStream, OutputStream 

InputStream: fileinputstream, 

 

문자 기반 처리 : 문자열 

~Reader, ~Writer 


바이트 기반 처리 

package 입출력스트림;

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

public class Sample01 {

	public static void main(String[] args) {

		try {
			InputStream in = System.in;
			int data = 0;

			while ((data = in.read()) != -1) {				//read 자체가 1byte씩 읽어 오지만 정수형태로 읽어오게 되고
				System.out.print((char) data);				// 그냥 출력해버리면 읽어오면 숫자로 나옴
			}
		} catch (IOException e) {
		
		}
	}
}

in.read()로 불러온것을 data 에 대입-> data = in.read()  를 먼저처리 하기위해 괄호를 넣는다.
InputStream in = System.in -> 스캐너 같은 기능 입력 가능하게 함

 

Sample01을 1번방식 불러오게하기 ↓

.read() 에 그냥 아무것도 없음  -1에 끝나게 됨.

package 입출력스트림;

import java.io.FileInputStream;

public class Sample02 {

   public static void main(String[] args) {
      
      try { //괄호안에 경로를 설정하면 경로에 있는 데이터를 가져와서 fis 변수에 저장됨
         FileInputStream fis = new FileInputStream("src/입출력스트림/Sample01.java");
               
            int data = 0; //종료시키게 하기 위한 변수 하나 선언
            
            while((data=fis.read()) != -1) {
               System.out.print((char)data);
            }
      } catch(Exception e) {
         
      }

   }

}

 

Sample01을 2번방식 불러오게하기 ↓

.read(byte[])b: 배열 b의 크기만큼만 읽음  더 읽을 배열이 없으면 -1리턴 시키고 종료 

바이트 형식에 맞춰서 불러오게끔 read를 함 

배열 크기를 메서드로 설정함↓

 

읽을 수 있는 크기만큼 배열 할당

package 입출력스트림;

import java.io.FileInputStream;

import com.sun.org.apache.bcel.internal.generic.NEW;

public class Sample02 {

   public static void main(String[] args) {
      
      try { //괄호안에 경로를 설정하면 경로에 있는 데이터를 가져와서 fis 변수에 저장됨
         FileInputStream fis = new FileInputStream("src/입출력스트림/Sample01.java");
               
            int data = 0; //종료시키게 하기 위한 변수 하나 선언
            
            byte[] buf = new byte[fis.available()]; 
            
            while((data=fis.read(buf)) != -1) {
               System.out.print(new String(buf,0,data));
            }
      } catch(Exception e) {
         
      }

   }

}

한글이 안깨지는 결과값 도출 

 

Sample01을 3번방식 불러오게하기 ↓

.read(bytep[]b, int off, int len) : 최대 len(길이)만큼 바이트를 읽음  배열 b[off]에서 부터 저장 

이런식으로 변경!


 

.close()  처리할 거 다 처리하고 스트림 연결 끊어버리는 메서드 

연결 끊어버리는 .close를 이용할때는 대부분 finally 사용!! 

 

package 입출력스트림;

import java.io.FileInputStream;

import com.sun.org.apache.bcel.internal.generic.NEW;

public class Sample02 {

   public static void main(String[] args) {
	   FileInputStream fis =null;
      
	   
	   try { //괄호안에 경로를 설정하면 경로에 있는 데이터를 가져와서 fis 변수에 저장됨
         fis = new FileInputStream("src/입출력스트림/Sample01.java");
               
            int data = 0; //종료시키게 하기 위한 변수 하나 선언
            
            byte[] buf = new byte[fis.available()]; 
            
            while((data=fis.read(buf,0,buf.length)) != -1) {
               System.out.print(new String(buf,0,data));
            }
      } catch(Exception e) {
         
      } finally {
		try {
			fis.close();
		} catch (Exception e2) {
			// TODO: handle exception
		}
	}

   }

}

이 Java 코드=.close;()  ↑  FileInputStream을 사용하여 파일을 읽는 간단한 예. FileInputStream은 파일에서 이진 데이터를 읽는 데 사용되며, 프로그램이 파일에서 읽는 것을 마칠 때 스트림이 제대로 닫히도록 하는 데 사용됨. 코드는 파일의 내용을 바이트 배열로 읽은 다음 배열을 문자열로 변환하여 콘솔에 인쇄!! 


문자 기반 처리

 

문자 스트림 

파일인풋스트림과 파일리더의 차이 

Reader -2byte

.read()

.read(char[] c)

.read(char[] c,int off, int len)

package 입출력스트림;

import java.io.FileReader;

public class Sample03 {

	public static void main(String[] args) {

	FileReader fr= null;
	
	try {
		fr = new FileReader("src/입출력스트림/Sample01.java");
		int data = 0;
		while( (data=fr.read())!= -1) {
			System.out.print((char)data);
		}
	} catch (Exception e) {
	
	}finally {
		try {
			fr.close();
		} catch (Exception e2) {
		}
	}
	}

}

파일리더에 

BufferedReader (보조스트림)사용하는법

사용이유 -> 속도향상 

ex) br= new BufferedReader(fr); -> 버퍼가 어떤 것을 보조할지(fr을 보조하려고 괄호 안에 fr을 넣음)

package 입출력스트림;

import java.io.BufferedReader;
import java.io.FileReader;
import java.nio.Buffer;

public class Sample04 {

	public static void main(String[] args) {

		FileReader fr = null;
		BufferedReader br = null;

		try {
			fr = new FileReader("src/입출력스트림/Sample01.java");
			br = new BufferedReader(fr); // 버퍼가 어떤 것을 보조할지(fr을 보조하려고 fr을 넣음)

			String txt = null;

			while ((txt = br.readLine()) != null) {
				System.out.println(txt);
			}

		} catch (Exception e) {
		
		}finally {
			try {
				br.close();
				fr.close();
			} catch (Exception e2) {
			
			}
		}
	}

}

br -> fr순으로 close! 

 


아웃풋스트림

바이트 출력 스트림 - OutputStream

XXXOutputstream

.flush(); 기능-> 스트림에 남아있는 찌꺼기(?) 전부 내보내는 기능 

 

package 입출력스트림;

import java.io.FileOutputStream;

public class Sample05 {

	public static void main(String[] args) {
 
		FileOutputStream fos = null;
		
		try {
			fos= new FileOutputStream("text.txt");
			
			fos.write(65);
			fos.write(66);
			fos.write(67);
		}	catch (Exception e) {
		
		} finally {
			try {
				fos.flush();	
				fos.close();
			} catch (Exception e2) {
			
			}
		}
	}

}

폴더 누르고 f5키하면 

text.txt 결과값 ABC

 

추가로 배열 보내기!! 

package 입출력스트림;

import java.io.FileOutputStream;

public class Sample05 {

	public static void main(String[] args) {
 
		FileOutputStream fos = null;
		
		try {
			fos= new FileOutputStream("text.txt",true);
			
			byte[] b = new byte[26];  // 내가 보내고싶은만큼
			
			byte data = 65;
			
			for (int i = 0; i < 26; i++) {
				b[i]= data;
				data++;
			}
				fos.write(b);
		
		}	catch (Exception e) {
		
		} finally {
			try {
				fos.flush();	
				fos.close();
			} catch (Exception e2) {
			
			}
		}
	}

}

ABC에다가 ABCDE..Z까지 추가!

+추가 
fos.write( b, 0, 5); 하면 
b[0] 부터 5개 라는 뜻이므로 
ABCDE가 출력됨 !!

 

보조스트림 PrintStream 이용!!

PrintStream 모든 데이터 타입 가능! 

예시 ↓

package 입출력스트림;

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

//아웃풋

public class Sample05 {

   public static void main(String[] args) {
      
      FileOutputStream fos = null;
      PrintStream ps = null;
      
      try {
         fos = new FileOutputStream("test.txt", true);
         ps = new PrintStream(fos); //보조 스트림, 보조할 대상을 소괄호안에 넣는다.
         
         ps.println("가나다");
         ps.print(123);
         ps.println(true);
         ps.print(3.14);

               
      } catch (Exception e) {
         
      } finally {
         try {
            fos.flush(); //스트림에 남아있는 내용(찌꺼기)을 다 내보낸 후
            fos.close(); //스트림을 닫아준다.
         } catch(Exception e) {
            
         }
      }

   }

}

 

보조스트림 PrintStream 이용한 결과값

 


문자 출력 스트림 - Writer 

Outputstream과 비교

.write(int i);

.write(byte [];

.write( byte [] b, int off, int len);

그냥  Writer도  .wrrite로 가능 

.write(int i)

.write(char[] c);

.write( char[] b, int off, int len);  -> 배열의 타입이 문자로 바뀜 

.write(String str) -> 아웃풋스트림과 달리 Writer는 문자열도 가능 

.write(String str, int off, int len);

여러가지 예시들 ↓

 

package 입출력스트림;

import java.io.FileWriter;

public class Sample06 {

	public static void main(String[] args) {

		FileWriter fw = null;

		try {
			fw= new FileWriter("text2.txt");

			fw.write('A');
			char[] buf = { 'B', 'C', 'D' };
			fw.write(buf);
			fw.write(buf, 1, 2); // buf 1번방 부터 2개를 넣겠다

			String str = "가나다라";
			fw.write(str);
			fw.write(str, 2, 2); // str 2번방 부터 2개를 넣어라

		} catch (Exception e) {
		} finally {
			try {
				fw.flush();
				fw.close();
			} catch (Exception e2) {

			}
		}
	}

}

결과값


기존 내 데스크탑에 있던 애플 사진을 인풋으로  자바로 가져왔다가 다시  아웃풋으로 SRC로 내보냄 

package 속도비교;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;

public class Sample01 {

	public static void main(String[] args) throws Exception { // 예외처리 떠넘기기

		/** 인풋, 아웃푼 메인스트림 */
		FileInputStream fis = null;
		FileOutputStream fos = null;

		/** 인풋, 아웃푹 보조스트림 */
		BufferedInputStream bis = null;
		BufferedOutputStream bos = null;

		int data = 0;
		long start = 0;
		long end = 0;

		fis = new FileInputStream("src/속도비교/apple.png"); // 내보내기
		fos = new FileOutputStream("src/apple.png"); // 들여보내기

		start = System.currentTimeMillis(); // 시작 시간

		while ((data = fis.read()) != -1) { // 읽어오고
			fos.write(data); // 내보내고
		}
		fos.flush(); // 찌꺽스 처리
		end = System.currentTimeMillis();
		fos.close();
		fis.close();

		System.out.println("버퍼 사용 X : " + (end - start));

		fis = new FileInputStream("src/속도비교/apple.png");
		bis = new BufferedInputStream(fis);
		fos = new FileOutputStream("src/apple.png");
		bos = new BufferedOutputStream(fos);

		start = System.currentTimeMillis(); // 시작 시간

		while ((data = bis.read()) != -1) { // 읽어오고
			bos.write(data); // 내보내고
		}
		bos.flush(); // 찌꺽스 처리
		end = System.currentTimeMillis();
		bis.close();
		bos.close();
		fos.close();
		fis.close();

		System.out.println("버퍼 사용 O : " + (end - start));

	}

}

!=-1:-1이 아니면 true이므로 -1이 리턴되면 false 반복문 종료

 

결과값: 

버퍼 사용 X : 39
버퍼 사용 O : 0

-> 기존에 있던거 인풋으로  자바로 가져와서 아웃풋으로 SRC로 내보냄 

 

↑위의 자바 코드는 두 가지 다른 방법을 사용하여 파일 복사 속도를 비교한다.하나는 버퍼링된 입출력 스트림을 사용하고 다른 하나는 사용하지 않는다. 이 코드는 먼저 FileInputStream 및 FileOutputStream 클래스를 사용하여 파일을 복사한 다음 복사하는 데 걸리는 시간을 측정. 그런 다음 BufferedInputStream 및 BufferedOutputStream 클래스를 사용하여 프로세스를 반복하고 소요 시간을 다시 측정. 마지막에는 각 방법에 소요되는 시간을 출력.

전반적으로 이 코드는 파일을 읽고 쓸 때 성능 향상을 위해 버퍼링된 스트림을 사용하는 방법의 간단한 예.

버퍼링된 스트림은 프로그램이 디스크에 액세스해야 하는 횟수를 줄여 성능을 향상시킬 있음. 

 


기본타입 입출력 보조스트림

바이트 스트림은-> 입출력 단위가 바이트임-> 기본타입인 int, char, long, double로 하고싶을 때 

사용되는 기본타입 입출력 보조스트림

DataInputStream

DataOutputStream

 

DataInputStream dis = new DataInputStream(바이트 스트림) 

.readInt(), .readDouble() // 문자열 같은 경우는 String이 아니라 .readUTF()

DataOutputStream dos = new DataOutputStream(바이트스트림) 

.writeInt() .writeDouble String -> .writeUTF()

 

package 보조스트림;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;

public class Sample01 {

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

		FileOutputStream fos = new FileOutputStream("test3.txt");
		DataOutputStream dos = new DataOutputStream(fos);

		dos.writeUTF("가나다");
		dos.writeDouble(3.14);
		dos.writeInt(20);
		dos.writeBoolean(true);

		dos.flush();
		dos.close();
		fos.close();

		FileInputStream fis = new FileInputStream("test3.txt");
		DataInputStream dis = new DataInputStream(fis);

		System.out.println(dis.readUTF());
		System.out.println(dis.readDouble());
		System.out.println(dis.readInt());
		System.out.println(dis.readBoolean());

	}

}

결과값:

가나다
3.14
20
true

!주의! Write할때 순서와 Read 할때 순서가 같아야함

 


객체 입출력 보조 스트림 

객체는 바이트 기반스트림 사용(문자가 아니기 때문)

 

객체 출력-> 객체를 일렬로 바이트로 변경해야함. 이것을 직렬화 라고한다.

객체 입력(읽어올 때) -> 바이트 일렬로 객체를  가져와야함 : 이것을 역직렬화 라고함  

 

SimpleDateFormat이란? ->

 

ObjectInputStream

ObjectOutputStream

 

package 객체입출력;

import java.io.Serializable;
import java.util.Date;

public class Board implements Serializable {

	private int bno;
	private String title;
	private String content;
	private String writer;
	private Date date;

	public Board(int bno, String title, String content, String writer, Date date) {
		super();
		this.bno = bno;
		this.title = title;
		this.content = content;
		this.writer = writer;
		this.date = date;
	}

	public int getBno() {
		return bno;
	}

	public void setBno(int bno) {
		this.bno = bno;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getContent() {
		return content;
	}

	public void setContent(String content) {
		this.content = content;
	}

	public String getWriter() {
		return writer;
	}

	public void setWriter(String writer) {
		this.writer = writer;
	}

	public Date getDate() {
		return date;
	}

	public void setDate(Date date) {
		this.date = date;
	}

}

↑위의 보드 클래스는 메시지 보드 또는 포럼의 보드를 나타내는 단순한 Java 클래스입니다. 클래스에는 보드 번호, 제목, 내용, 작성자 및 날짜와 같은 보드에 대한 정보를 저장하기 위한 여러 필드가 있습니다. 클래스는 또한 이러한 각 필드에 대한 getter 및 setter 메서드를 가지고 있으므로 다른 클래스가 Board 개체에 저장된 정보를 읽고 수정할 수 있습니다. Board 클래스는 Serializable 인터페이스를 구현합니다. 즉, 이 클래스의 개체는 파일에 저장되거나 네트워크를 통해 전송될 수 있는 바이트 시퀀스로 변환되거나 변환될 수 있습니다. 이것은 Board 객체를 저장하고 전송하는 데 유용합니다.

 

 

package 객체입출력;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.sun.swing.internal.plaf.basic.resources.basic;

public class Sample01 {

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

		writeList();

		List<Board> list = readList();

		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

		for (Board b : list) {
			System.out.println(b.getBno() + "\t" + b.getTitle() + "\t" + b.getContent() + "\t" + b.getWriter() + "\t"
					+ sdf.format(b.getDate()));
		}
	}

	public static void writeList() throws Exception {

		List<Board> list = new ArrayList<>();

		list.add(new Board(1, "java", "객체지향", "김자바", new Date()));
		list.add(new Board(2, "c", "절차지향", "박씨", new Date()));
		list.add(new Board(3, "jsp", "서버", "최서버", new Date()));

		FileOutputStream fos = new FileOutputStream("board.db");
		ObjectOutputStream oos = new ObjectOutputStream(fos);

		oos.writeObject(list);

		oos.flush();
		oos.close();
		fos.close();
	}

	public static List<Board> readList() throws Exception {

		FileInputStream fis = new FileInputStream("board.db");
		ObjectInputStream ois = new ObjectInputStream(fis);

		List<Board> list = (List<Board>) ois.readObject();

		ois.close();
		fis.close();

		return list;
	}
}

↑ Sample01 클래스객체 직렬화를 사용(  ObjectOutputStream oos = new ObjectOutputStream(fos);)
하여 Board 객체 목록을 파일에 저장하고 파일에서 복원하는 방법을 보여주는 간단한 Java 프로그램입니다. 메인() 메서드는 먼저 writeList() 메서드를 호출하여 보드 개체 목록을 "board.db"라는 파일에 기록합니다. writeList() 메서드는 새 List of Board 개체를 만들고 목록에 세 개의 Board 개체를 추가합니다. 그런 다음 FileOutputStream과 ObjectOutputStream을 생성하여 Board 개체 목록을 파일에 기록합니다.


보드 오브젝트 목록을 파일에 쓴 후, 메인() 메서드는 readList() 메서드를 호출하여 파일에서 목록을 다시 읽습니다. readList() 메서드는 파일에서 Board 개체 목록을 읽기 위해 FileInputStream과 ObjectInputStream을 만듭니다. 그런 다음 파일에서 읽은 Board 개체 목록을 반환합니다.

마지막으로 메인() 메서드는 보드 개체 목록을 반복하여 각 보드에 대한 정보를 콘솔에 인쇄합니다. 각 보드의 정보는 bno, 제목, 내용, 작성자 및 날짜 형식으로 인쇄됩니다. SimpleDateFormat 클래스는 각 Board 개체의 날짜 필드를 원하는 형식으로 포맷하는 데 사용됩니다.

 

결과값: 

1 java 객체지향 김자바 2022-12-07
2 c 절차지향 박씨 2022-12-07
3 jsp 서버 최서버 2022-12-07

 


 


File 클래스 관련 메서드들

Directory는 파일이 아니라 폴더임! ! 

package 객체입출력;

import java.io.File;

public class Sample02 {

	public static void main(String[] args) {

		File f= new File("text.txt");
		
		
		
		
		System.out.println(f.length()+"byte");	// 파일 용량 알려줌
		
		System.out.println(f.canWrite()); 	// 쓰기권한
		
		System.out.println(f.canRead());	// 읽기 권한에 관해 알려줌 
		
		System.out.println(f.getPath());
		
		System.out.println(f.getAbsolutePath());  		// 경로 알려줌
		
		System.out.println(f.getName()); // 파일명 나오게끔 			
		
		System.out.println(f.isDirectory()); 		
		
		System.out.println(f.isFile());		//파일인지 아닌지 true or false로 리턴됨

	}

}

결과값

29byte
true
true
text.txt
C:\Users\user\eclipse-workspace\Java20221207\text.txt
text.txt
false
true


자바 문제풀어보기

TEXT.TXT에는 

AAA

BBB

CCC

DDD

EEE 가 저장되어있음

RESULT.TXT에다가

EEE

DDD

CCC

BBB

AAA

를 내보내게끔 

package 문제;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Comparator;

public class Sample01 {

	 public static void main(String[] args) throws Exception {
	      ArrayList<String> lines = new ArrayList<>();
	      
	      FileReader fr = new FileReader("test.txt");
	      BufferedReader br = new BufferedReader(fr);
	      
	      while(true){
	         String line = br.readLine();
	         if(line == null)
	            break;
	         lines.add(line);
	      }
	      
	      br.close();
	      fr.close();
	      
	      lines.sort(Comparator.reverseOrder());
	      
	      
	      PrintWriter pw = new PrintWriter("result.txt");
	      
	      for(String line : lines) {
	         pw.println(line);
	      }
	      
	      pw.close();

	      
	   }
	   
	   

	}

 

lines.sort(Comparator.reversOrder()); -> lines의 ArrayList에 저장이 되어있는 내용을 역순으로 정렬(역정렬)

.sort();는 정렬

 

완료!! 


위를 불러와서 합계랑 평균 구해보시오!!

 

package 문제;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Comparator;

public class Sample01 {

	 public static void main(String[] args) throws Exception {
	      ArrayList<String> lines = new ArrayList<>();
	      
	      FileReader fr = new FileReader("test.txt");
	      BufferedReader br = new BufferedReader(fr);
	      
	      while(true){
	         String line = br.readLine();
	         if(line == null)
	            break;
	         lines.add(line);
	      }
	      
	      br.close();
	      fr.close();
	      
	      lines.sort(Comparator.reverseOrder());
	      
	      
	      PrintWriter pw = new PrintWriter("result.txt");
	      
	      for(String line : lines) {
	         pw.println(line);
	      }
	      
	      pw.close();

	      
	   }
	   
	   

	}
728x90