반응형

 

파일 만든 것도 중요한데

jvm->가상머신 실제아니고 실제인것 처럼 동작

java는 직접적으로 handing안하고 jvm이 인수 있는 것

 

 

업데이트 ->

맨처음 있는 가 없는 가 확인해서 다운로드 한다.

다운르도 하면서 설치 파일 생긴다.

 

 

서버에 a.dat       ->업데이트 단순하게 있는가 없는 가 할때 클라이언트에 있을 때 크기를 비교한다.

                                  날짜도 비교할 수 있다.

                                 

클라이언트 a.dat

 

클라이언트 에서 수정을 안한다. 다운로드 하다가 수정하다가 다운로드 끄지면 a.dat 가 깨져서 사용할 수 없어서 서버에 a.data  임시.dat로 만든다.

클라이언트에 a.dat ->back후 생성

a.     dat 삭제하고 생선

 

window업데이트 중인데 끄면 안되는데 다운로드 할 경우 끌 수 있다.

다운로드 받을때 끄도 문제 없다.데이터 수정할 경우 끄면 안된다.

application 파일에 대한 정보가 중요하다.

업데이트 할 때 문제 가 생긴다 .

 

경로

절대 경로: root부터 불변의 경로 ->고정

상대 경로: 현재 위치에 따라서 변하게 된다 ->

 

\ 문자 : 제어문자 (프로그래밍 언어가 해석할려고 한다.)

            white space

\\

 

정규식에서는 \ -> \\\\

파일 :///

/시작할 셩우 최상위

./ ->현재 디렉토리

 

1. File 클래스

v  java.io 패키지에 존재하는 시스템에 있는 파일이나 디렉토리를 추상화한 클래스

v  File 클래스를 이용하면 파일의 크기, 생성, 삭제 작업 및 마지막 수정날짜 등 다양한 정보를 알 수 있는 메소드를 제공

v  경로

ü  절대 경로: 루트로부터의 위치

l  Windows -> 루트드라이브:\디렉토리경로\파일이름

l  Web -> 프로토콜://자원경로

l  그 이외의 경우 -> /루트디렉토리/디렉토리경로/파일이름

l  Windows 경우는 디렉토리 기호가 \ 그 이외의 경우는 /

ü  상대경로: 현재 위치로부터의 경로

l  ./: 현재 디렉토리

l  ../: 상위 디렉토리

 

Dev 개발(development) 환경 window  \

                                                         이 경우 절대 경로 면 문제 생긴다.

Ops 운영(operation) 환경    linux     /

 

dev - ops

개발환경에서 운영환경으로 바꿀때 소스를 적게 바꿔야 한다.

소스 바꾸는 것이 위험하다.

 

source- >내가 작성한 문장이지 실행은 안된다.

     compile

class

  

    buile

            load

  

    run

소스를 바꾸면 위에것 다 다시해야 한다. 그래서 문제가 생길수 도있다.

디렉토리 ->상대경로

 

app

         src

C:\\project\\JAVA_PROJECT\\java\\src\\java\\img\\"+(i%10)+".png" ->절대 경로

다른데서 사용할 없다.

그래서 상대경로를 사용한다.

 

./그림파일 집에  들고 가도  위치에 문제가 안생긴다. 소스 코드가 클 가능성이 있다.

 

절대 경로 사용할 수 있는 것은 파일이나 데이터베이스에 저장한다.  경로 바꿀 경우 여기 수정한다.

원만하면 상대경로로 써야 한다.

 

string ->예외를 발생시키는 것이 낮아진다.

path는 경로

name은 이름만 리턴한다.

isreturn 타입은 boolean이다.

 return long

mkdir ->디렉토리 만들어준다,

 

**File.클래스

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

1.생성자

FIle(String 파일경로) :파일경로를 가지고 생성

File(String parent,String child) //parntchild를 조합해서 생성

File(File parent, String child) :parentchild를 조합해서 생성

 

2.파일 경로

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

=>window는 디렉트리 기호호 \나머지 운영체제는 /

=>절대 경로는 소스 상에서 등장하지 않는 것이 좋습니다.

개발환경에서 운영환경으로 이행할 때 소스의 수정을 유발할 수 있습니다.

절대경로를 사용해야 한다면 다른 파일이나 데이터베이스에 작성해두고 불러서 사용하는 형태로 작성해야 운영환경으로 이행할 떄 소스를 수정하지 않고 사용이 가능합니다.

 

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

./: 현재 디렉토리

../: 상위 디렉토리

 

File f = new File(cwd.getAbsoluteFile()+"/src/0.png");

src ->..으로 사용불가하다 .부모로 가기 때문이다.

예전에 ..으로 애매모호한디텍토리로 가능한 것은 정규식사용 가능하기 떄문이다.

 

public class FileInfo {

       public static void main(String[] args) {

               //절대 경로를 이용해서 파일 인스턴스 생성

               //File f = new File("C:\\project\\JAVA_PROJECT\\java\\src\\java\\img\\0.png");

              

               //상대경로를 이용해서 파일 인스턴스 생성 : 파일을 프로젝트 디렉토리에 복사하고 실행

               //java/ src/

               //C:\project\JAVA_PROJECT\java  ./0.png

               File cwd = new File(".");

               System.out.println(cwd.getAbsoluteFile());

              

               File f = new File(cwd.getAbsoluteFile()+"/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.Path 클래스

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

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

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

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

 

2.Path의 문제점

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

파일과 path를 두가지 쓰야 하는 문제가 발생

 

3.Path객체 생성

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

 

 

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

Paths.get(uri)

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

 

4.Path의 메소드

File toFitle():파일  인스턴스 리턴

URI toURI();URI인스턴스 리턴

 

5.파일 작업 메소스

1)파일복사 :Files.copy

2)파일 삭제 :Files.delete

3)파일 생성:Files.createFile

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

 

6.임시 파일 만들기

=>네트워크에서 많은 양의 데이터를 다운로드 받아서 사용하는 경우 메모리에 계속 저장하면 메모리 부족 현상이 발생할 수 있습니다.

일시적으로 임시 파일에 저장한 후 전부 다운로드 받으면 그 때 임시파일의 내용을 이용

Files.createTempFile(Path path, String pre, String ext)

=>pre 는 임시파일 앞에 들어갈 문자열이고 ext는 임시파일의 확장자

public class PathUse {

       public static void main(String[] args) {

               //src디렉토리에 있는 o.png파일을 Path 객체로 생성

               Path path = Paths.get("./src/0.png");

               //복사할 파일 경로르 ㄹ생성

               Path to = Paths.get("./src/zero.png");

              

               try {

                      //path에서 to 복사

                      Files.copy(path, to);

                      Files.delete(path);

               } catch (IOException e) {

                      // TODO Auto-generated catch block

                      e.printStackTrace();

               }

       }

}

 

**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(자원 생성){자원 사용} cathch(Exception e){예외처리 내용} 으 형태로 자원을 생성하면 close를 호출하지 않아도 자동으로 반납합니다.

try - resources구문이라고 합니다.

 

 

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

public class ByteInputOutput {

       public static void main(String[] args) {

               //try()안에서 만든 자원은 close 호출하지 않아도 됩니다.

               try(

                      //파일에 기록하기 이한 인스턴스 생성  

                             //파일 경로만 설정하면 기록할 마다 새로 기록 FileOutputStream fos = new FileOutputStream("./src/java/file.dat");

                             //두번째 매개변수로  true 설정하면 존재하는 경우 이어쓰기를 합니다.

                      FileOutputStream fos = new FileOutputStream("./src/java/file.dat",true);

                      //파일에서 읽어오기 위한 인스턴스 생성

                             //뒤에 옵션이 없다.

                      FileInputStream fis = new FileInputStream("./src/java/file.dat");

                             ){

                      //기록할 내용 만들기

                      String msg= "Hello Stream 안녕";

                      //문자열을 바이트 단위로 만들기

                      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];//일반적으로 8 배수로 읽는다.

                      while(true) {

                             //split 크기만큼 읽고 읽은 개수를 리턴

                             int r = fis.read(split);

                             if(r <= 0) {

                                    break;

                             }

                             //읽은 데이터가 있으면 처리

                             //문자를 바이트로 읽어서 변환하지는 않음

                             //데이터를 사용할 배열을 바로 사용하면 안되고 0부터 읽은 개수만큼만 사용해야 합니다.

                             //전체를 사용하는 경우 읽은 개수가 부족하면 이상한 결과를 만듭니다.

                             //txt파일은 bytes 읽으면 안된다 .깨진다.

                             String str = new String(split, 0 ,r); ///한글이 깨진다.

                             System.out.println(str);

                      }

               }catch (Exception e) {

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

               }

       }

 

 

 

 

메모리 저장해놓고 하는 것이 빠르다.

 

 

우리 코드는 jvm과 밖에 지원 못한다.

os가 자기가 지언한 것을 상용하는 것을 native method

java코드가 운영체제가 관리하는 자원을 사용하는 경우

java 코드 -> jvm->운영체제의 native method 호출

 

java코드가 native method를 자주 호출하면 효율이 떨어집니다.

이런 경우는 BATCH(일괄 -모아서 처리)처리르 고려

 

 

 

자바은 모아서 처리 할 수 잇는 스트림 제공

jvm이 알아서 버퍼를 만든다.

BYTE stream =>BufferedInputStream :다른 inputstream

                       PrintStream : 다른 outputstream(print라는 메소드를 가지고 있다.)

                       system.outprintstream이다.

 

Buffer:임시기억 장치 속도 차 떄문제 존재

Double Buffering

buffer단점 메모리를 많이 사용한다.

프린트도 같은 기능이다. 복사한 내용을 buffere 저장

한장일 경우 buffer이 필요없다. 속도가 늘어진다. 상황을 판단하면서 해야 한다.

 

awtdouble buffering 안한다.

swingdouble buffering 한다.

 

체팅 과 복사 등을 여러번한다. 그래서 메모리에 연다.

통상적으로 메로리에 하는 것이 좋다.

게임은 graphic을 가속한다.

 

출력은 바로 안하고 비운다.실제르는 PRINT하는 것이 아니라고 WRITE한다.

 

os.직접 대화하는 것은 assembly  , c 이다.

cunix

unix95%c언어와 assemble로 되여있다.

 

read - > jvm-> os->native method->

 

7)Buffer이용

=>입출력 명령은 우리가 자바코드로 작성하지만 실제 동작은 운영체제의 native method를 호출해야 합니다.

너무 잦은 입출력 명령은 운영체제의 효율을 떨어뜨려서 애플맄이션의 성능을 떨어뜨릴수 있습니다.

이런 경웬느 명령을 버퍼에서 모아서 한꺼번에 처리하는 것이 효율적일 수 있습니다.

=>버퍼를 이용하는   ByteStreamBufferedInputStream,PrintStream이 있습니다.

이 스트림들은 다른 스트림을 매개변수로 해서 인스턴스를 생성하고 이전 입출력명령을 그래도 사용할 수 있고 몇개의 추가된 메소드가 존재합니다.

=>자바는 명령을 수행하는 방식이 바뀌더라도 오버라이딩을 이용해서 명령을 추가하는 구조를 이용하기 때문에호출되는 메소드 이름은 그대로 입니다.

 

 

public class BufferInputOutput {

       public static void main(String[] args) {

               try(PrintStream ps = new PrintStream(new FileOutputStream("./src/java/buf.dat"));

                             BufferedInputStream bis = new BufferedInputStream(new FileInputStream("./src/java/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)기타 스트림

=>DataiInputStream & 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();

 

int write(String str);

int 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(파일 경로));

 

=>다른 intputStream으로 부터 읽어오는 Reader생성

new BufferedReader(new InputStreamReader(InputStream 인스턴스));

키보드로 부터 읽어오는 Reader : new BufferedReader(new InputStreamReader(Systme.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("./src/java/data.txt");

                             BufferedReader br = new BufferedReader(new FileReader("./src/java/data.txt"));

                             ){

                      pw.println("안녕하세요 반갑습니다.");

                      pw.println("내일 모래면 설날입니다.");

                      pw.flush();

                     

                      //파일의 내용을 읽기

                      while(true) {

                             //한줄 일기

                             String line = br.readLine();

                             // 읽었으면 중지

                             if(line == null) {

                                    break;

                             }

                             System.out.println(line);

                      }

               }catch(Exception e) {

                      System.out.println("예외:" +e.getMessage());

               }

       }

}

 

0:0:0:0:0:0:0:1 - - [30/May/2017:16:59:23 +0900] "GET /library/ HTTP/1.1" 200 12223

get ->요청방식

HTTP/1.1

200 정상

 

 

500번대는 서버오류

12223 트래픽

 

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("./src/java/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 += 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]);

                            

                            

                             //11 line 192.168.0.2 - - [30/May/2017:17:03:02 +0900] "GET / HTTP/1.1" 404 994

                             //192.168.0.2 - - [30/May/2017:17:03:02 +0900] "GET / HTTP/1.1" 404 -

                             //가장 마지막 데이터를 정수로 변환해서 total 추가

                             //예외가 발생해서 중단되면  try ~ catch 감싸면 예외가 발생해도 계속 수행합니다.

                             try {

                                    total += Integer.parseInt(ar[ar.length-1]);

                             }catch(Exception e) {

                                   

                             }

                            

                      }

                     

                      System.out.println("트래픽 합계: "+total);

                     

                      //set  출력

                      for(String ip : set) {

                             System.out.println(ip);

                      }

                     

                     

                      //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():현재 포인터의 위치를 리턴

public class RandomFileMain {

       public static void main(String[] args) {

               try (// 파일 읽고 쓰기 객체 생성

                             RandomAccessFile f = new RandomAccessFile("./src/java/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 -객체 직렬화

=>파일 입출력의 기본 단위는 bytechar입니다.

=>실제 사용하는 데이터는 bytechar도 있지만 int와 기본형 데이터나 직접 만든 class의 인스턴스인 경우도 있습니다.

이런 데이터를 파일에 저장할려면 bytechar로 변환해서 저장해야 합니다.

읽을 때는 읽어온 데이터를 다시 원래의 자료형으로 변환해서 읽어야 합니다.

=>직접 만든 클래스의 인스턴스를 파일에 저장할 수 있도록 해주는 기능을 제공하는데 이 때 저장되어야 하는 클래스에 Serializable인터페이스를 implements해야 합니다.

 

=>ObjectInputStream ObjectOutputStream클래스를 이용해서 읽기 쓰기를 합니ㅏㄷ.

이 클래스들에서는 writeObjectreadObject라는 별도의 메소드가 제공되비낟.

 

=>이 방식으로 저장한 데이터는 저장할 때 사용한 클래스가 없다면 제대로 읽어 낼 수 가 없습니다.

응용프로그램이 만든 파일을 다른 응용프로그램이 읽으면 깨지는 현상

=

 

=>응용프로그램을 만들거나 데이터 통신을 할 때 Serializable을 고려 해봐야 합니다.

Andriod같은 경우는 화면과 화면이 데이터를 주고 받을 때 Serializable인터페이스를 구현한 데이터만 가능하도록 제한을 해둠

 

=>Serializable인터페이스는 classImplements만 하면 됩니다.

메소드를 구현할 필요가 없습니다.

 

=>몇몇 클래스로부터 상속받으면 경고가 발생하는 경우가 있는데 Seriablizavle인터페이스가 구현된 클래스로부터 상속을 받으면 SereaLVersion iD를 만들라고 경고가 발생합니다.

 

=>Wrapper(기본형 ->참조형).String , date, calendar, 자료구조 클래스(List, Set, Map)들은 SerializableIMPLEMENTS되어 있습니다.

 

=>DTO(DATA tRANSFER OBJECt -여러 개의 변수를 하나로 묶어서 표현하기 위한 클래스 Variable Class또는 Domain classs라고도 합니다.) 클래스를 만들어서 파일에 기록하고 읽어오기

DTOTable 을 설계할 때 구별이 되는 속성 (Primary key)은 정수로 만드는 것이 좋습니다.

회원정보를 만들 때 idemail등이 primary key가 될 수 있지만 데이터를 빠르게 조회하고 싶으면 정수를 하나 추가시켜서 이 항목을 primary key로 만드는 것이 좋습니다.

 

 

Unit

-      정수로 유닛번호

-      문자열로 유닛이름

-      숫자로 공경력

-      숫자로 방어력

-      숫자로 레벨

 

 

dict는 이름이 있어나

list set등은 이름이 없다.

 

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;

       }

      

       //모든 속성의 값을 하나의 문자열로 만들어서 리턴해주느 메소드

       //출력하는 메소드에 인스턴스 이름을 대입하면 메소드가 호출됩니다.

       //모든 객체 지향언어는 방식을 이용해서 출력합니다.

       //메소드 이름이 다를 뿐입니다. (python 다르다.__str__)

       @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);

              

               //byte char(String) 아닌 데이터를 읽고 때는 ObjectOutputStream.

               //ObjectInputStream 이용

              

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

                      //오류 난다.

                      //PrintStream ps = new PrintStream(new FileOutputStream("./src/java/star.dat"))

                      //pw.write(unit)

                     

                      //이렇게 저장하면 unit.toString() 결과가 저장

                      //PrintWriter pw = new PrintWriter("./src/java/star.dat");

                      //pw.print(unit);

                     

                      //데이터 기록 : unit 클래스인 Unit Serializable인터페이슬 구현하지 않았다면

                      //ClassCastException 발생 - 변환이 안된다고 예외 발생

                      oos.writeObject(unit);

               }catch(Exception e) {

                      System.out.println("예외 : " +e.getMessage());

               }

       }

}

 

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);

              

               //byte char(String) 아닌 데이터를 읽고 때는 ObjectOutputStream.

               //ObjectInputStream 이용

              

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

                             ObjectInputStream ois = new ObjectInputStream(new FileInputStream("./src/java/star.dat"));){

                      //오류 난다.

                      //PrintStream ps = new PrintStream(new FileOutputStream("./src/java/star.dat"))

                      //pw.write(unit)

                     

                      //이렇게 저장하면 unit.toString() 결과가 저장

                      //PrintWriter pw = new PrintWriter("./src/java/star.dat");

                      //pw.print(unit);

                     

                      //데이터 기록 : unit 클래스인 Unit Serializable인터페이슬 구현하지 않았다면

                      //ClassCastException 발생 - 변환이 안된다고 예외 발생

                     

                      //여러번 있을 경우 os에도 안좋고 작성하기도 번거럽다.

                      /*oos.writeObject(unit);

                     

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

                      System.out.println(unit1);

                      oos.writeObject(unit1);

                     

                      System.out.println("================");

                      //데이터 읽어오기 serializable 데이터

                      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:FFFFF:FFFF:FFFF:FFFF:FFFF

=>IP주소는 국가 별로 할당

=>자신의 IP: 127.0.0.1 또는 0000:0000:0000:0000:0000:0000:0000:0000

 

 

=>사설 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:특정 자원에 대한 고유한 이름

UIRURL보다 큰 개념

 

반응형

'Study > Java' 카테고리의 다른 글

java-16  (0) 2020.10.10
java-15  (1) 2020.10.05
java-13  (0) 2020.10.03
java-12  (0) 2020.10.02
java-11  (0) 2020.10.01

+ Recent posts