반응형

 

파일 만든 것도 중요한데

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
반응형

**Event처리

=>Event는 외부에서 발생하는 사건

=>자바의 awtswing의 이벤트 처리는 Listener인터페이스나 Adapter클래스가 처리합니다.

1.이벤트 처리 방법

=>처리하고자 하는 이번트의 Listener인터페이스를 Implements하거나 Adapter클래스를 상속받은 클래스의 인스턴스를 생성

=>컴포넌트.add이벤트리스너(앞에서 생성한 인스턴스);

 

=>이러한 방식의 처리를 Delegate(위임)를 이용한 처리 방식

이벤트가 발생한 객체가 이벤트를 처리하는 것이 아니고 이벤트가 발생한 객체가 다른 객체에게 이벤트 처리를 위임하는 방식

컴포넌트는 출력에만 집중하고 다른 작업은 별도의 객체가 처리하는 것이 유지보수에 유리

 

=>이벤트 처리하는 메소드를 확인

이 메소드의 매개변수를 이용하면 이벤트가 발생한 객체에 대한 정보를 가져올 수 있습니다.

자바에서는 getSource()를 호출하면 이벤트가 발생한 객체에 대한 참조를 리턴받을 수 있습니다.

가지고 있는 메소드들이 이벤트별로 다른데 이 메소드들이 이벤트에서 사용할 정보를 리턴해줍니다.

키보드 이벤트가 어떤 이벤트 인지

 

2.이벤트 처리 실습

=>버튼을 누르거나 메뉴를 누르는 경우 또는 TextField에서 Return키를 누르는 경우를 처리할 때는 ActionListener를 이용해서 처리

=>버튼과 텍스트 필드를 만들고 버튼을 누르면 텍스트 필드에 입력된 내용을 콘솔에 출력

 

1) Anonymous클래스를 이용하는 방법

디자인 처리랑 이벤트 처리가 같이 되여있다.

책은 같이 사용하는 것으로 되여있다.

책과 실제로 일하는 것은 다르다.

실제 연습할 때는 분할 해서 해야 한다.

=>실습

public class MyWindow extends Frame {

       private Button btn;

       private TextField tf;

      

       public MyWindow() {

               //여러개의 컴포넌트를 묶어줄 container생성

               //안드로이드에서는 layout이다.

               Panel p  = new Panel();

              

               //컴포넌트들을 생성

               btn = new Button("click");

               tf = new TextField(30);

              

               //버튼의 이벤트 처리를 위한 ActionListener인터페이스의 anonymous clss생성

               //자바에서는 listener 대부분 인터페이스이다.

               ActionListener listener = new ActionListener() {

                      //버튼을 누르거나 텍스트 필드에서 Return누르거나 메뉴를 누르면 호출되는 메소드

                      @Override

                      public void actionPerformed(ActionEvent e) {

                             //입력한 내용 가져옥

                             String msg = tf.getText();

                             //출력

                             System.out.println(msg);

                      }

               };

               //btn에서 Action이벤트가 발생하면 listener 대신 처리하도록 위임(Delegation)

               //btn.addActionListener(listener);

              

               //컴포넌트들을 컨테이너에 배치

               p.add(tf);

               p.add(btn);

              

               //컨테이너를 윈도우에 배치

               add(p);

              

               //Frame 기본 설정

               setTitle("이벤트 처리");

               setLocation(100, 100);

               setSize(300, 400);

               setVisible(true);

       }

 

}

 

 

2) .별도의 이벤트 처리 클래스를 생성해서 이벤트를 처리

이벤트 처리하는 것은 handler가 있다.

나중에 연결만해주면 된다.

하지만 생성자를 생성하는 것을 알아야 한다.

작업을 나누어서 하는 것이 편하다ㅏ.

ActionListener인터페이스를 impelements한 클래스를 생성 - EventHandler

public class EventHandler implements ActionListener {

       private TextField tf;

      

       //생성자 -TextField 1개를 주입받는 생성자

       public EventHandler(TextField tf) {

               this.tf = tf;

       }

 

       @Override

       public void actionPerformed(ActionEvent e) {

               String msg = tf.getText();//오류가 난다. TextFiled 업다.

               System.out.println(msg);

       }

 

}

 

=>MyWindow클래스의 생성자에서 이벤트 연결

               //이벤트 처리를 위한 인스턴스를 생성

               //다른데에서 사용하고 싶을 생성자를 해서 넣어주면 사용 가능하다.

               EventHandler handler = new EventHandler(tf);

               btn.addActionListener(handler);

 

 

 

3.인터페이스를 이용하는 방법

1)인터페이스를 구현한 클래스를 만들고 인스턴스를 만드는 방법

=>유지보수를 위해서는 이 방식을 권장

=>생성자나 Setter메소드를 이용해서 데이터를 넘겨야 하는 어려움이 있음

 

2)인터페이스를 가지고 Anonymous Class를 만드는 방법

=>일반적인 자바(안드로이드)책에서 많이 사용하는 방법

=>이 방법은 컴포넌트가 구현된 클래스에 만들기 때문에 클래스의 변수 사용이 자유로워서 많이 이용

 

3)특수한 인터페이스의 경우는 람다를 이요하는 방법

=>Android Studio는 이 방식으로 최적화

 

4.Event Routing

=>여러 개의 이벤트를 하나의 인스턴스가 처리하도록 하는 방법

=>1개의 이벤트를 1개의 인스턴스가 처리하도록 하면 여러 개의 이벤트를 처리 할때 인스턴스의 개수가 늘어나고 제어하기가 어려워집니다.

=>이 때는 이벤트 처리 메소드에서 이벤트가 발생한 인스턴스를 구분해서 분기를 해야 합니다.

awtswing에서는 이벤트 처리 메소드의 매개변수가 getSource()를 호출하면 이벤트가 발생한 객체의 참조를 리턴하기 때문에 이를 이용해서 구분할 수 있고 ActionEvent의 경우는 getActionCommand()를 호출하면 문자열을 리턴해주는데 이 문자열이 버튼의 텍스트입니다.

getSource()를 사용하는 경우는 배열이나 List인 경우

배열이나 List는 반복문을 사용할 수 있다.

 

Button [] btn = new Button[3];

for(int i = 0; i<3, i++){

System.out.println("버튼" +"i")

}

버튼을 3개 만들 때

Button btn1, btn2, btn3;

btn1 = new Button("버튼1");

btn2 = new Button("버튼2");

btn3 = new Button("버튼3");

 

배열이나 리스트 이용하면 비교하기도 편하고

관리하기도 편하다.

=>이전 Frame에 버튼을 2개 추가해서 이벤트 라우팅 구현-MyWindow클래스에서 작업

1)인스턴스 변수로 버튼을 2개 추가

       private Button btn1, btn2;

       private Button[] buttons = new Button[2];

 

2)생성자 메소드에서 버튼 2개를 만들어서 윈도우에 추가

       //버튼을 생성해서 패널에 추가

               btn1= new Button("button1");

               p.add(btn1);

              

               btn2= new Button("button2");

               p.add(btn2);

              

               //버튼의 이벤트 처리 -라우팅을 이용하지 않는 경우

               // 경우 많으면 힘들다.

               /*ActionListener event1 = new ActionListener() {

                      //버튼을 누르거나 텍스트 필드에서 Return누르거나 메뉴를 누르면 호출되는 메소드

                      @Override

                      public void actionPerformed(ActionEvent arg0) {

                             System.out.println("버튼1 클릭했습니다.");

                      }

               };

               btn1.addActionListener(event1);

              

               ActionListener event2 = new ActionListener() {

                      //버튼을 누르거나 텍스트 필드에서 Return누르거나 메뉴를 누르면 호출되는 메소드

                      @Override

                      public void actionPerformed(ActionEvent arg0) {

                             System.out.println("버튼2 클릭했습니다.");

                      }

               };

               btn2.addActionListener(event2);*/

              

               //이벤트 라우팅을 이용하는 방법

               ActionListener eventRouting = new ActionListener() {

                      //버튼을 누르거나 텍스트 필드에서 Return누르거나 메뉴를 누르면 호출되는 메소드

                      @Override

                      public void actionPerformed(ActionEvent arg0) {

                             //arg0.getActionCommand() 경웬느 text 사용해야 한다.

                             /*switch(arg0.getActionCommand()) {

                             case "button1":

                                    System.out.println("버특1클릭");

                                    break;

                             case "button2":

                                    System.out.println("버특2클릭");

                                    break;

                             }*/

                             System.out.println(arg0.getActionCommand() +" 예약");

                      }

               };

               btn1.addActionListener(eventRouting);

               btn2.addActionListener(eventRouting);

 

=>P 만들고 후에 코드를 추가해야 합니다.

패널을 만들고 해야 한다.

 

5.ItemEvent

=>체크박스 라디오 버튼 이나 콤보박스(Choice) 선택을 변경하는 경우에 발생하는 이벤트

=>ItemListener인터페이스 처리

=>이벤트 처리 메소드의 매개변수가 getItem() 호출하면 어떤 Item 이벤트가 발생했는지 있고 getStateChange()메소드를 호출하면 어떤 상태로 변경되었는지 확인이 가능

 

6.TextListener

=>TextField TextArea에서 텍스트의 변경이 발생했을 때를 처리하는 리스너

=>TextValueChanged(TextEvent e)메소드를 이용해서 처리

=>텍스트가 변경될 상태 변화에 따라 메시지를 출력하거나 유효성을 검사하는 용도로 사용

 

영문대소문자 그리고 숫자 특수문자가 1 이상이면 강함이라고 출력

그렇지 않은 경우에는 약함이라고 출력

특수문자는 영문 대소문자가 아니고 숫자도 아니면 특수문자로 판단

 

               //텍스트 필드나 텍스트 에어리어의 문자열이 변경될 처리를 위한 인스턴스

               TextListener t1 = new TextListener() {

                     

                      @Override

                      public void textValueChanged(TextEvent e) {

                             //텍스트 필드에 입력된 문자열을 가져오기

                             String msg = tf.getText();

                             //대소문자 숫자 ,특수문자 개수를 저장할 변수를 생성

                             int dae = 0;

                             int so = 0;

                             int su = 0;

                             int etc =0;

                            

                             //문자열을 문자단위로 접근

                             for(int i = 0;i < msg.length(); i++) {

                                    //앞에서 부터 한글자씩 가져오기

                                    char ch = msg.charAt(i);

                                    //System.out.println(ch);

                                    if(ch >= 'A' && ch <= 'Z') {

                                            dae += 1;

                                    }else if(ch >= 'a' && ch <= 'z') {

                                            so += 1;

                                    }else if(ch>= '0'  && ch <= '9'){

                                            su += 1;

                                    }else {

                                            etc += 1;

                                    }

                             }

                            

                             /*if(dae >0 && so > 0 && su >0 && etc>0) {

                                    System.out.println("강함");

                             }*/

                            

                             if(dae * so * su  * etc != 0) {

                                    System.out.println("강함");

                             }else {

                                    System.out.println("약함");

                             }

                      }

               };

               tf.addTextListener(t1);

 

**keyListener

=>키보드 이벤트를 처리하기 위한 리스너

1)처리를 위한 메소드

void keyPressed(keyEvent e);키보드를 누를

 

void keyReleased(keyEvent e);키보드에서 손을

 

void keyTypers(keyEvent e);키보드를 누르고 누른 키가 문자 키일 호출되는 메소드

keyPressed 키보드 위치만을 감지를 해서 대소문자 구분을 하지 못했고   keyTypers 대소문자 구분을 했습니다.

 

2)keyEvent클래스

=>모든 key값이 상수로 정의되어 있습니다.

=>getKeyChar() 이용해서 누른 문자를 가져올 있고  getKeyCode() 이용해서 누른 키보드의 숫자 값을 가져올 있습니다.

 

 

c, java, c# ..

옵션을 만들때 int enum 이용

int enum =>정수

python 문자열로 만든다.함수를 찾아도 어려운 이유가 여기 있다. 옵션들이 문자로 되여있다.

문자열 dictionary

color = ""

 

성별

python => String str = "";

 

c,java int gender  ->0 남자

                    ->1 여자

숫자 경우 2여도 되고 3 되고

java, c 상수 만들 경우 대문자로 쓴다.

int MAN = 0; //남자

int MAN = 1;

 

=> 바꿀 경우

final int WOMAN = 0;

       int MAN =1;

 

옵션 -> 택일 : 일련번호사용 (성별 ) - 영문자( A: 65, B : 66, C:67  ..)

     -> 다중선택(취미등 ) : 2 지수승 사용

취미 현재 2개이다

독서

컴퓨터

ð  4가지 경우가 있다.

1.  하나도 선택 안한

2.  독서

3.  컴퓨터

4.  독서 + 컴퓨터

독서 , 컴퓨터 , 복싱 = > 8

독서 ,컴퓨터 , 복싱 , 1 = > 16

여러개 옵션을 사용한 것은 이렇게 사용하면 안된다. 그래서 비트로 한다.

 

복싱

컴퓨터

독서

 

0

0

0

 

1

1

1

 

독서    1

컴퓨터  2

복싱    4

독서 + 복싱 : 5

하나의 BIT 하나이다.

옵션이 많으면 감당할 없다. 4, 5, 6, 7.....

그래서 1인지 확인 해야 한다. 1인지 확인 하는 방법은 &1 이다.나머지는 0이니깐

 

& 0 & 1 =>0

  1 & 1 =>1

 

키보드 문자키는 같이 못눌린다.

 

CTRL: 128

ALT : 512

512 640이나 물어보는 것은 낭비이다.

그래서 & 512한다.

0 & 512 => 0

0 아닌것 하고 하면 512

CTRL 경우에는 & 128

 

두가지

판단 ALT, SHIFT, ALT, MOUSE 감지

 

특정 os 타겟팅  ->여기는 숫자로 쓰준다. 확정되여있다.

swift(Object -c)       ios

andriod  ->안드로이드

vc ++ vc## -> windows 윈도우용

 

shift : 4

 

java->플랫폼의 독립적 운영체제마다 달라서 확정 주지 않다. 운영체제 특징도 많이 알아야 한다. 운영체제마다 값이 다르기 때문이다.

자바는 shift 4

thread 운영체제제에서  thread우선순위가 다르다.

window 10 이고 7이다.

 

 

자바나 ,python 윈도우형이 별로 없는 이유가 vc++, vc##편하기 때문이다.

 

ctrl+->   -> 가속도 10으로

ctrl+s ->자동 발사 s-> 싸는

 

 

 

3) 방향키를 이용해서 레이블을 움직이고 control + x 누르면 프로그램 종료하는 윈도우

KeyWindow

//키보드 이벤트 처리를 위한 인스턴스를 생성

               KeyListener listener  = new KeyListener() {

                      //키보드를 눌렀을 호출되는 메소드

                      @Override

                      public void keyPressed(KeyEvent arg0) {

                             //조합키 확인: shift -1, control -2 , alt -8

                             int modifiers = arg0.getModifiers();

                             //System.out.println(modifier);

                             //contlol+ X이면 종료

                             if((modifiers &2 ) != 0) {

                                    //별도로 누른 키가 X인지 확인 -대소문자 구분해서 하고자 하는 경우는 getKeyChar()

                                    int key = arg0.getKeyCode();

                                    if(key == KeyEvent.VK_X) {

                                            System.exit(0);

                                    }

                             }

                            

                             //System.out.println("아무 키나 누르면 호출됩니다.");

                             //대다수의 프로그램 언어가 유사하게 만들어졌다.

                            

                             //KeyChar 대소문자 구분 a->a A->A

                             //System.out.println(arg0.getKeyChar());

                             //keyCode 대소문자 구분 안함: a->64 A->65 방향키

                             //System.out.println(arg0.getKeyCode());

                            

                             //현재 레이블의 위치 가져오기

                             int x = lbl.getLocation().x;

                             int y = lbl.getLocation().y;

                            

                             //누른 키보드 가져오기

                             int code = arg0.getKeyCode();

                             switch(code){

                             case KeyEvent.VK_UP:

                                    y = y -5;

                                    break;

                             case KeyEvent.VK_DOWN:

                                    y = y + 5;

                                    break;

                             case KeyEvent.VK_LEFT:

                                    x = x -5;

                                    break;

                             case KeyEvent.VK_RIGHT:

                                    x = x + 5;

                                    break;

                             }

                             lbl.setLocation(x, y);

                      }

                      //키보드에서 손을 호출되는 메소드

                      @Override

                      public void keyReleased(KeyEvent arg0) {

                             //System.out.println("키보드에서 손을 때면 무조건 호출");

                      }

                      //문자키를 눌렀을 호출되는 메소드

                      @Override

                      public void keyTyped(KeyEvent arg0) {

                             //System.out.println("문자 키를 눌렀을 호출");

                      }

               };

               //윈도우에 키보드 이벤트 리스터를 연결

               this.addKeyListener(listener);

 

 

8.MouseListener

=>마우스 이벤트를 처리해주는 리스터

=>클릭 , 영역에 마우스가 들어온 경우 , 영역에서 벗어나는 경우 ,마우스는 누를 , 마우스에서 손을 땔때 처리를 위한 메소드가 존재

=>MouseEvent에서는 마우스의 좌표를 리턴해주는 메소드와 클릭 횟수 등을 리턴해주는 메소드가 존재

 

 

9.MouseMotionListener

=>마우스를 드레그 때를 처리해주는 리스너

=>버튼을 누르고 움직일 때는 위한  Dragged메소드와 마우스를 움직이면 무조건 호출되는 Moved 메소드가 존재

 

 

10.WindowListener

=>윈도우 이벤트를 처리해주는 리스너

=>윈도우 관련된 7개의 이벤트 처리 메소드가 존재

=>윈도우의 종료 버튼을 누를 처리를 위한 메소드는 windowClosing

이전 윈도우의 생성자에 종료 버튼을 누를 프로그램이 종료되도록 이벤트 처리 코드를 추가

WindowListener windowListener = new WindowListener() {

                      //7개가 만들어진다.

                      @Override

                      public void windowActivated(WindowEvent e) {

                             // TODO Auto-generated method stub

                            

                      }

                     

                      @Override

                      public void windowClosed(WindowEvent e) {

                             // TODO Auto-generated method stub

                            

                      }

                     

                      @Override

                      public void windowDeactivated(WindowEvent e) {

                            

                      }

                     

                      //종료 버튼을 누를 호출되는 메소드

                      @Override

                      public void windowClosing(WindowEvent e) {

                             //프로그램 종료

                             System.exit(0);

                      }

                     

                      @Override

                      public void windowDeiconified(WindowEvent e) {

                            

                      }

                     

                      @Override

                      public void windowIconified(WindowEvent e) {

                            

                      }

                     

                      @Override

                      public void windowOpened(WindowEvent e) {

                            

                      }

               };

               //윈도우 이벤트 연결

               this.addWindowListener(windowListener);

사용하지도 않는 메소드를 overriding해놓았다.

 

 

11.이벤트 처리를 Listener인터페이스를 이용해서 처리하도록 하면 실제 사용하는 메소드는 1 밖에 없는 인터페이스의 메소드는 전부 추상 메소드라서 반드시 재정의 해야 합니다.

java awt에서는 메소드가 2 이상인 Listener들을 Adapter클래스에 비여있는 내용으로 구현해서 필요한 메소드만 재정의 있도록 Adapter class 제공합니다.

Adapter class 전부 추상 클래스라서 직접 인스턴스를 생성하지 못합니다.

 

앞의 윈도우 이벤트 처리 구문을 수정

               //Listener 인터패이스라서 모든 메소드를 구현해야 하지만

               //Adapter 추상클래스라서 추상메소드 필요한 메소드만 구현하면 됩니다.

               WindowAdapter windowListener= new WindowAdapter() {

                      //종료 버튼을 누를 호출되는 메소드

                      @Override

                      public void windowClosing(WindowEvent e) {

                             //프로그램 종료

                             System.exit(0);

                      }

               };

               //윈도우 이벤트 연결

               this.addWindowListener(windowListener);

 

 

**Swing

=>jvm 자원을 이용해서 GUI(Graphic User Interface)프로그래밍

=>플랫폼에 독립적인 프로그래밍

=>AWT보다 속도도 빠르고 효율적

 

**Container

1.JFrame

=>윈도우 클래스

=>종료 기능을 부여할 때는 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) 호출

=>pack이라는 메소드를 제공해서 윈도우 전체 크기를 하위 COmponent들을 배치한 크기로 설정

=>setIconImage(Image image) 이용해서 아이콘 설정 가능

 

2.전체 화면 크기 구하기

Tookit toolkit = Tookit.getDefaultToolkit();

Dimension size = toolkit.getScreenSize();

 

3.JPanel

=>패널 클래스

=>생성자에 Panel(boolean isDoubleBuffered):더블 버퍼링 여부를 설정

더블 버퍼링: 출력할 내용을 메모리에 저장해두고 출력하는 방식

            메모리 사용량은 늘어나지만 다음에 다시 출력할 출력 속도를 빠르게 해줍니다.

4.JScrollPane

=>스크롤 기능을 가진 클래스

=>부모 화면보다 컴포넌트를 배치할 사용

=>생성자를 호출해서 인스턴스를 만들 하위 컴포넌트를 대입

 

 

**Swing 일반 컴포넌트

1.경계선 설정 기능(Border)

=>setBorder메소드에 AbstractBorder클래스의 하위 클래스 인스턴스를 대입하면 경계선이 만들어집니다.

=>AbstractBorder클래스의 하위 클래스 :BevelBorder, CompoundBorder, EmptyBorder, EctchedBorder, TitleBorder

 

2.Component 마우스를 올리면 보여지는 tooltip 설정 기능

=>setTooltipText메소드에 문자열을 대입하면 툴팁이 만들어집니다.풍선 도움말

 

 

3.JLabel

=>문자열 출력을 위한 컴포넌트

=>생성자에서 Icon 대입하면 이미지 출력 가능

맞춤 설정도 가능합니다.

 

 

 

 

4.버튼

=>AbstractButton(추상클래스) 클래스로 부터 상속받은 클래스를 이용

=>JButton,JTOGGLEButton,JRadioButton 으로 구분

=>현재 윈도우에 버튼을 추가해서 버튼을 누를 마다 애니메이션을 시작하고 중지하는 기능을 구현

=>스레드를 만들어야 하는 순간

중간중간 다른 작업을 수행할 있도록 만들어야

실행 중간에 멈출수 있도록 해야

네트워크에서 다운로드나 업로드를 받을 (오랜 시간이 걸리는 작업)

상바대는 작업이라면 버튼 하나면 된다. 시작 중지

public class MyFrame extends JFrame {

       JLabel lbl;

       ImageIcon icon;

       JButton btn;

       //여기에서 만든 변수는 자동 초기하된다.

       //애니메이션을 수행할 스레드 변수

       Thread th;//자바는 네트워크 작업할 스레드 필수 하니깐

       public MyFrame() {

               JPanel p = new JPanel();

               //JLabel lbl = new JLabel("문자열");

               //이미지를 가지고 아이콘을 생성

               //이미지 파일 크기 그래도 성성됩니다.

               icon = new ImageIcon("C:\\project\\JAVA_PROJECT\\java\\src\\java\\img\\heli1.png");

               lbl = new JLabel(icon);

               p.add(lbl);

              

               //버튼을 만들어서 패널에 추가

               btn =   new JButton("시작");

               p.add(btn);

              

               //버튼을 누를 이밴트 처리를 위한 인스턴스를 생성

               //위임해도 실행하는데는 아무런 영향이 없다.

               ActionListener listener = new ActionListener() {

                      @Override

                      public void actionPerformed(ActionEvent e) {

                             switch(e.getActionCommand()) {

                             case "시작":

                                    btn.setText("중지");

                                    //스레드를 생성해서 시작

                                    th = new Thread() {

                                            String[] images = {"heli1.png" ,"heli2.png","heli3.png"};//images[i%images.length]

                                            public void run() {

                                                   try {

                                                          int i = 0;

                                                          while(true) {

                                                                 //0.1초마다 대기

                                                                 Thread.sleep(100);

                                                                 //아이콘 생성

                                                                 icon = new ImageIcon("C:\\project\\JAVA_PROJECT\\java\\src\\java\\img\\"+(i%10)+".png");

                                                                 lbl.setIcon(icon);

                                                                 i += 1;

                                                          }

                                                   }catch (InterruptedException e) {

                                                          return ;

                                                   }

                                            }

                                    };

                                    th.start();

                                   

                                    break;

                             case "중지":

                                    btn.setText("시작");

                                    //스레드를 중지

                                    th.interrupt();

                                    break;

                             }

                      }

               };

               btn.addActionListener(listener);

               add(p);

              

               //Frame 기본 설정

               setTitle("이미지 레이블");

               setLocation(100, 100);

               setSize(1000, 1000);

               setVisible(true);

               //종료 기능 부여

               setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

              

               //이미지 교체 애니메이션

               //현재는 코드가 진행이 안된다.

               /*String[] images = {"heli1.png" ,"heli2.png","heli3.png"};*/

               /*int i = 0;

               while(true) {

                      try {

                             Thread.sleep(50);

                             //icon = new ImageIcon("C:\\project\\JAVA_PROJECT\\java\\src\\java\\img\\"+(i%10)+".png");

                             icon = new ImageIcon("C:\\project\\JAVA_PROJECT\\java\\src\\java\\img\\heli"+(i%3)+".png");

                             lbl.setIcon(icon);

                             i = i+ 1;

                      } catch (InterruptedException e) {

                             // TODO Auto-generated catch block

                             e.printStackTrace();

                      }

               }*/

               //시작하고 중지 스레드 interrupte걸어서

              

               /*for(int i = 0 ; i< 10; i++) {

                      try {

                             Thread.sleep(1000);

                             System.out.println(i);

                             //lbl.setText("레이블:"+i);

                            

                             icon = new ImageIcon("C:\\project\\JAVA_PROJECT\\java\\src\\java\\img\\"+i+".png");

                             //끝부분만 바꾸면 바꿀 있다.

                             lbl.setIcon(icon);

                            

                      } catch (InterruptedException e) {

                      }

               }*/

       }

}

 

 

5.JTextField

=> 줄의 문자열을 입력받기 위한 컴포넌트

=>현재 커서의 위치를 getCaretPosition으로 가져오고 setCaretPosition(int position)으로 설정

마우스 포인터를 cursor하는 경우도 있지만 caret이라고 하는 경우도 있습니다.

cursort 데이터를 단위로 하나씩 접근하는 포인터의 의미로도 사용

 

6.JPasswordField

=>비밀번호를 입력받기 위한 컴포넌트

=>보여지는 문자를 echoChar라고 합니다.

=>입력한 내용을 가져올 때는 getText deprecated 되서 getPassword 사용하는 것을 권장

 

 

7.JTextArea

=>여러 입력을 위한 컴포넌트

=> 바꿈 모드 설정을 위한 setLineWrap(boolean warp). setWrapStyle(boolean word):단어 단위 바꿈

 

8.JComboBox

=>콤보박스

=>여러 개의 항목 중에서 화면에 하나만 출력하고 하나만 선택할 있도록 해주는 컴포넌트

 

9. JList

=>리스트 또는 리스트 박스

=>여러 개의 항목 여러 개를 화면에 출력할 있고 여러 개를 선택하도록 있도록 해주는 컴포넌트

=>ComboBox JList 용도가  Radio CheckBox 같은데 항목이 많을 Radio CheckBox 영역을 너무 많이 차지 하기 때문에 이런 경우에는 comboBox List 사용

항목의 개수 때문에

 

 

10.JTable

=>테이블 모양으로 데이터를 출력하는 컴포넌트

1)생성자

JTable():비여있는 상태로 생성

JTable(int rows, int cols);행과 수를 지정해서 생성

JTable(TableModel model): 데이터 모델을 이용해서 생성 -MVC구현을 위해서 존재

 

2)데이터 출력

setValueAt(Object value, int row, int col):row col 해당하는 셀에 value toString 결과를 출력

 

setModel(TableModel model);테이블 모델을 만들어서 출력

 

3) DefaultTableModel

DefaultTableModel()

DefaultTableModel(int 행개수, int 열개수)

DefaultTableModel(Object [][]data, Object[] columnName):첫번째 매개변수는 셀에 출력할 데이터의 이차원배열이고 뒤의 데이터는 컬럼이름 배열

 

4)테이블 모델을 이용해서 데이터를 설정한 경우의 데이터 편집

addRow(Object[] data)

insertRow(int row,Object[] data)

moveRow(int start, int end, int to);start부터 end까지의 행을 to 위치로 이동

 

updateUI();다시 출력

 

5)테이블 모델을 이용하기를 권장하는 이유

=>JTable 출력하는 모양에만 관여를 하고 실제 데이터의 삽입과 삭제는 TableModel 관여

 

**Pane

=>특정 목적에만 이용하도록 만든 컴포넌트

1.JScrollPane

=>스크롤을 만들어주는 컴포넌트

 

2.JEditorPane

=>텍스트를 출력하기 이한 컴포넌트

=>TextArea 다른 점은 URL 연결해서 HTML 출력할 있고 RTF포맷도 출력이 가능

 

3.JTabbedPane

=>탭을 만들기 위한 컴포넌트

 

4)javax.swing.JOptionPane

=>메시지나 줄의 입력을 받기 위한 대화상자

1)MessageDialog

=>단순 메시지 출력을 위한 대화상자

=>JOptionPane.showMessageDialog() 이용해서 생성

 

2)ConfirmDialog

=>버튼을 2 이상 배치해서 생성한 버튼에 따라 다른 작업을 하고자 사용

=> JOptionPane.showConfirmDialog() 이용해서 생성

누른 버튼의 인덱스를 리턴합니다.

 

3)InputDialog

=>하나의 텍스트필드를 배치해서 줄의 텍스틀 입력받을 있는 대화상자

=> JOptionPane.showInputDialog() 이용해서 생성

확인 버튼을 누르면 입력한 내용이 String으로 리턴되고 취소버튼을 누르면 null 리턴됩니다.

입력한 내용이 없는데 확인을 누르면 null 아니고 "" 리턴됩니다.

 

 


showMessageDialog
(Component parentComponent, Object message, String title, int messageType, Icon icon)

Brings up a dialog displaying a message, specifying all parameters.

 

               //showMessageDialog(Component parentComponent, Object message, String title, int messageType, Icon icon)

               //단순한 메시지 출력 - 리턴값이 없습니다.

               //JOptionPane.showMessageDialog(this, "메시지","제목",JOptionPane.ERROR_MESSAGE);

               //ERROR_MESSAGE red

              

               //2 이상의 버튼을 배치해서 confirm 받는 메소드

               /*

               int result = JOptionPane.showConfirmDialog(this, "정말로 삭제","삭제",JOptionPane.YES_NO_CANCEL_OPTION);

               if(result == JOptionPane.YES_OPTION) {

                      JOptionPane.showMessageDialog(this, "yes","제목",JOptionPane.ERROR_MESSAGE);

               }else if(result == JOptionPane.NO_OPTION) {

                      JOptionPane.showMessageDialog(this, "no","제목",JOptionPane.ERROR_MESSAGE);

               }else {

                      JOptionPane.showMessageDialog(this, "cancel","제목",JOptionPane.ERROR_MESSAGE);

               }*/

              

               //한줄의 텍스트를 입력받는 대화상자를 출력

               //입력한 내용이 없는 상태에서 확인을 누르면 ""

               //

               String name = JOptionPane.showInputDialog(this,"이름을 입력하세요","");

               System.out.println(name);

 

**메뉴

=>JMenuBar, JMenu, JMenuItem(JMenuItem, JCheckBoxMenuItem, JRadioButtonMenuItem)

=>메뉴에 setMnemonic(int 단축키) 설정하면 alt 조합해서 단축키로 사용 가능

응용프로그램을 만들 alt 포함해서 단축키를 만드는 것은 권장하지 않습니다.

미국에서 메뉴에 대한 단축키를 alt 사용한다.

ctrl 단독으로 많이사용한다.

 

**Stream

1.  입출력 Stream

2.  1.8에서 등장한 Map Reduce 프로그래밍일 위한 스트림 ->우리가 하는

 

 

 

반응형

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

java-15  (1) 2020.10.05
java-14  (0) 2020.10.04
java-12  (0) 2020.10.02
java-11  (0) 2020.10.01
java-10  (0) 2020.09.30

+ Recent posts