。゚(*´□`)゚。

코딩의 즐거움과 도전, 그리고 일상의 소소한 순간들이 어우러진 블로그

[네이버클라우드] 클라우드 기반의 개발자 과정 7기/웹프로그래밍

[NC7기-44일차(6월27일)] - 웹프로그래밍 25일차 -2

quarrrter 2023. 6. 27. 18:11

팩토리얼

n! = (n-1)! * n

package bitcamp.test;

public class Test {

public static void main(String[] args) {
		
		System.out.println(factorial(5));
	} 

	static int factorial (int value) {
		if (value ==1) {
			return 1;
		}
		return factorial(value -1) * value;
	}
}

호출이 끝나지 않은 상태에서 호출 호출 호출 호출 호출 ,,,,  5를 호출했을때 jvm stack에 5가 생김. 같은 이름으로 메서드를 호출했다고 생각하면 됨. 안에서 빙빙 도는게 아니구 새로운 메서드를 호출 호출 호출 한거임

메서드 호출되면 jvm stack에 사용할 로컬변수가 만들어짐

재귀호출이면 stack에 만들어지구 만들어지구 꽉차면 무한루프 빠져서 stack overflow에 빠짐 

 

재귀호출 : 수학식을 그대로 사용할 수 있어서 좋음 

단점: 너무 많이 이루어지면 stack overflow 빠질 수 있음, 메모리 & 시간이 낭비될 수 있음. 반복문을 돌릴 수 있으면 반복문 돌리는게 메모리 & 시간 줄일수잇음. 팩토리얼처럼 가벼운 경우엔 재귀호출이 편하긴함. 

 

io ex01 -exam0710 // 활용 - 지정한 폴더 및 그 하위 폴더까지 모두 검색하여 파일 및 디렉토리 이름을 출력하라.

유닉스에는 트리라는게 있음 

// 활용 - 지정한 폴더 및 그 하위 폴더까지 모두 검색하여 파일 및 디렉토리 이름을 출력하라.
package com.eomcs.io.ex01;
import java.io.File;
public class Exam0710 {

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

    File dir = new File(".");
    System.out.println(dir.getCanonicalPath());

    printList(dir, 1);
  }

  static void printList(File dir, int level) {

    // 현재 디렉토리의 하위 파일 및 디렉토리 목록을 알아낸다.
    File[] files = dir.listFiles();

    // 리턴 받은 파일 배열에서 이름을 꺼내 출력한다.
    String indent = getIndent(level);
    for (File file : files) {

        System.out.print(indent);

      if (file.isDirectory() && !file.isHidden()) {
        System.out.printf("%s/\n", file.getName());
        printList(file, level + 1);
      } else if (file.isFile()) {
        System.out.print("\\-- ");
        System.out.printf("%s\n", file.getName());
      }
    }
  }

  static String getIndent(int level) {
	  StringBuilder strBuilder = new StringBuilder();
    for (int i = 0; i < level; i++) {
    	strBuilder.append("  ");
    }
    return strBuilder.toString();
  }

}

폴더삭제

// 활용 - 지정한 폴더를 삭제하라.
package com.eomcs.io.ex01;

import java.io.File;

public class Exam0720_04 {

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

    // temp 디렉토리를 삭제하기
    File dir = new File("temp");

    deleteFile(dir);
  }

  static void deleteFile(File dir) {
    // 주어진 파일이 디렉토리라면 하위 파일이나 디렉토리를 찾아 지운다.
    if (dir.isDirectory()) {
      File[] files = dir.listFiles();
      for (File file : files) {
        deleteFile(file);
      }
    }

    dir.delete(); // 현재 파일이나 폴더 지우기
  }

}

정리하기 , , ,, ,

 

ex02 0110- 0130 FileOutputStream

// Byte Stream - 바이트 단위로 출력하기
package com.eomcs.io.ex02;

import java.io.FileOutputStream;

public class Exam0110 {

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

    // 1) 파일로 데이터를 출력하는 객체를 준비한다.
    // - new FileOutputStream(파일경로)
    // - 지정된 경로에 해당 파일을 자동으로 생성한다.
    // - 기존에 같은 이름의 파일이 있으면 덮어쓴다.
    // - 주의! 기존 파일이 삭제된다.
    // - 파일 경로가 절대 경로가 아니면
    //   - 리눅스,유닉스: / 로 시작하지 않으면,
    //   - 윈도우: c:\, d:\ 등으로 시작하지 않으면,
    //   현재 디렉토리가 기준이 된다.
    FileOutputStream out = new FileOutputStream("temp/test1.data");

    // 2) 1바이트를 출력한다.
    // => write(int) : 1바이트를 출력하는 메서드이다.
    //    파라미터의 타입이 int라고 해서 4바이트를 출력하는 것이 아니다.
    //    오직 맨 끝 1바이트만 출력한다.(2자리)
    out.write(0x7a6b5c4d); // 출력하는 값은 0x4d 이다.
    out.write(2);     // 0x00000002
    out.write(40);    // 0x00000028
    out.write(100);   // 0x00000064
    out.write(101);   // 0x00000065
    out.write(102);   // 0x00000066
    out.write(127);   // 0x0000007f
    out.write(255);   // 0x000000ff
    out.write('A');   // 0x0041
    out.write('가');  // 0xac00

    // 3) 출력 도구를 닫는다.
    // - OS에서 관리하는 자원 중에서 한정된 개수를 갖는 자원에 대해
    //   여러 프로그램이 공유하는 경우, 항상 사용 후 OS에 반납해야 한다.
    // - 그래야 다른 프로그램이 해당 자원을 사용할 수 있다.
    //   예) 파일, 메모리, 네트워크 연결 등
    // - 이런 자원을 사용하는 클래스는 자원을 해제시키는 close()라는 메서드가 있다.
    // - 보통 java.lang.AutoCloseable 인터페이스를 구현하고 있다.
    // - 이번 예제에서 다루는 FileOutputStream 클래스에도 close()가 있다.
    // - 따라서 FileOutputStream 객체를 사용한 후에는 close()를 호출하여
    //   사용한 자원을 해제시켜야 한다.
    // - close()를 호출하면,
    //   FileOutputStream이 작업하는 동안 사용했던 버퍼(임시메모리)를 비운다.
    // - OS에서 제공한 파일과의 연결을 끊는다.
    //
    out.close();
    // 물론, JVM을 종료하면 JVM을 실행하는 동안 사용했던 모든 자원은
    // 자동으로 해제된다.
    // 이런 예제처럼 짧은 시간 동안만  실행되는 경우,
    // close()를 호출하지 않아도 자원을 해제시키는데 문제가 없다.
    // 문제는 24시간 365일 멈추지 않고 실행하는 서버 프로그램인 경우
    // 사용한 자원을 즉시 해제시키지 않으면
    // 자원 부족 문제가 발생한다.
    // 결론!
    // - 간단한 코드를 작성하더라도 AutoCloseable 인터페이스를 구현한 클래스를 사용할 때는
    //   사용하고 난 후 자원을 해제시는 close()를 반드시 호출하라.
    //
    System.out.println("데이터 출력 완료!");

  }

binary file / text file 

binary file : 텍스트 편집기로 읽고 변경할 수 없는 파일 => 데이터의 형식이 바이트 단위로 되어있다. => 전용app 편집

예) .hwp .pdf .jpg .gif .avi .class .exe .wav .mp3 .ppt .xls

text file : 텍스트 편집기(메모장, vs code, Eclipse)로 읽고 변경할 수 있는 파일 

예) .txt .java .c .py .html .docx .rtf .js .css .pptx .xlsx (ECMA관리로 ,,,  글케됨)

// Byte Stream - 바이트 단위로 읽기

package com.eomcs.io.ex02;
import java.io.FileInputStream;
public class Exam0120 {

  public static void main(String[] args) throws Exception {
    // 1) 파일 데이터 읽기를 담당할 객체를 준비한다.
    // - new FileInputStream(파일경로)
    FileInputStream in = new FileInputStream("temp/test1.data");

*************************
    // 2) 1바이트를 읽는다.
    // => read() 메서드의 리턴 타입이 int 라 하더라도 1바이트를 읽어 리턴한다.
    int b = in.read(); // 읽은 값은 0x4d 이다.
    
    System.out.printf("%02x\n", b);
    System.out.printf("%02x\n", in.read());
    System.out.printf("%02x\n", in.read());
    System.out.printf("%02x\n", in.read());
    // read() 를 호출할 때마다 이전에 읽은 바이트의 다음 바이트를 읽는다. 

    // 3) 읽기 도구를 닫는다.
    in.close();
  }
}

***********************
    // 반복문을 이용하여 여러 바이트를 읽는다.
    int b;
    //    while (true) {
    //      b = in.read();
    //      if (b == -1) // 파일의 끝에 도달하면 -1을 리턴한다.
    //        break;
    //      System.out.printf("%02x ", b);
    //    }
// -1이면 파일의 끝에 도달했다는 뜻이다. 
    while ((b = in.read()) != -1) {
      System.out.printf("%02x ", b);
    }

    in.close();
  }

}

 

Byte Stream - 바이트 배열 읽기 (내 눈으로 바이트 코드 확인)

Byte Stream - 바이트 배열의 특정 부분을 출력하기 (byte코드에 넣기)

 
Byte Stream - 바이트 배열 읽기
바이트들을 저장할 배열을 넉넉히 준비한다. => 이렇게 임시 데이터를 저장하기 위해 만든 바이트 배열을 보통 "버퍼(buffer)"라 한다.
 
1.  read(byte[])
    - 버퍼가 꽉 찰 때까지 읽는다.
    - 물론 버퍼 크기보다 파일의 데이터가 적으면 파일을 모두 읽어 버퍼에 저장한다.
    - 리턴 값은 읽은 바이트의 개수이다.
   2. read(byte[], 저장할 위치, 저장하기를 희망하는 개수)
    - 읽은 데이터를 "저장할 위치"에 지정된 방부터 개수만큼 저장한다.
    - 리턴 값은 실제 읽은 바이트 개수이다.
write(byte[]) : 배열의 값 전체를 출력한다.
write(byte[], 시작인덱스, 출력개수) : 시작 위치부터 지정된 개수를 출력한다.

out.write(bytes, 2, 3); // 2번 데이터부터 3 바이트를 출력한다.

 

읽기 
FileInputStream in = new FileInputStream("temp/test1.data");
byte[] buf = new byte[100];
int count = in.read(buf);
in.close();
System.out.printf(count);
for(int i = 0; i < count; i++ )
 System.out.prlinf("%02x ", buf[i]);
System.out.println();
바이트 배열의 특정부분 출력하기
FileOutputStream out = new FileOutputStream("temp/test1.data");
byte[] bytes = {0x7a, 0x6b, 0x5c, 0x4d, 0x3e, 0x2f, 0x30};
out.write(bytes, 2, 3); // 2번 데이터부터 3 바이트를 출력한다.
out.close();
읽은 데이터를 바이트 배열의 특정 위치에 저장하기
FileInputStream in = new FileInputStream("temp/test1.data");
byte[] buf = new byte[100];
int count = in.read(buf);
in.close();
System.out.printf("%d\n", count);
for(int i = 0; i < 100; i++ )
System.out.printf("%d: %02x \n", i, buf[i]);
 

 

 

프로젝트에서 외부 라이브러리를 사용하는 방법

Maven Central: com.drewnoakes:metadata-extractor:2.18.0 (sonatype.com)

 

 

추가 후 저장

 

라이브러리 리스트  새로고침-

Eclipse IDE에서 해당 프로젝트를 refresh 한다.

 

// FileInputStream 활용 - JPEG 파일 읽기 : 위도 경도 알아내기
package com.eomcs.io.ex02;

import java.io.File;

import com.drew.imaging.ImageMetadataReader;
import com.drew.metadata.Metadata;
import com.drew.metadata.exif.GpsDirectory;

public class Exam0420 {

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

    File file = new File("sample/gps-test.jpeg");
    
    Metadata metadata = ImageMetadataReader.readMetadata(file);
    GpsDirectory gpsDirectory = metadata.getFirstDirectoryOfType(GpsDirectory.class);
    
    System.out.println(gpsDirectory.getGeoLocation().getLatitude());
    System.out.println(gpsDirectory.getGeoLocation().getLongitude());
  }

}