즐겁게!! 자신있게!! 살아보세!!

재밌는 인생을 위하여! 영촤!

Language_Study/JAVA

[JAVA, App] 18.Stream

Godwony 2020. 12. 27. 12:13
728x90
반응형

File 클래스

  • 파일을 생성하고 삭제 그리고 파일에 대한 정보를 리턴하는 클래스

 

1.생성자

  • File(String 파일경로): 파일경로를 가지고 생성
  • File(String parent, String child): parent 와 child를 조합해서 생성
  • File(File parent, String child): parent 와 child를 조합해서 생성

 

2.파일 경로

1) 절대 경로 : 루트로부터의 경로

  • windows는 디렉토리 기호로 \ 나머지 운영체제는 /
  • 절대경로는 소스 상에서 등장하지 않는 것이 좋습니다.
    • 개발환경에서 운영환경으로 이행할 때 소스의 수정을 유발할 수 있습니다.
    • 절대경로를 사용해야 한다면 다른 파일이나 데이터베이스에 작성해두고 불러서 사용하는 형태로 작성해야 운영환경으로 이행할 때 소스를 수정하지 않고 사용이 가능합니다.

2) 상대 경로 : 현재 디렉토리부터에서의 경로

  • ./: 현재 디렉토리
  • ../: 상위 디렉토리

3.파일 정보 확인

    public static void main(String[] args) {
        //절대 경로를 이용해서 파일 인스턴스 생성
        //File f = new File("C:\\Users\\admin\\Documents\\0.png");

        //상대 경로를 이용해서 파일 인스턴스 생성 : 파일을 프로젝트 디렉토리에 복사하고 실행
        File f = new File("./src/0.png");
        //파일의 존재 여부 확인 - 서버 & 클라이언트 환경에서 클라이언트에 파일 존재여부를 확인해서 다운로드
        boolean isExists = f.exists();
        System.out.println("존재여부:" + isExists);
        //파일의 마지막 수정 시간 확인 - 업데이트할 때 이 시간이 서로 다르면 다운로드
        long modify = f.lastModified();
        System.out.println("마지막 수정시간:" + modify);

        //수정시간을 우리가 사용하는 시간으로 변경
        Date date = new Date(modify);
        System.out.println("마지막 수정시간:" + date);

        //파일의 크기 확인 - 업데이트할 때도 사용할 수 있고 다운로드 여부를 판정하는데도 이용
        //파일의 크기를 알려줘서 다운로드 여부를 판단하도록 하는 경우가 있습니다.
        long size = f.length();
        System.out.println("파일크기:" + size);
    }

java.nio.file.Path 클래스

  • 기존 File 클래스의 문제점을 해결하기 위해서 등장한 클래스

1.기존 File 클래스의 문제점

1) 파일의 메타 데이터(데이터를 위한 데이터 - 데이터 자체에 대한 정보)와 심볼릭 링크(윈도우즈의 바로가기와 유사한 개념)를 취급할 수 없는 제약

2) 디렉토리 안에서 파일이 생성되고 수정되고 삭제되는 것을 감시하지 못함

2.Path의 문제점

  • 이전에 만들어진 API 들이 File 클래스를 많이 이용

3.Path 객체 생성

1) Paths.get(String 파일경로)

2) URI uri = URI.create(file://파일경로);
Paths.get(uri);

  • URI 클래스를 이용하면 네트워크 상에 있는 파일도 생성할 수 있음

4.Path의 메소드

  • File toFile(): 파일 인스턴스 리턴
  • URI toURI(): URI 인스턴스 리턴

5.파일 작업 메소드

1) 파일 복사: Files.copy

2) 파일 삭제: Files.delete

3) 파일 생성: Files.createFile

4) 디렉토리 생성: Files.createDirectory

public static void main(String[] args) {
        //src 디렉토리에 있는 0.png 파일을 Path 객체로 생성
        Path path = Paths.get("./src/0.png");
        //복사할 파일 경로를 생성
        Path to = Paths.get("./src/zero.png");

        try {
            //path에서 to로 복사
            Files.copy(path, to);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

6.임시 파일 만들기

  • 네트워크에서 많은 양의 데이터를 다운로드 받아서 사용하는 경우 메모리에 계속저장하면 메모리 부족 현상이 발생할 수 있습니다.
    • 일시적으로 임시 파일에 저장한 후 전부 다운로드 받으면 그 때 임시파일의 내용을 이용
    • Files.createTempFile(Path path, String pre, String ext)
  • pre는 임시파일 앞에 들어갈 문자열이고 ext는 임시파일의 확장자

Stream

  • 입출력을 처리하는 중간 매개체, 데이터를 운반하는 통로
  • 파일이나 네트워크 또는 입출력 장치 들과 통신을 하기 위해서는 스트림이 필요1.스트림 분류1) 방향에 따른 분류
  • 입력 스트림 과 출력 스트림

2) 전송되는 데이터에 따른 분류

  • byte 스트림(일반 파일)과 문자 스트림(텍스트 파일 - 텍스트 단위 전송)
  • 문자 스트림 대신에 byte 스트림을 사용하는 것은 가능
    • 반대는 안됨

2.ByteStream

1) InputStream

  • 바이트 단위로 읽어올 때 사용하는 스트림들의 최상위 클래스로 추상 클래스
  • 공통으로 사용할 메소드들을 선언만 해놓은 클래스
    • int available(): 읽을 수 있는 바이트 수를 리턴
    • void close(): 연결을 해제하는 메소드
    • int read(): 한 바이트를 읽어서 리턴, 읽은 데이터가 없으면 -1을 리턴
    • int read(byte []): byte 배열만큼 읽어서 매개변수로 대입된 byte 배열에 저장하고 읽은 바이트수를 리턴
    • 읽은 데이터가 없으면 -1을 리턴
  • int read(byte [], int start, int len): start 부터 len 만큼 읽어서 byte 배열에 저장하고 읽은 바이트 수를 리턴
    • 읽은 데이터가 없으면 -1을 리턴

2) OutputStream

  • 바이트 단위로 출력하기 위한 스트림의 최상이 클래스로서 추상 클래스
  • void close(): 연결 해제
  • void write(int n): n을 기록
  • void write(byte [] b): 바이트 배열의 내용 기록
  • void write(byte [] b, int start, int len): 바이트 배열에서 start 부터 len 만큼 기록
  • void flush(): 버퍼의 내용을 전부 기록
  • 기록을 할 때는 출력 대상에게 바로 기록하는 것이 아니고 버퍼에 기록한 후 버퍼가 차면 기록을 합니다.
    • 마지막에 버퍼의 내용이 남아있는데 기록이 안되는 현상이 발생할 수 있습니다.
    • 기록을 한 후 flush()를 호출하게 되면 남아있는 내용을 모두 기록하게 됩니다.

3) FileInputStream

  • 파일에서 바이트 단위로 읽어오는 클래스
  • FileInputStream(String path)
  • FileInputStream(File path)

4) FileOutputStream

  • 파일에 바이트 단위로 기록하는 클래스
  • FileOutputStream(String path): 파일이 존재하면 지우고 생성, 없으면 바로 생성
  • FileOutputStream(String path, boolean append): 없으면 생성하고 있으면 이어쓰기
  • FileOutputStream(File path)
  • FileOutputStream(File path, boolean append)

5) close

  • File 이나 Network 자원은 Java의 자원이 아니고 운영체제의 자원입니다.
    • 이러한 외부 자원을 사용할 때는 사용이 끝나면 자원을 반납해야 합니다.
    • 자원이 사용이 끝나고 자원을 반납하지 않으면 운영체제는 그만큼의 자원을 사용할 수 없는 상태가 됩니다.
    • 반드시 close를 호출해 주어야 합니다.
    • 1.7 버전 부터는 try(자원 생성) { 자원 사용} catch(Exception e){예외처리 내용} 의 형태로 자원을 생성하면 close를 호출하지 않아도 자동으로 반납합니다.
    • try - resources 구문이라고 합니다.

6) 문자열을 바이트 단위로 파일에 기록하고 읽어오기

    public static void main(String[] args) {
        //try() 안에서 만든 자원은 close를 호출하지 않아도 됩니다.
        try(
                //파일에 기록하기 위한 인스턴스 생성
                //파일 경로만 설정하면 기록할 때 마다 새로 기록
                //두번째 매개변수로 true를 설정하면 존재하는 경우 이어쓰기를 합니다.
                FileOutputStream fos = new FileOutputStream("./file.dat", true);
                //파일에서 읽어오기 위한 인스턴스 생성
                FileInputStream fis = new FileInputStream("./file.dat");
        ){
            //기록할 내용 만들기
            String msg = "안녕하세요 반갑습니다.";
            //문자열을 바이트 배열로 만들기
            byte [] b = msg.getBytes();
            //기록
            fos.write(b);
            fos.flush();

            /*
            //한번에 읽기
            //읽을 데이터 개수를 가져오기
            int len = fis.available();
            //읽은 데이터를 저장할 배열을 생성
            b = new byte[len];
            //데이터 읽기
            fis.read(b);
            //바이트 배열을 문자열로 변환
            String data = new String(b);
            System.out.println(data);
            */

            //용량이 큰 경우 한번에 읽으면 메모리 부족으로 예외가 생기거나 시간이 오래 걸릴 수 있습니다.
            //나누어서 읽는 것이 효율적

            //저장할 배열을 생성 - 크기는 8의 배수로 생성하는 것이 일반적
            byte [] split = new byte[8];
            while(true) {
                //split 크기만큼 읽고 읽은 개수를 리턴
                int r = fis.read(split);
                //r이 0보다 작거나 같으면 읽은게 없음
                if(r <= 0) {
                    break;
                }
                //읽은 데이터가 있으면 처리
                //문자를 바이트로 읽어서 변환하지는 않음
                //데이터를 사용할 때 배열을 바로 사용하면 안되고 0부터 읽은 개수만큼만 사용해야 합니다.
                //전체를 사용하는 경우 읽은 개수가 부족하면 이상한 결과를 만듭니다.
                String str = new String(split, 0, r);
                System.out.println(str);
            }

        }catch(Exception e) {
            System.out.println("예외내용:" + e.getMessage());
        }

    }

7) Buffer 이용

  • 입출력 명령은 우리가 자바코드로 작성하지만 실제 동작은 운영체제의 native method를 호출해야 합니다.
    • 너무 잦은 입출력 명령은 운영체제의 효율을 떨어뜨려서 애플리케이션의 성능을 떨어뜨릴수 있습니다.
    • 이런 경우에는 명령을 버퍼에서 모아서 한꺼번에 처리하는 것이 효율적일 수 있습니다.
  • 버퍼를 이용하는 ByteStream은 BufferedInputStream, PrintStream이 있습니다.
    • 이 스트림들은 다른 스트림을 매개변수로 해서 인스턴스를 생성하고 이전 입출력명령을 그대로 사용할 수 있고 몇 개의 추가된 메소드가 존재합니다.
  • 자바는 명령을 수행하는 방식이 바뀌더라도 오버라이딩을 이용해서 명령을 추가하는 구조를 이용하기 때문에 호출되는 메소드 이름은 그대로 입니다.
public class BufferInputOutput {

    public static void main(String[] args) {
        try(PrintStream ps = new PrintStream(new FileOutputStream("./buf.dat"));
                BufferedInputStream bis = 
                        new BufferedInputStream(
                                new FileInputStream("./buf.dat"));
        ){
            //기록하기
            ps.println("Hello Buffered Stream");
            ps.flush();

            //읽기
            //읽을 데이터 크기 가져오기
            int len = bis.available();
            //읽은 데이터를 저장할 배열 생성
            byte [] b = new byte[len];
            //데이터 읽기
            bis.read(b);
            //읽은 데이터를 문자열로 변환해서 출력
            System.out.println(new String(b));

        }catch(Exception e) {
            System.out.println("예외:" + e.getMessage());
        }

    }

}

8) 기타 스트림

  • DataInputStream & DataOutputStream
    • 기본형(int, double, boolean 등)의 데이터를 읽고 쓸 수 있는 메소드를 제공하는 클래스
  • Sequence Stream
    • 여러 개의 스트림을 합쳐서 읽을 수 있도록 해주는 스트림

2.문자 스트림 - Chracter Stream

  • 문자 단위로 데이터를 주고받는 스트림
    1) Reader
  • 문자 입력 스트림의 최상위 클래스로 추상 클래스
void close()

int read()
int read(char [] buf)
int read(char [] buf, int start, int len)

2) Writer

  • 문자 출력 스트림의 최상위 클래스로 추상 클래스
void close()

void write(String str)
void write(String str, int start, int len)
void flush()

3) FileReader

  • 파일에서 문자 단위로 읽어 오기 위한 스트림
  • 생성자
FileReader(String filepath)
FileReader(File file)

4) FileWriter

  • 파일에 문자 단위로 기록하기 위한 스트림
  • 생성자
FileWriter(String filepath)
FileWriter(File file)
FileWriter(String filepath, boolean append): 추가 모드 설정 가능
FileWriter(File file, boolean append): 추가 모드 설정 가능

5) BufferedReader

  • 버퍼를 이용해서 문자 단위로 읽어 올 수 있는 스트림
  • 생성자
    BufferedReader(Reader in)
  • 파일에서 읽어오는 Reader 생성
    new BufferedReader(new FileReader(파일 경로));
  • 다른 InputStream 으로부터 읽어오는 Reader 생성
    new BufferedReader(new InputStreamReader(InputStream 인스턴스));
  • 키보드로부터 읽어오는 Reader : new BufferedReader(new InputStreamReader(System.in));
  • 소켓에서 읽어올 때는 Socket.getInputStream()System.in 대신에 대입합니다.
  • 읽어오는 메소드로 readLine()을 제공
    • 줄 단위로 읽어서 String으로 리턴하는 메소드
  • 네트워크 상에서 문자열을 주고받을 때나 텍스트 파일을 읽을 때 이 스트림을 이용

6) PrintWriter

  • 문자 단위로 버퍼를 이용해서 출력하는 클래스
PrintWriter(String 파일경로)
PrintWriter(File file)
PrintWriter(OutputStream outputStream)
PrintWriter(Writer writer)
  • 출력을 할 때 print 메소드를 사용하는 것이 가능

7) 문자 단위로 파일에 기록하고 읽기

public class CharacterStream {

    public static void main(String[] args) {
        try(
                //파일에 문자 단위로 기록하기 위한 스트림
                PrintWriter pw = new PrintWriter("./data.txt");
                BufferedReader br = new BufferedReader(
                        new FileReader("./data.txt"));
                ){

            pw.println("안녕하세요 반갑습니다.");
            pw.println("내일 모레면 설날입니다.");

            //파일의 내용 읽기
            while(true) {
                //한 줄 읽기
                String line = br.readLine();
                //다 읽었으면 중지
                if(line == null) {
                    break;
                }
                System.out.println(line);
            }

        }catch(Exception e) {
            System.out.println("예외:" + e.getMessage());
        }    
    }

}

8) log.txt 파일을 읽어서 기술 통계값 구하기

  • 하나의 문자열을 특정 문자로 분리하는 메소드: String [] split(String 구분자)
  • 문자열을 정수로 변환하는 메소드 Integer.parseInt(String 문자열)
  • 텍스트 파일에 변환이 안되는 문자열을 포함시켰을 가능성이 있기 때문에 예외처리를 해야 합니다.

public class LogRead {

    public static void main(String[] args) {
        try(BufferedReader br = new BufferedReader(new FileReader("./log.txt"));){

            //파일의 내용을 줄단위로 읽기            
            //트래픽의 합계를 저장할 변수
            int total = 0;
            //접속한 IP 주소를 중복없이 출력
            HashSet<String> set = new HashSet<String>();
            //접속한 IP 별 트래픽 합계
            //Map에서 없는 Key를 사용하면 null이 리턴
            HashMap<String, Integer> map = new HashMap<String, Integer>();

            while(true) {
                String line = br.readLine();
                if(line == null) {
                    break;
                }
                //System.out.println(line);
                //공백을 기준으로 분할
                String [] ar = line.split(" ");

                //ip를 가지고 데이터가 있는지 확인
                Integer traffic = map.get(ar[0]);
                //없는 데이터면 traffic 은 0
                if(traffic == null) {
                    traffic = 0;
                }
                try {
                    traffic = traffic + Integer.parseInt(ar[ar.length-1]);
                }catch(Exception e) {}
                //map 에 저장 :  동일한 key 저장을 하면 업데이트
                map.put(ar[0], traffic);

                //가장 마지막 데이터 출력
                //System.out.println(ar[ar.length-1]);

                //Set에 첫번째 항목을 저장 - 중복된 데이터는 저장하지 않음
                set.add(ar[0]);

                //가장 마지막 데이터를 정수로 변환해서 total에 추가
                //예외가 발생해서 중단되면 try ~ catch로 감싸면 예외가 발생해도 계속 수행합니다.
                try {
                    total = total + Integer.parseInt(ar[ar.length-1]);
                }catch(Exception e) {}
            }

            System.out.println("트래픽 합계:" + total);
            System.out.println("====================");
            //Set 출력
            for(String ip : set) {
                System.out.println(ip);
            }
            System.out.println("====================");

            //Map 의 Key 와 Value를 전부 출력하기
            Set<String> keys = map.keySet();
            for(String key : keys) {
                System.out.println(key + ":" + map.get(key));
            }

        }catch(Exception e) {
            System.out.println("예외:" + e.getMessage());
        }

    }

}

3.RandomAccessFile

  • 일반적인 스트림을 이용하면 파일을 한 방향으로만 읽고 쓸 수 있습니다.
  • 한 번 읽은 데이터는 스트림을 다시 생성하지 않으면 다시 읽거나 쓸 수 없습니다.
  • 읽고 쓰기가 모두 가능하고 한 번 읽었던 데이터도 다시 읽을 수 있도록 만들어주는 파일 입출력 클래스

1) 생성자
RandomAccessFile(String file, String mode)
RandomAccessFile(File file, String mode)

  • 모드는 r(읽기 전용), rw(읽고 쓰기 가능), rws(쓰기 한 데이터가 바로 반영되고 파일 정보도 바로 갱신), rwd(쓰기 한 데이터가 바로 반영되지만 파일 정보를 나중에 갱신)

2) 메소드

  • void seek(long pos): 파일 포인터(읽고 쓰기 위한 위치)를 pos 위치로 옮겨주는 메소드
  • void write(byte [] b): b 의 내용을 파일 포인터 위치에 기록
  • int read(byte [] b): 파일 포인터 위치에서 b 배열의 크기만큼 읽어서 b에 저장하고 읽은 개수를 리턴
  • long getFilePointer(): 현재 파일 포인터의 위치를 리턴
  • long length(): 파일의 크기를 리턴

3) 앞에서 5바이트를 2번 읽기

public class RandomFileMain {

    public static void main(String[] args) {
        try(
                //파일 읽고 쓰기 객체 생성
                RandomAccessFile f = new RandomAccessFile("./random.txt", "rw");
                ){

            //기록할 내용 생성
            String msg = "Hello Random Access File";
            //문자열을 바이트 배열로 변환해서 기록
            f.write(msg.getBytes());

            //데이터 읽기
            //파일 포인터를 읽을 위치로 이동
            f.seek(0);
            //5개 읽기
            byte [] b = new byte[5];
            f.read(b);
            //바이트 배열을 문자열로 변환해서 출력
            System.out.println(new String(b));

            //파일 포인터를 시작위치로 다시 옮겨서 다시 읽어 냄
            f.seek(0);
            //5개 읽기
            b = new byte[5];
            f.read(b);
            //바이트 배열을 문자열로 변환해서 출력
            System.out.println(new String(b));

        }catch(Exception e) {
            System.out.println("예외:" + e.getMessage());
        }

    }

}

4.Serializable - 객체 직렬화

  • 파일 입출력의 기본 단위는 byte 나 char 입니다.
  • 실제 사용하는 데이터는 byte 나 char 도 있지만 int 와 기본형 데이터나 직접 만든 class의 인스턴스인 경우도 있습니다.
    • 이런 데이터를 파일에 저장할려면 byte 나 char로 변환해서 저장해야 합니다.
    • 읽을 때는 읽어온 데이터를 다시 원래의 자료형으로 변환해서 읽어야 합니다.
  • 직접 만든 클래스의 인스턴스를 파일에 저장할 수 있도록 해주는 기능을 제공하는데 이 때 저장되어야 하는 클래스에 Serializable 인터페이스를 implements 해야 합니다.
  • ObjectInputStream 과 ObjectOutputStream 클래스을 이용해서 읽고 쓰기를 합니다.
    • 이 클래스들에서는 writeObject 와 readObject 라는 별도의 메소드가 제공됩니다.
  • 이 방식으로 저장한 데이터는 저장할 때 사용한 클래스가 없다면 제대로 읽어 낼 수 가 없습니다.
    • 응용프로그램이 만든 파일을 다른 응용프로그램이 읽으면 깨지는 현상
  • 응용프로그램을 만들거나 데이터 통신을 할 때 Serializable을 고려해봐야 합니다.
    • Android 같은 경우는 화면과 화면이 데이터를 주고 받을 때 Serializable 인터페이스를 구현한 데이터만 가능하도록 제한을 해둠
  • Serializable 인터페이스는 Class에 implements만 하면 됩니다.
    • 메소드를 구현할 필요가 없습니다.
  • 몇몇 클래스로부터 상속받으면 경고가 발생하는 경우가 있는데 Serializable 인터페이스가 구현된 클래스로부터 상속을 받으면 SerealVersion ID를 만들라고 경고가 발생합니다.
  • Wrapper(기본형 -> 참조형), String, Date, Calendar, 자료구조 클래스(List, Set, Map)들은 Serializable이 implements 되어 있습니다.
  • DTO(Data Transfer Object - 여러 개의 변수를 하나로 묶어서 표현하기 위한 클래스로 Variable Class 또는 Domain Class 라고도 합니다.) 클래스를 만들어서 파일에 기록하고 읽어오기
    • DTO 나 Table 을 설계할 때 구별이 되는 속성(Primary key)은 정수로 만드는것이 좋습니다.
    • 회원정보를 만들 때 id 나 email 등이 primary key 가 될 수 있지만 데이터를 빠르게 조회하고 싶으면 정수를 하나 추가시켜서 이 항목을 primary key로 만드는 것이 좋습니다.
Unit
 - 정수로 유닛번호
 - 문자열로 유닛이름
 - 숫자로 공격력
 - 숫자로 방어력
 - 숫자로 레벨
public class Unit implements Serializable{
    private static final long serialVersionUID = 1L;

    private int num;
    private String name;
    private int offence;
    private int deffence;
    private int level;

    //매개변수가 없는 생성자 - 기본 데이터가 제공되지 않을 때 사용
    public Unit() {
        super();
    }

    //모든 속성을 매개변수로 받아서 생성해주는 생성자
    //기본 데이터가 제공될 때 사용 - 테스트 할 때 좋음
    public Unit(int num, String name, int offence, int deffence, int level) {
        super();
        this.num = num;
        this.name = name;
        this.offence = offence;
        this.deffence = deffence;
        this.level = level;
    }

    //접근자 메소드
    public int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getOffence() {
        return offence;
    }

    public void setOffence(int offence) {
        this.offence = offence;
    }

    public int getDeffence() {
        return deffence;
    }

    public void setDeffence(int deffence) {
        this.deffence = deffence;
    }

    public int getLevel() {
        return level;
    }

    public void setLevel(int level) {
        //레벨이 변경될 때 offence 값이 자동으로 다시 계산됨
        this.level = level;
        offence = offence + level * 10;
    }

    //모든 속성의 값을 하나의 문자열로 만들어서 리턴해주는 메소드
    //출력하는 메소드에 인스턴스 이름을 대입하면 이 메소드가 호출됩니다.
    //모든 객체 지향언어는 이 방식을 이용해서 출력합니다.
    //메소드 이름이 다를 뿐입니다.
    @Override
    public String toString() {
        return "Unit [num=" + num + ", name=" + name + ", offence=" + offence + ", deffence=" + deffence + ", level="
                + level + "]";
    }    
}
  • main
public class SerializableMain {
    public static void main(String [] args) {
        Unit unit = new Unit(1, "탱크", 10, 10, 0);
        System.out.println(unit);
        unit.setLevel(1);
        System.out.println(unit);
        System.out.println("==================================");

        //byte 나 char(String)이 아닌 데이터를 읽고 쓸 때는 ObjectOutputStream,
        //ObjectInputStream 을 이용

        try(ObjectOutputStream oos = 
                new ObjectOutputStream(
                    new FileOutputStream("./star.dat"));

            ObjectInputStream ois = 
                new ObjectInputStream(
                    new FileInputStream("./star.dat"));){
            //데이터 기록 : unit 의 클래스인 Unit 이 Serializable 인터페이스를 구현하지 않았다면
            //ClassCastException이 발생 - 형 변환이 안된다고 예외 발생
            /*
            oos.writeObject(unit);

            Unit unit1 = new Unit(2, "마린", 5, 5, 0);
            oos.writeObject(unit1);

            //데이터 읽어오기
            Unit unit2 = (Unit)ois.readObject();
            System.out.println(unit2);
            Unit unit3 = (Unit)ois.readObject();
            System.out.println(unit3);
            */

            Unit unit1 = new Unit(2, "마린", 5, 5, 0);
            ArrayList<Unit> list = new ArrayList<Unit>();
            list.add(unit);
            list.add(unit1);
            oos.writeObject(list);

            //List로 저장한 데이터 읽어오기
            ArrayList<Unit> read = (ArrayList<Unit>)ois.readObject();
            for(Unit u : read) {
                System.out.println(u);
            }

        }catch(Exception e) {
            System.out.println("예외:" + e.getMessage());
        }
    }
}

5.AutoClosable

  • try() 안에서 생성한 자원을 자동으로 해제할 수 있도록 해주는 인터페이스
    AutoClosable 인터페이스가 구현된 클래스는 try() 안에서 생성하면 close()를 호출할 필요가 없습니다.

네트워크

1.용어

1) Protocol: 통신을 하기 위한 규칙, 규약, 약속

  • 통신을 하고자 할 때는 Protocol이 같아야만 통신이 가능

2) IP Address(IP 주소): 하나의 단말기(기계)를 구분하기 위한 주소 체계

  • IPv4: 32비트 주소 - 0
    255.0
    255.0
    255.0
    255
  • IPv6:128비트 주소 - 4비트씩 묶어서 16진수 그리고 다시 4개씩 묶어서 : 으로 구문
    0000:0000:0000:0000:0000:0000:0000:0000
    FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF
  • IP 주소는 국가 별로 할당
  • 자신의 IP: 127.0.0.1 또는 0000:0000:0000:0000:0000:0000:0000:0001
  • 사설 IP: 10.x.x.x, 192.168.x.x, 172.16.x.x~172.31.x.x

3) port: 하나의 단말기에서 서비스를 구분하기 위한 번호
0-65535

  • 서비스가 애플리케이션

4) 통신을 할 때는 IP 주소 와 Port 번호가 같이 필요

5) 0-1023 번까지의 포트번호는 예약
1521: 오라클
3306: mysql
27017: mongodb
tomcat: 8080

6) domain: IP 주소를 문자열로 변경한 것

  • 사람이 알아보기 쉽게 하기 위해서 만든것

7) URL: 인터넷 상의 자원의 위치

8) URI: 특정 자원에 대한 고유한 이름

  • URI가 URL보다 큰 개념
728x90
반응형

'Language_Study > JAVA' 카테고리의 다른 글

[JAVA, App] 20.Parsing  (0) 2020.12.28
[JAVA, App] 19.통신  (0) 2020.12.27
[JAVA, App] 17.자바GUI  (0) 2020.12.27
[JAVA, App] 16.이벤트처리  (0) 2020.12.27
[JAVA, App] 15.MutualExclusion  (0) 2020.12.27