https://validator.w3.org/

 

The W3C Markup Validation Service

Validate by File Upload Note: file upload may not work with Internet Explorer on some versions of Windows XP Service Pack 2, see our information page on the W3C QA Website.

validator.w3.org

여기서 체크하면 된다.

 

https://www.w3schools.com/

 

W3Schools Online Web Tutorials

HTML Example:

This is a heading

This is a paragraph.

Try it Yourself CSS Example: body {   background-color: lightblue; } h1 {   color: white;   text-align: cente

 

www.w3schools.com

 

 

 

여기서 html콘솔 에관한 것 확인도 가능하다

APK

안드로이드 응용 프로그램 패키지(영어: Android application package, APK)는 안드로이드 소프트웨어 미들웨어 배포에 사용되는 패키지 파일이며, '.apk'확장자를 가진다. APK 파일은 우분투 같은 데비안 기반 운영 체제에서 사용하는 뎁 패키지 마이크로소프트 윈도우에서 사용하는 MSI 패키지와 같은 설치 파일과 비슷하다. APK 파일을 만들려면, 안드로이드용 프로그램을 먼저 컴파일한 후, 모든 파일들을 하나의 패키지 파일로 모은다. APK 파일은 해당하는 프로그램의 모든 코드를 포함하며, 자원, 정보, 인증서 및 매니페스트 파일 (en:Manifest file) 등을 포함한다.

안드로이드 응용 프로그램 패키지의 확장자는 .apk ZIP파일 기반인 JAR를 기반으로 하며, 압축 파일의 한 종류이다. MIME 유형은 application/vnd.android.package-archive이다.

 

 

ios jailbreak

iOS 탈옥(영어: iOS jailbreak)은 iOS의 샌드박스 제한을 풀어 타 회사에서 사용하는 서명되지 않은 코드를 실행할 수 있게 하는 과정을 말한다. 시디아의 개발자인 제이 프리맨은 전체 아이폰 중 10%가 탈옥되었다고 추정한다.

 

탈옥을 하는 이유 중 하나는 애플과 앱 스토어가 막아 놓은 컨텐츠에 접근하기 위해서이다.[2] 애플은 앱 스토어에 앱을 등록하기 전에, 먼저 앱이 정책에 부합하는지를 검열하는 절차를 가진다.[3] 하지만, 애플의 검열 기준은 안전성과 보안 문제만에 관한 것은 아니며, 이 기준은 상당히 모호하고 독단적이라는 비판을 받는다.[4] 검열에서 삭제된 앱들을 이용하기 위해서,[5] 사용자들은 탈옥을 함으로써 앱스토어를 이용하지 않고 애플리케이션을 이용할 수 있다. 또한 탈옥을 함으로써 아예 애플에게 검열받지 않은 앱,[6] 즉 사용자가 직접 제작한 앱이나 인터페이스를 사용할 수 있다.

시디아를 통해서 다운받는 애플리케이션들은 애플의 앱스토어 규정을 완전히 무시해도 되기 때문에, 시디아의 대부분의 애플리케이션들은 그 자체로 작동하는 것이 아니라, 앱스토어의 다른 앱들을 해킹하는 용도로 쓰인다.[7] 유저들은 이러한 탈옥 앱을 설치함으로써 인터페이스를 개인화하거나,[7]필요한 기능들을 추가하거나 고칠 수 있으며,[8] 직접 파일에 엑세스함으로써 앱을 좀 더 손쉽게 수정할 수 있다.[9][10] 중국사람들은 애플것보다 쓰기 쉬운 중국어 자판을 설치하기 위해 탈옥을 하기도 한다.[11]

 

iOS 탈옥 - 위키백과, 우리 모두의 백과사전

iOS 탈옥(영어: iOS jailbreak)은 iOS의 샌드박스 제한을 풀어 타 회사에서 사용하는 서명되지 않은 코드를 실행할 수 있게 하는 과정을 말한다. 시디아의 개발자인 제이 프리맨은 전체 아이폰 중 10%가

ko.wikipedia.org

 

 

 

루팅

루팅(영어: rooting)은 모바일 기기에서 구동되는 안드로이드 운영 체제 상에서 최상위 권한(루트 권한)을 얻음으로 해당 기기의 생산자 또는 판매자 측에서 걸어 놓은 제약을 해제하는 행위를 가리키는 말이다.

이 루팅을 통해 해당 기기의 사용자들은 생산자 또는 판매자 측에서 공식 제공하는 버전보다 더 높은 버전의 안드로이드나 CyanogenMod처럼 사용자들이 임의로 개조한 안드로이드를 설치 및 구동할 수 있으며, 사용자가 속한 지역의 안드로이드 사용자들에게 판매하지 않는 프로그램들을 구입하거나 일반 사용자 권한 이상의 권한 등을 필요로 하는 프로그램들을(백업 프로그램, 하드웨어 해킹 프로그램 등) 사용할 수 있다.

안드로이드 특성상 반드시 최고권한(관리자)이 필요한 동작(카메라무음, 파일접근, 시스템앱삭제 등등)을 수행하고자 할 때 진행된다. 한 번 루팅된 안드로이드는 언루팅 하지 않는 이상 몇 번이고 supersu를 지웠다 설치했다 해도 루팅은 그대로 유지된다.

기기의 생산자 또는 판매자 측에서 걸어 놓은 제약을 해제한다는 면에서 iOS 관련 용어인 탈옥(Jailbreaking)과 비슷하지만 안드로이드 루팅은 서드파티 프로그램 설치를 막아 놓은 AT&T 안드로이드 폰들을 제외하고는[1] 루팅 없이도 구글 플레이에서 제공하지 않는 프로그램을 따로 구할 필요가 없다는 차이점이 있다.

 

 

 

 

넷스케이프(몰라도된다.)

 

 

서브라임텍스트

서브라임 텍스트(Sublime Text)는 파이썬 API용으로 작성된 사유 크로스 플랫폼 소스 코드 편집기이다. 수많은 프로그래밍 언어 마크업 언어를 네이티브로 지원하며 플러그인을 사용하여 사용자에 의해 기능을 확장할 수 있다. (플러그인은 일반적으로 자유 소프트웨어 라이선스로 공동체에 의해 빌드, 관리된다)

 

 

 

아톰

아톰(Atom)은 자유-오픈 소스 형태의[4][5] OS X, 리눅스, 윈도우[6] 문서  소스 코드 편집기이다. Node.js로 작성된 플러그인, 깃허브가 개발한 임베디드 깃 관리 지원을 포함한다. 대부분의 확장 패키지는 자유 소프트웨어 라이선스를 취하며 커뮤니티가 만들고 관리하고 있다.[7] 아톰은 크로미엄에 기반을 두며 커피스크립트로 작성되어 있다.[8] IDE로 사용할 수도 있다. 2015년 6월 25일에 정식 1.0 버전이 출시되었다.[9]

 

아톰 (문서 편집기) - 위키백과, 우리 모두의 백과사전

아톰 (문서 편집기) 위키백과, 우리 모두의 백과사전.

ko.wikipedia.org

 

 

 

팬그램

팬그램(pangram)은 알파벳의 모든 글자를 사용해 만든 문장을 뜻한다. 엄격하게 한 글자를 한 번만 사용한 경우도 있고, 복수 사용을 허용한 경우도 있다. 즉, 글이 최대한 짧으면서 모든 글자를 사용했을 때 가치가 높아진다.

그 자체로 언어유희로서 창작되고 활용되기도 하며 장비를 테스트할 때도 이용된다. 특히 시각 디자인에서 폰트 모양을 보여줄 때 요긴하게 사용된다. 레이아웃을 보여줄 때 사용하는 의미 없는 글줄인 로렘 입숨과 성격이 비슷하다.

팬그램의 반대 개념으로, 알파벳의 특정 글자를 사용하지 않고 문장을 만드는 것을 리포그램이라고 하며, 이쪽은 오히려 글이 길어야 가치가 높아진다. 이는 KBS의 스펀지 95회 방송분에서 언급된 적이 있다.

http://guny.kr/stuff/klorem/

 

한글 Lorem Ipsum (간세네)

로렘 입숨(lorem ipsum; 줄여서 립숨, lipsum)은 출판이나 그래픽 디자인 분야에서 폰트, 타이포그래피, 레이아웃 같은 그래픽 요소나 시각적 연출을 보여줄 때 사용하는 표준 채우기 텍스트로, 최종

guny.kr

 

 

 

브라우저 엔진

트라이던트 엔진은 이질적인 엔진이다.

브라우저 엔진(browser engine)은 주된 모든 웹 브라우저의 핵심이 되는 소프트웨어 구성 요소이다. 브라우저 엔진의 주된 역할은 HTML 문서와 기타 자원의 웹 페이지 사용자의 장치에 상호작용적인 시각 표현으로 변환시키는 것이다.

 

 

 

 

데이트 피커(예전에쓰던거)

jQuery UI(제이쿼리 UI)는 jQuery(자바스크립트 라이브러리), 종속형 시트(CSS), HTML로 구현된 GUI 위젯, 애니메이션 시각 효과, 테마의 묶음이다.[4] 자바스크립트 애널리틱스 서비스 Libscore에 따르면 jQuery UI는 상위 100만 개의 웹사이트 중 197,000곳 이상에서 이용되며 2번째로 유명한 자바스크립트 라이브러리로 분석되었다.[5] 저명한 사용처는 핀터레스트, 페이팔, IMDb, 허핑턴 포스트, 넷플릭스가 포함된다.[6]

jQuery와 jQuery UI 둘 다 MIT 허가서를 통해 jQuery 재단에 의해 배급되는 자유-오픈 소스 소프트웨어이다. jQuery UI는 2007년 9월 처음 게시되었다.[3][7]

 

 

jQuery UI - 위키백과, 우리 모두의 백과사전

jQuery UI(제이쿼리 UI)는 jQuery(자바스크립트 라이브러리), 종속형 시트(CSS), HTML로 구현된 GUI 위젯, 애니메이션 시각 효과, 테마의 묶음이다.[4] 자바스크립트 애널리틱스 서비스 Libscore에 따르면 jQue

ko.wikipedia.org

https://jqueryui.com/datepicker/

 

Datepicker | jQuery UI

Datepicker Select a date from a popup or inline calendar The datepicker is tied to a standard form input field. Focus on the input (click, or use the tab key) to open an interactive calendar in a small overlay. Choose a date, click elsewhere on the page (b

jqueryui.com

 

modal

이미지 하이라이트 대신 사용 같은창이어도 사용자가 다른 느낌을 받도록

아래사이트에서 관련 내용 확인가능

https://www.w3schools.com/

 

W3Schools Online Web Tutorials

HTML Example:

This is a heading

This is a paragraph.

Try it Yourself CSS Example: body {   background-color: lightblue; } h1 {   color: white;   text-align: cente

 

www.w3schools.com

 

출처 : 위키백과

 

'HTML > 용어' 카테고리의 다른 글

HTML용어2  (0) 2021.08.05

예외 발생시키기

키워드 throw를 사용해서 프로그래머가 고의로 예외를 발생시킬 수 있다.

1. 먼저, 연산자 new를 이용해서 발생시키려는 예외 클래스의 객체를 만든 다음
	Exception e = new Exception("고의로 발생시켰음");
    2. 키워드 throw를 이용해서 예외를 발생시킨다.
    throw e;

 

public class ExceptionEx09 {
	// Exception 클래스들 : checked exception
	// RuntimeException 클래스들 : unchecked exception
	
	public static void main(String[] args) {
		try {
		Exception e = new Exception("고의 발생 예외");
		throw e;
	} catch (Exception e1) {
		System.out.println("에러 메세지 : " + e1.getMessage());
		e1.printStackTrace();
	}
	System.err.println("프로그램이 정상 종료됨");
//		throw new Exception("이거도 가능");
	}

Exception인스턴스를 생성할 때, 생성자에 String을 넣어 주면, 이 String이 Exception인스턴스에 메세지로 저장된다. 이 메세지는 getMessage()를 이용해서 얻을 수 있다.

 

 

public class ExceptionEx11 {
	public static void main(String[] args) {
		throw new RuntimeException(); //RuntimeException을 고의로 발생시킨다.
	}
}

이 예제는 예외처리를 하지 않았음에도 불구하고 이전의 예제와는 달리 성공적으로 컴파일되나, RuntimeException이 발생하여 비정상적으로 종료된다.

RuntimeException클래스와 그 자손(RuntimeException클래스들)에 해당하는 예외는 프로그래머에 의해 실수로 발생하는 것들이기 때문에 예외처리를 강제하지 않는 것이다. 만일 RuntimeException클래스들에 속하는 예외가 발생할 가능성이 있는 코드에서도 예외처리를 필수로 해야 한다면, 아래와 같이 참조변수와 배열이 사용되는 모든 곳에 예외처리를 해주어야 할 것이다.

try{
	int[] arr= new int[10];

	System.out.println(arr[10]);
} catch(ArrayIndexOutOfBoundsException ae) {
		...
} catch(NullPointerException ne) {
		...
}

컴파일러가 예외처리를 확인하지 않는 RuntimeException클래스들은 'unchecked예외)라고 부르고, 예외처리를 확인하는 Exception클래스들은 'checked예외'라고 부른다.

 

 

 

메서드에 예외 선언하기

예외를 처리하는 방법에는 지금까지 배워 온 try-catch문을 사용하는 것 외에, 예외를 메서드에 선언하는 방법이 있다.

 메서드에 예외를 선언하려면, 메서드의 선언부에 키워드 throws를 사용해서 메서드 내에서 발생할 수 있는 예외를 적어주기만 하면 된다. 그리고 예외가 여러 개일 경우에는 쉼표(,)로 구분한다.

void method() throws Exception {
	//메서드의 내용
}

이렇게 예외를 선언하면, 이 예외뿐만 아니라 그 자손타이브이 예외까지도 발생할 수 있다는 점에 주의하자. 앞서 오버라이딩에서 살펴본 것과 같이, 오버라이딩할 때는 단순히 선언된 예외의 개수가 아니라 상속관계까지 고려해야 한다.

 

매서드의 선언부에 예외를 선언함으로써 메서드를 사용하려는 사람이 메서드의 선언부를 보앗을 때, 이 메서드를 사용하기 위해서는 어떠한 예외들이 처리되어져야 하는지 쉽게 알 수 있다.

 기존의 많은 언어들에서는 메서드에 예외선언을 하지 않았기 때문에, 경험 많은 프로그래머가 아니고서는 어떤 상황에 어떤 종류의 예외가 발생할 가능성이 있는지 충분히 예측하기 힘들기 때문에 그에 대한 대비를 하는 것이 어려웠다.

 그러나 자바에서는 메서드를 작성할 때 메서드 내에서 발생할 가능성이 있는 예외를 메서드의 선언부에 명시하여 이 메서드를 사용하는 쪽에서는 이에 대한 처리를 하도록 강요하기 때문에, 프로그래머들의 짐을 덜어 주는 것은 물론이고 보다 견고한 프로그램 코드를 작성할 수 있도록 도와준다.

 

 메서드에 예외를 선언할 때 일반적으로 RuntimeException클래스들은 적지 않는다. 이 들을 메서드 선언부에 throws에 선언한다고 해서 문제가 되지는 않지만, 보통 반드시 처리해주어야 하는 예외들만 선언한다.

 치처럼 JAVA API문서를 통해 사용하고자 하는 메서드의 선언부와 Throws: 를 보고, 이 메서드에서는 어떤 예외가 발생할 수 있으며 반드시 처리해주어야 하는 예외에는 어떤 것들이 있는지 확인하는 것이 좋다.

 

public class ExceptionEx12 {
	public static void main(String[] args) throws Exception {
		method1();
	}
	static void method1() throws Exception {
		method2();
	}
	static void method2() throws Exception {
		throw new Exception();
	}
}

위의 실행결과를 보면, 프로그램의 실행도중 java.lang.Exception이 발생하여 비정상적으로 종료했다는 것과 예외가 발생했을 때 호출스택(call stack)의 내용을 알 수 있다.

 위의 결과로부터 다음과 같은 사실을 알 수 있다.

1 예외가 발생했을 때, 모두 3개의 메서드(main, method1, method2)가 호출스택에 있었으며,
2 예외가 발생한 곳은 제일 윗줄에 있는 method2()라는 것과
3 main메서드가 method1()을, 그리고 method1())은 method2()를 호출했다는 것을 알 수 있다.

위의 예제를 보면, method2()에서 'throw new Exception():'문장에 의해 예외가 강제적으로 발생했으나 try-catch문으로 예외처리를 해주지 않았으므로, method2()는 종료되면서 예외를 자신을 호출한 method1()에게 넘겨준다. 마찬가지로 main메서드에게까지 예외를 넘겨준다.

 그러나 main메서드에서도 예외처리를 해주지 않았으므로 main메서드가 종료되어 프로그램이 예외로 인해 비정상적으로 종료되는 것이다.

예외가 발생한 메서드에서 예외처리를 하지 않고 자신을 호출한 메서드에게 예외를 넘겨줄 수는 있지만, 이것으로 예외가 처리된 것은 아니고 예외를 단순히 전달만 하는 것이다. 결국 어느 한 곳에서는 반드시 try-catch문으로 예외처리를 해주어야 한다.

 

public class ExceptionEx13 {
	public static void main(String[] args) {
		method1();
	}
	static void method1() {
		try {
			throw new Exception();
		} catch (Exception e) {
			System.out.println("method1메서드에서 예외가 처리되었습니다.");
			e.printStackTrace();
		}
	}
}

예외는 처리되었지만, printStackTrace()를 통해 예외에 대한 정보를 화면에 출력하였다. 예외가 method1()에서 발생했으며, main메서드가 method1()을 호출했음을 알 수 있다.

 

 

 

 

finally블럭

finally블럭은 예외의 발생여부에 상관없이 실행되어야할 코드를 포함시킬 목적으로 사용된다. try-catch문의 끝에 자원반납을 목적(네트워크 관리)으로 선택적으로 덧붙여 사용할 수 있으며, try-catch-finally의 순서로 구성된다.

try {
	// 예외가 발생할 가능성이 있는 문장들을 넣는다.
} catch (Exception e1) {
	// 예외처리를 위한 문장을 적는다.
} finally {
	// 예외의 발생여부에 관계없이 항상 수행되어야 하는 문장들을 넣는다.
	// finally블럭은 try-catch문의 맨 마지막에 위치해야한다.
}

예외가 발생한 경우에는 try > catch > finally의 순으로 실행되고, 예외가 발생하지 않은 경우에는 try > finally의 순으로 실행된다.

 

public class FinallyTest {
	public static void main(String[] args) {
		try {
			startInstall();
			copyFiles();
			deleteTempFiles();
		} catch (Exception e) {
			e.printStackTrace();
			deleteTempFiles();
		}
	}
	
	static void startInstall() {
		/*프로그램 설치에 필요한 준비를 하는 코드를 적는다. */
	}
	static void copyFiles() {/* 파일들을 복사하는 코드를 적는다 */}
	static void deleteTempFiles() {/* 임시파일들을 삭제하는 코드를 적는다.*/}
}

startInstall(), copyFiles(), deleteTempFiles()에 주석문 이외에는 아무런 문장이 없지만, 각 메서드의 의미에 해당하는 작업을 수행하는 코드들이 작성되어 있다고 생각하자.

 

이예제의 목적은 프로그램 설치를 위한 준비를 하고 파일들을 복사하고 설치가 완료되면, 프로그램을 설치하는데 사용된 임시파일들을 삭제하는 순서로 진행된다.

프로그램의 설치과정중에 예외가 발생하더라도, 설치에 사용된 임시파일들이 삭제되도록catch블럭에 deleteTempFiles()메서드를 넣었다.

 결국 try블럭의 문장들을 수행하는 동안에(프로그램을 설치하는 과정에), 예외의 발생여부에 관계없이 deleteTempfiles()메서드는 실행되어야 하는 것이다.

이럴 때 finally블럭을 사용하면 좋다. 아래의 코드는 위의 예제를 finally블럭을 사용해서 변경한 것이며, 두 예제의 기능은 동일하다.

public class FinallyTest3 {
	public static void main(String[] args) {
		FinallyTest3.method1();
		System.out.println("method1()의 수행을 마치고 main메서드로 돌아왔습니다.");
		new RuntimeException("내가만든 unchecked exception");
	}

	static void method1() {
		try {
			System.out.println("method1()이 호출되었습니다.");
			return;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			System.out.println("method1()의 finally블럭이 실행되었습니다.");
		}
	}
}
method1()이 호출되었습니다.
method1()의 finally블럭이 실행되었습니다.
method1()의 수행을 마치고 main메서드로 돌아왔습니다.

위의 결과에서 알 수 있듯이, try블럭에서 return문이 실행되는 경우에도 finally블럭의 문장들이 먼저 실행된 후에, 현재 실행 중인 메서드를 종료한다.

 이와 마찬가지로 catch블럭의 문장 수행 중에 return문을 만나도 finally블럭의 문장들은 수행된다.

 

 

 

자동 자원 반환 try-with-resource문

JDK1.7부터 try-with-resources문이라는 try-catch문의 변형이 새로 추가되었다. 이 구문은 입출력(I/O)와 관련된 클래스를 사용할 때 유용한데, 아직 입출력에 대해 배우지 않았으므로 유용함을 느끼기는 아직 이르다.

 주로 입출력에 사용되는 클래스 중에는 사용한 후에 꼭 닫아 줘야 하는 것들이 있다. 그래야 사용했던 자원(resources)이 반환되기 때문이다.

try {
	fis = new FileInputStream("score.dat");
	dis = new DataInputStream(fis);
		...
} catch(IOException ie) {
	ie.printStackTrace();
} finally {
	try {
		if(dis != null)
			dis.close();
	}catch(IOException ie) {
		ie.printStackTrace();
	}
}

DataInputStream으로부터 데이터를 읽는 코드이다. finally블럭 안에 try-catch문을 추가해서 close()에서 발생할 수 있는 예외를 처리하도록 변경했는데, 코드가 복잡해져서 좋지않고, try블럭과 finally블럭에서 모두 예외가 발생하면, try블럭의 예외는 무시된다.

이러한 점을 개선하기 위해서 try-with-resources문이 추가된 것이다. 코드를 try-with-resources문으로 바꾸면 다음과 같다.

 

try (FileInputStream fis = new FileInputStream("score.dat");
	DataInputStream dis = new DataInputStream(fis)) {
	while(true) {
		score = dis.readInt();
		sum += score;
	}
} catch(EOFException e) {
	System.out.println("점수의 총합은 " + sum "입니다.");
} catch(IOException ie) {
	ie.printStackTrace();
}

try - with - resources문의 괄호()안에 객체를 생성하는 문장을 넣으면, 이 객체는 따로 close()를 호출하지 않아도 try블럭을 벗어나는 순간 자동적으로 close()가 호출된다. 그 다음에 catch블럭 또는 finally블럭이 수행된다.

try블럭의 괄호()안에 변수를 선언하는 것도 가능하며, 선언된 변수는 try블럭 내에서만 사용할 수 있다.

이처럼 try-with-resources문에 의해 자동으로 객체의 close()가 호출될 수 있으려면, 클래스가 AUtoCloseable이라는 인터페이스를 구현한 것이어야만 한다.

public interface AutoCloseable {
	void close() throws Exception;
}

위의 인터페이스는 각 클래스에서 적절히 자원반환작업을 하도록 구현되어 있다. 그런데, 위의 코드를 잘 보면 close()도 Exception을 발생시킬 수 있다. 만일 자동 호출된 close()에서 예외가 발생하면 어떻게 처리를 할 것인가?

public class TryWithResourceEx {
	public static void main(String[] args) {
		try (CloseableResource cr = new CloseableResource()) {
			cr.exceptionWork(false);
		} catch (WorkException e) {
			e.printStackTrace();
		} catch (CloseException e) {
			e.printStackTrace();
		}
		System.out.println();

		try (CloseableResource cr = new CloseableResource()) {
			cr.exceptionWork(true);
		} catch (WorkException e) {
			e.printStackTrace();
		} catch (CloseException e) {
			e.printStackTrace();
		}
	}
}

class CloseableResource implements AutoCloseable {
	public void exceptionWork(boolean exception) throws WorkException {
		System.out.println("exceptionWork(" + exception + "가 호출됨");

		if (exception)
			throw new WorkException("WorkException발생!!!");
	}

	public void close() throws CloseException {
		System.out.println("close()가 호출됨");
		throw new CloseException("CloseException발생!!!");
	}
}

class WorkException extends Exception {
	WorkException(String msg) {
		super(msg);
	}

}

class CloseException extends Exception {
	CloseException(String msg) {
		super(msg);
	}
}

main메서드에 두 개의 try-catch문이 있는데, 첫 번째 것은 close()에서만 예외를 발생시키고, 두 번째 것은 exception Work()와 close()에서 모두 예외를 발생시킨다.

 첫 번째는 일반적인 예외가 발생하였을 때와 같은 형태로 출력되지만, 두 번째는 출력형태가 다르다. 먼저 첫번째 exceptionWork()에서 발생한 예외에 대한 내용이 출력되고, close()에서 발생한 예외는'억제된(suppressed)'이라는 의미의 머리말과 함께 출력되었다.

 두 예외가 동시에 발생할 수는 없기 때문에, 실제 발생항 예외를 WorkException으로 하고, CloseException은 억제된 예외로 다룬다. 억제도니 예외에 대한 정보는 실제로 발생한 예외인 WorkException에 저장된다.

 Throwable에는 억제된 예외와 관련된 다음과 같은 메서드가 정의되어 있다.

void addSuppressed(Throwable exception) 억제된 예외를 추가
Throwable[] getSuppressed()				억제된 예외(배열)을 반환

만일 기존의 try-catch문을 사용했다면, 먼저 발생한 WorkException은 무시되고, 마지막으로 발생한 CloseException에 대한 내용만 출력되었을 것이다.

 

 

7-21 다음과 같이 attack메서드가 정의되어 있을 때, 이 메서드의 매개변수로 가능한 것 두 가지를 적으시오.

interface Movable {
		void move(int x, int y);
	}

	void attack(Movable f) {
		}

null, Movable인터페이스를 구현한 클래스 또는 그 자손의 인스턴스

 

 

7-22 아래는 도형을 정의한 Shape클래스이다. 이 클래스를 조상으로 하는 Circle클래스와 Rectangle클래스를 작성하시오. 이때, 생성자도 각 클래스에 맞게 적절히 추가해야 한다.

(1) 클래스명   : Circle

    조상클래스 : Shape

    멤버변수    : double r - 반지름

 

(2) 클래스명    : Rectangle

     조상클래스 : Shape

     멤버변수    : double width - 폭

                    : double height - 높이

     메서드       : 

1.  메서드명    : isSquare

    기      능    : 정사각형인지 아닌지를 알려준다.

    반환타입    : boolean

    매개변수    : 없음

abstract class Shape {
	Point p;

	Shape() {
		this(new Point(0, 0));
	}

	Shape(Point p) {
		this.p = p;
	}

	abstract double calcArea(); // 도형의 면적을 계산해서 반환하는 메서드

	Point getPosition() {
		return p;
	}

	void setPosition(Point p) {
		this.p = p;
	}
}

class Point {
	int x;
	int y;

	Point() {
		this(0, 0);
	}

	Point(int x, int y) {
		this.x = x;
		this.y = y;
	}

	public String toString() {
		return "[" + x + "," + y + "]";
	}
}

 

abstract class Shape {
	Point p;

	Shape() {
		this(new Point(0, 0));
	}

	Shape(Point p) {
		this.p = p;
	}

	abstract double calcArea(); // 도형의 면적을 계산해서 반환하는 메서드

	Point getPosition() {
		return p;
	}

	void setPosition(Point p) {
		this.p = p;
	}
}

class Rect extends Shape {
	double width;
	double height;

	Rect(double width, double height) {
		this(new Point(0, 0), width, height);
	}

	Rect(Point p, double width, double height) {
		super(p); // . 조상의 멤버는 조상의 생성자가 초기화하도록 한다
		this.width = width;
		this.height = height;
	}

	boolean isSquare() {
// width height 0 width height true . 나 가 이 아니고 와 가 같으면 를 반환한다
		return width * height != 0 && width == height;
	}

	double calcArea() {
		return width * height;
	}
}

class Circle extends Shape {
	double r; // 반지름

	Circle(double r) {
		this(new Point(0, 0), r); // Circle(Point p, double r)를 호출
	}

	Circle(Point p, double r) {
		super(p); // . 조상의 멤버는 조상의 생성자가 초기화하도록 한다
		this.r = r;
	}

	double calcArea() {
		return Math.PI * r * r;
	}
}

class Point {
	int x;
	int y;

	Point() {
		this(0, 0);
	}

	Point(int x, int y) {
		this.x = x;
		this.y = y;
	}

	public String toString() {
		return "[" + x + "," + y + "]";
	}
}

 

 

 

7-23 문제7-22에서 정의한 클래스들의 면적을 구하는 메서드를 작성하고 테스트하시오.

class JavaExercise7_23 {


	public static void main(String[] args) {
		Shape[] arr = { new Circle(5.0), new Rect(3, 4), new Circle(1) };
		System.out.println(" :" + sumArea(arr));
	}
}

 

class Exercise7_23 {
	static double sumArea(Shape[] arr) {
		double sum = 0;
		for (int i = 0; i < arr.length; i++)
			sum += arr[i].calcArea();
		return sum;
	}

	public static void main(String[] args) {
		Shape[] arr = { new Circle(5.0), new Rect(3, 4), new Circle(1) };
		System.out.println(" :" + sumArea(arr));
	}
}

 

 

 

 

7-24 다음 중 인터페이스의 장점이 아닌 것은? e

a. 표준화를 가능하게 해 준다.

b. 서로 관계없는 클래스들에게 관계를 맺어줄 수 있다/

c. 독립적인 프로그래밍이 가능하다.

d. 다중 상속을 가능하게 해 준다.

e. 패키 지간의 연결을 도와준다

 

 

 

7-25 Outer클래스의 내부 클래스 Inner의 멤버 변수 iv의 값을 출력하시오.

class Outer { // 외부 클래스
	class Inner { // ( ) 내부 클래스 인스턴스 클래스
		int iv = 100;
	}
}
class JavaExercise7_25 {
	public static void main(String[] args) {
	}
}

 

class Outer { // 외부 클래스
	class Inner { // ( ) 내부 클래스 인스턴스 클래스
		int iv = 100;
	}
}
class JavaExercise7_25 {
	public static void main(String[] args) {
		Outer o = new Outer();
		Outer.Inner ii = o.new Inner();
		System.out.println(ii.iv);
	}
}
100

 

7-26 Outer클래스의 내부 클래스 Inner의 멤버변수 iv의 값을 구하시오.

class Outer { // 외부 클래스
	static class Inner { // (static ) 내부 클래스 클래스
		int iv = 200;
	}
}

class JavaExercise7_26 {
	public static void main(String[] args) {
	}
}

 

 

class Outer { // 외부 클래스
	static class Inner { // (static ) 내부 클래스 클래스
		int iv = 200;
	}
}
class JavaExercise7_26 {
	public static void main(String[] args) {
		Outer.Inner ii = new Outer.Inner();
		System.out.println(ii.iv);
	}
}

 

 

 

 

7-27 다음과 같은 실행혈과를 얻도록 (1)~(4)의 코드를 완성하시오.

class Outer {
	int value = 10;

	class Inner {
		int value = 20;

		void method1() {
			int value = 30;
			System.out.println(/* (1) */);
			System.out.println(/* (2) */);
			System.out.println(/* (3) */);
		}
	} // Inner클래스의 끝
} // Outer클래스의 끝

class JavaExercise7_27 {
	public static void main(String args[]) {
		/*
		 * (4) . 알맞은 코드를 넣어 완성하시오
		 */
		inner.method1();
	}
}
30
20
10

 

 

 

 

class Outer {
	int value = 10; // Outer.this.value

	class Inner { // (instance inner class) 인스턴스 클래스
		int value = 20; // this.value

		void method1() {
			int value = 30; // value
			System.out.println(value);
			System.out.println(this.value);
			System.out.println(Outer.this.value);
		}
	} // Inner클래스의 끝
} // Outer클래스의 끝

class JavaExercise7_27 {
	public static void main(String args[]) {
		Outer outer = new Outer();
		Outer.Inner inner = outer.new Inner();
		inner.method1();
	}
}
30
20
10

 

 

 

 

7-28 아래의 EventHandler를 익명 클래스 (anonymous class)로 변경하시오.

import java.awt.*;
import java.awt.event.*;

class JavaExercise7_28 {
	public static void main(String[] args) {
		Frame f = new Frame();
		f.addWindowListener(new EventHandler());
	}
}
class EventHandler extends WindowAdapter {
	public void windowClosing(WindowEvent e) {
		e.getWindow().setVisible(false);
		e.getWindow().dispose();
		System.exit(0);
	}
}

 

 

 

import java.awt.*;
import java.awt.event.*;

class JavaExercise7_28 {
	public static void main(String[] args) {
		Frame f = new Frame();
		f.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				e.getWindow().setVisible(false);
				e.getWindow().dispose();
				System.exit(0);
			}
		});
	} // main
}

 

 

 

 

7-29 지역 클래스에서 외부 클래스의 인스턴스 멤버와 static멤버에 모두 접근할 수 있지만, 지역변수는 final이 붙은 상수만 접근할 수 있는 이유가 무엇인가?

 

메서드가 수행을 마쳐서 지역변수가 소멸된 시점에도, 지역 클래스의 인스턴스가 소멸된 지역변수를 참조하려는 경우가 발생할 수 있기 때문이다.

7-11 문제 7-10에서 작성한 MyTv2 클래스에 이전 채널(previous channel)로 이동하는 기능의 메서드를 추가해서 실행결과와 같은 결과를 얻도록 하시오.

이전 채널의 값을 저장할 멤버변수를 정의하라.

 

메서드명 : gotoPrevChannel

기     능 : 현재 채널을 이전 채널로 변경한다.

반환 타입 : 없음

매개변수 : 없음

class MyTv2 {
	boolean isPowerOn;
	int channel;
	int volume;
	int prechannel;
	final int MAX_VOLUME = 100;
	final int MIN_VOLUME = 0;
	final int MAX_CHANNEL = 100;
	final int MIN_CHANNEL = 1;

	public void setVolume(int volume) {
		if (volume > MAX_VOLUME || volume < MIN_VOLUME)
			return;
		this.volume = volume;
		
	}

	public int getVolume() {
		return volume;
	}

	public void setChannel(int channel) {
		if (channel > MAX_CHANNEL || channel < MIN_CHANNEL)
			return;
		prechannel = this.channel;
		this.channel = channel;
	}

	public int getChannel() {
		return channel;
	}
	
	public void gotoPrevChannel() {
		setChannel(prechannel);
	}
	
}

class ExerciseEx7_11 {
	public static void main(String args[]) {
		MyTv2 t = new MyTv2();
		t.setChannel(10);
		System.out.println("CH:"+t.getChannel());
		t.setChannel(20);
		System.out.println("CH:"+t.getChannel());
		t.gotoPrevChannel();
		System.out.println("CH:"+t.getChannel());
		t.gotoPrevChannel();
		System.out.println("CH:"+t.getChannel());

	}
}

 

 

 

7-12 다음 중 접근 제어자에 대한 설명으로 옳지 않은 것은?(모두 고르시오) c

a. public은 접근 제한이 전혀 없는 접근 제어 자이다.

b. (default)가 붙으면, 같은 패키지 내에서만 접근이 가능하다.

c. 지역변수에도 접근제어자를 사용할 수 있다.

d. protect가 붙으면, 같은 패키지 내에서도 접근이 가능하다.

e. protected가 붙으면, 다른 패키지의 자손 클래스에서 접근이 가능하다.

 

c. 지역변수에는 접근제어자를 사용할 수 없다.

 

 

 

7-13 Math클래스의 생성자는 접근 제어자가 private이다. 그 이유는 무엇인가?

Math클래스의 모든 메서드가 static메서드이고 인스턴스 변수가 존재하지 않기 때문에 객체를 생성할 필요가 없기 때문이다.

 

 

 

7-14 문제 7-1에 나오는 섰다 카드의 숫자와 종류(isKwang)는 사실 한번 값이 지정되면 변경되어서는 안 되는 값이다. 카드 숫자가 한번 잘못 바뀌면 똑같은 카드가 두장이 될 수도 있기 때문이다. 이러한 문제점이 발생하지 않도록 아래의 SutdaCard를 수정하시오.

class SutdaCard {
	final int num;
	final boolean isKwang;

	SutdaCard() {
		this(1, true);
	}

	SutdaCard(int num, boolean isKwang) {
		this.num = num;
		this.isKwang = isKwang;
	}

	public String toString() {
		return num + (isKwang ? "K" : "");
	}
}

class Exercise7_14 {
	public static void main(String args[]) {
		SutdaCard card = new SutdaCard(1, true);
	}
}

 

 

 

 

7-15 클래스가 다음과 같이 정의되어 있을 때, 형 변환을 올바르게 하지 않은 것은? e

	class Unit {}
	class AirUnit extends Unit {}
	class GroundUnit extends Unit {}
	class Tank extends GroundUnit {}
	class AirCraft extends AirUnit {}
	Unit u = new GroundUnit();
	Tank t = new Tank();
	AirCraft ac = new AirCraft();

a. u = (Unit) ac;

b. u = ac;

c. GroundUnit gu = (GroundUnit) u;

d. AirUnit au = ac;

e. t = (Tank) u;

f. GroundUnit gu = t;

 

e. 조상 타입의 인스턴스를 자손 타입으로 형 변환할 수 없다.

 

 

7-16 다음 중 연산 결과가 true가 아닌 것은? (모두 고르시오) e

	class Car {}
	class FireEngine extends Car implements Movable {}
	class Ambulance extends Car {}
	FireEngine fe = new FireEngine()

a. fe instanceof FireEngine

b. fe instanceof Movable

c. fe instanceof Object

d. fe instanceof Car

e. fe instanceof Ambulance

 

e Abulance는 FireEngine과 아무 관계도 없다.

 

 

7-17 아래 세 개의 클래스로부터 공통부분을 뽑아서 Unit이라는 클래스를 만들고, 이 클래스를 상속받도록 코드를 변경하시오.

class Marine { // 보병
	int x, y; // 현재 위치
	void move(int x, int y) { /* */ } //지정된 위치로 이동
	void stop() { /* */ } //현재 위치에 정지
	void stimPack() { /* .*/} //스팀팩을 사용한다
}
class Tank { // 탱크
	int x, y; // 현재 위치
	void move(int x, int y) { /* */ } //지정된 위치로 이동
	void stop() { /* */ } //현재 위치에 정지
	void changeMode() { /* . */} //공격모드를 변환한다
}
class Dropship { // 수송선
	int x, y; // 현재 위치
	void move(int x, int y) { /* */ }// 지정된 위치로 이동
	void stop() { /* */ } //현재 위치에 정지
	void load() { /* .*/ } //선택된 대상을 태운다
	void unload() { /* .*/ } //선택된 대상을 내린다
}
public class JavaExercise7_17 {
		abstract class Unit {
		int x, y;
		abstract void move(int x, int y);
		void stop() { /* */ }	
	
	class Marine extends Unit{ // 보병
		void move(int x, int y) { }
		void stimPack() { /* .*/}
		}
		class Tank extends Unit{ // 탱크
		void move(int x, int y) { }
		void changeMode() { /* . */} 
		}
		class Dropship extends Unit{ // 수송선
		void move(int x, int y) { }
		void load() { /* .*/ } 
		void unload() { /* .*/ } 
		}
	}
}

 

 

 

7-18 다음과 같은 실행결과를 얻도록 코드를 완성하시오.

메서드명 : action

기     능 : 주어진 객체의 메서드를 호출한다.

              DanceRobot인 경우, dance()를 호출하고,

              SingleRobot인 경우, sing()를 호출하고,

              DrawRobot인 경우, draw()를 호출한다.

반환 타입 : 없음

매개변수 : Robot r - Robot인스턴스 또는 Robot의 자손 인스턴스

public class JavaExercise7_18 {
	public static void main(String[] args) {
		Robot[] arr = { new DanceRobot(), new SingRobot(), new DrawRobot() };
		for (int i = 0; i < arr.length; i++)
			action(arr[i]);
	} // main
}

class Robot {
}

class DanceRobot extends Robot {
	void dance() {
		System.out.println("춤을 춥니다");
	}
}

class SingRobot extends Robot {
	void sing() {
		System.out.println("노래를 합니다");
	}
}

class DrawRobot extends Robot {
	void draw() {
		System.out.println("그림을 그립니다");
	}
}
춤을 춥니다
노래를 합니다
그림을 그립니다

 

 

 

public class JavaExercise7_18 {
	public static void action(Robot r) {
		if (r instanceof DanceRobot) {
			DanceRobot dr = (DanceRobot) r;
			dr.dance();
		} else if (r instanceof SingRobot) {
			SingRobot sr = (SingRobot) r;
			sr.sing();
		} else if (r instanceof DrawRobot) {
			DrawRobot dr = (DrawRobot) r;
			dr.draw();

		}

	}

	public static void main(String[] args) {
		Robot[] arr = { new DanceRobot(), new SingRobot(), new DrawRobot() };
		for (int i = 0; i < arr.length; i++)
			action(arr[i]);
	} // main
}

class Robot {
}

class DanceRobot extends Robot {
	void dance() {
		System.out.println("춤을 춥니다");
	}
}

class SingRobot extends Robot {
	void sing() {
		System.out.println("노래를 합니다");
	}
}

class DrawRobot extends Robot {
	void draw() {
		System.out.println("그림을 그립니다");
	}
}
춤을 춥니다
노래를 합니다
그림을 그립니다

 

 

 

7-19 다음은 물건을 구입하는 사람을 정의한 BUyer클래스이다. 이 클래스는 멤버 변수로 돈(money)과 장 바위나(cart)를 가지고 있다. 제품을 구입하는 기능의 buy메서드와 장바구니에 구입한 물건을 추가하는 add메서드, 구입한 물건의 목록과 사용금액, 그리고 남은 금액을 출력하는 summary메서드를 완성하시오

 

1. 메서드명 : buy

   기      능 : 지정된 물건을 구입한다. 가진 돈(money)에서 물건의 가격을 빼고, 장바구니(cart)에 넣는다.

                 만일 가진 돈이 물건의 가격보다 적다면 바로 종료한다.

   반환 타입 : 없음

   매개변수 : Product p - 구입할 물건

 

2. 메서드명 : add

   기      능 : 지정된 물건을 장바구니에 담는다.

                 만일 지정된 장바구니에 담을 공간이 없으면, 장바구니의 크기를 2배로 늘린 다음에 담는다.

   반환타입 : 없음

   매개변수 : Product p - 구입한 물건

 

3. 메서드명 : summary

   기      능 : 구입한 물건의 목록과 사용금액, 남은 금액을 출력한다.

   반환타입 : 없음

   매개변수 : 없음

class Exercise7_19 {
	public static void main(String args[]) {
		Buyer b = new Buyer();
		b.buy(new Tv());
		b.buy(new Computer());
		b.buy(new Tv());
		b.buy(new Audio());
		b.buy(new Computer());
		b.buy(new Computer());
		b.buy(new Computer());
		b.summary();
	}
}

class Buyer {
	int money = 1000;
	Product[] cart = new Product[3]; // 구입한 제품을 저장하기 위한 배열
int i = 0; // Product cart index 배열 에 사용될

void buy(Product p) {
// 1.1 . 가진 돈과 물건의 가격을 비교해서 가진 돈이 적으면 메서드를 종료한다
if(money < p.price) {
System.out.println(" "+ p +" / ."); 잔액이 부족하여 을 를 살수 없습니다
return;
}
잔액이 부족하여 을 를 살수 없습니다 Computer / .
구입한 물건:Tv,Computer,Tv,Audio,Computer,Computer,
사용한 금액:850
남은 금액:150

 

 

 

class Exercise7_19 {
	public static void main(String args[]) {
		Buyer b = new Buyer();
		b.buy(new Tv());
		b.buy(new Computer());
		b.buy(new Tv());
		b.buy(new Audio());
		b.buy(new Computer());
		b.buy(new Computer());
		b.buy(new Computer());
		b.summary();
	}
}

class Buyer {
	int money = 1000;
	Product[] cart = new Product[3]; // 구입한 제품을 저장하기 위한 배열
	int i = 0; // Product cart index 배열 에 사용될

	void buy(Product p) {
		if (money < p.price)
			return;
		else if (true) {
			money -= p.price;
			add(p);
		}
		cart[i++] = p;
	}

	void add(Product p) {
		if (i >= cart.length) {
			Product[] tmp = new Product[cart.length * 2];
			System.arraycopy(cart, 0, tmp, 0, cart.length);
			cart = tmp;
		}
	}

	void summary() {
		String itemList = "";
		int sum = 0;
		for (int i = 0; i < cart.length; i++) {
			if (cart[i] == null)
				break;
			itemList += cart[i] + ",";
			sum += cart[i].price;
		}
		System.out.println(" :" + itemList);
		System.out.println(" :" + sum);
		System.out.println(" :" + money);
	} 
}

class Product {
	int price; // 제품의 가격

	Product(int price) {
		this.price = price;
	}
}

class Tv extends Product {
	Tv() {
		super(100);
	}

	public String toString() {
		return "Tv";
	}
}

class Computer extends Product {
	Computer() {
		super(200);
	}

	public String toString() {
		return "Computer";
	}
}

class Audio extends Product {
	Audio() {
		super(50);
	}

	public String toString() {
		return "Audio";
	}
}

 

 

 

 

 

7-20 다음의 코드를 실행한 결과를 적으시오.

class Exercise7_20 {
	public static void main(String[] args) {
		Parent p = new Child();
		Child c = new Child();
		System.out.println("p.x = " + p.x);
		p.method();
		System.out.println("c.x = " + c.x);
		c.method();
	}
}

class Parent {
	int x = 100;

	void method() {
		System.out.println("Parent Method");
	}
}

class Child extends Parent {
	int x = 200;

	void method() {
		System.out.println("Child Method");
	}
}
p.x = 100
Child Method
c.x = 200
Child Method

ANSI C, ANSI 99

안시는 오라클을 사용할 때 사용하는용어이다

ANSI C, ISO C, 표준 C(Standard C)는 미국 국립 표준 협회(ANSI)와 국제 표준화 기구(ISO)가 출판한 C 프로그래밍 언어의 이후 표준들을 가리킨다. 역사적으로 이 이름들은 오리지널의 가장 잘 지원되는 버전의 표준(C89 또는 C90)을 가리켰다. C로 개발하는 소프트웨어 개발자들은 표준을 따르는 것을 권고받으며 그렇게 함으로써 컴파일러 간 이식에 도움을 줄 수 있다.

 

 

유스 케이스 다이어그램

유스 케이스 다이어그램(use case diagram)은 사용자, 그리고 사용자가 수반한 다른 유스 케이스(UML의 행위자(액터)와 액터가 요구하여 시스템이 수행하는 일의 목표이다.) 간의 관계를 보여주는 사용자-시스템 간 상호작용의 표현이다. 유스 케이스 다이어그램은 각기 다른 종류의 시스템 사용자와 각기 다른 유스 케이스를 식별할 수 있으며 다른 유형의 다이어그램이 수반되기도 한다. 유스 케이스는 원이나 타원으로 표현된다.

 

 

데이터베이스 정규화

관계형 데이터베이스의 설계에서 중복을 최소화하게 데이터를 구조화하는 프로세스를 정규화(Normalization)라고 한다. 데이터베이스 정규화의 목표는 이상이 있는 관계를 재구성하여 작고 잘 조직된 관계를 생성하는 것에 있다. 일반적으로 정규화란 크고, 제대로 조직되지 않은 테이블들과 관계들을 작고 잘 조직된 테이블과 관계들로 나누는 것을 포함한다. 정규화의 목적은 하나의 테이블에서의 데이터의 삽입, 삭제, 변경이 정의된 관계들로 인하여 데이터베이스의 나머지 부분들로 전파되게 하는 것이다.

관계형 모델의 발견자인 에드거 F. 커드는 1970년에 제 1 정규화(1NF)로 알려진 정규화의 개념을 도입하였다.[1] 에드거 F. 커드는 이어서 제 2 정규화(2NF)와 제 3 정규화(3NF)를 1971년에 정의하였으며,[2] 1974년에는 레이먼드 F. 보이스와 함께 보이스-코드 정규화(BCNF)를 정의하였다.[3] 4NF 이상의 정규화는 이후에 다른 이론가들에 의해서 정의되었으며, 가장 최근에 소개된 정규화는 2002년에 크리스토퍼 J. 데이트, 허그 다위, 니코스 로렌츠에 의해 소개된 제 6 정규화(6NF)이다.[4]

비공식적으로 관계형 데이터베이스 테이블(컴퓨터 공학적 표현으로는 관계)이 제 3 정규(3NF)화가 되었으면 정규화 되었다 라고 한다.[5] 3NF 테이블의 대부분이 삽입, 변경, 삭제 이상이 없으며, 3NF 테이블의 대부분이 BCNF, 4NF, 5NF이다.(그러나 일반적으로 6NF는 아니다.)

데이터베이스 디자인 표준 가이드는 데이터베이스가 완전히 정규화되게 디자인되어야 한다; 그 뒤에 일부가 성능상의 이유로 비정규화될 수는 있다.[6] 그러나, 데이터 웨어하우스 디자인을 위한 관점 모델링과 같은 일부 모델링 규칙에서는 예외적으로 비 정규화된 디자인을 추천한다. 즉 대규모 부분에서의 디자인은 3NF가 아니다.

 

 

 

개체-관계 모델(ERD)

데이터 모델링 분야에서 개체-관계 모델이란 구조화된 데이터에 대한 일련의 표현이다.

서로 관계된 두 개의 엔티티

"구조"화된 데이터를 저장하기 위해 데이터베이스를 쓴다. 이 데이터의 "구조" 및 그에 수반한 제약 조건들은 다양한 기법에 의해 설계될 수 있다. 그 기법 중 하나가 개체-관계 모델링(Entity-Relationship Modelling)이다. 줄여서 ERM이라고 한다. ERM 프로세스의 산출물을 가리켜 개체-관계 다이어그램(Entity-Relationship Diagram)이라 한다. 줄여서 ERD라 일컫는다. 데이터 모델링 과정은 데이터 모델을 그림으로 표현하기 위해 표시법을 필요로 한다. 

 

 

 

부하분산(로드벨런싱)

하분산 또는 로드 밸런싱(load balancing)[1]은 컴퓨터 네트워크 기술의 일종으로 둘 혹은 셋이상의 중앙처리장치 혹은 저장장치와 같은 컴퓨터 자원들에게 작업을 나누는 것을 의미한다. 이로써 가용성 및 응답시간을 최적화 시킬 수 있다. 예를 들어, 메인프레임 1대(단일 구성체) 보다 IA-32와 같은 일반적인 서버(복합 구성체)가 안정성 면에서 유리한 위치에 있다. 부하분산 서비스는 그에 적합한 하드웨어와 소프트웨어에 의해 제공된다. 이 기술은 보통 내부 네트워크를 이용한 병렬처리(특히, 고가용성의 병렬처리)에 사용된다.

부하분산을 위한 대부분의 응용 프로그램은 다수의 서버(다른 말로, 서버 팜)를 가지고 한 가지 종류의 인터넷 서비스를 지원하는 방식이다. 보통 부하 분산은 트래픽이 많은 웹 사이트, IRC 네트워크, FTP 사이트, NNTP 서버 그리고 DNS서버에 적용이 되고 있다.

인터넷 서비스를 위해서는 소프트웨어를 이용한 부하분산이 적용되며, 이 소프트웨어는 중간에 위치에 실제 서비스하는 서버와 클라이언트를 포트를 이용해 중개하고 있다. 그러나 사용자는 이를 알아차리지 못한다. 이를 투명성이라한다.

또한, 보안이라는 측면에서 내부 네트워크 구조를 숨김으로서 크래킹을 막을 수 있다.

일부 부하분산 소프트웨어는 실서비스 서버들을 관리하는 역할을 수행하기도 한다. (예를 들어, 서버 다운 혹은 백업에 관련된 작업과 같은)

부하분산의 다른 방식으로는 Round Robin DNS 라고 하는 특별한 하드웨어 및 소프트웨어가 필요가 없는 방식이 있다. 이 방식에서는 여러 개의 IP주소를 동일한 도메인 네임에 연관지어 놓고 클라이언트들이 어떤 서버를 사용할 것인지 결정하게 하는 방식이다. 일반적인 부하분산과는 다르게 "투명성"이 존재하지 않는다. 왜냐하면 이미 내부의 서버들의 주소가 이미 노출되어 있기 때문이다.

이 방식은 장단점이 혼재되어 있다. DNS서버에 대한 의존도가 높고 부하분산이 원하는 대로 될 수 있다는 것이다.

 

 

 

OSI 모형

OSI 모형(Open Systems Interconnection Reference Model)은 국제표준화기구(ISO)에서 개발한 모델로, 컴퓨터 네트워크 프로토콜 디자인과 통신을 계층으로 나누어 설명한 것이다. 일반적으로 OSI 7 계층이라고 한다.

 

 

 

스키마

스키마(schema)는 계획이나 도식(圖式)을 가리키는 영어 낱말로, 다음을 가리킨다. 참고로 스킴(scheme)은 스키마와 거의 같은 의미로 쓰이나, 보통 스키마가 대략적인 계획이나 도식을 뜻하는 데 비해 스킴은 구체적이고 확정된 것을 말한다.

  • 데이터베이스 스키마는 자료를 저장하는 구조와 표현법을 정의한 것을 뜻하는 전산학 용어이다.
  • XML 스키마 XML 문서의 내용, 구조, 형식을 규정하는 명세(明細)로, 그 서술 자체를 XML로 한다.
  • 선험적 도식(先驗的圖式) 또는 스키마(schema)는 칸트 철학에서 유래한 철학 용어이다.
  • 스키마(schema, 도식)는 인공지능, 인지과학, 언어학 등에서 공통으로 사용하는 개념으로 지식을 표상하는 구조를 말한다. 스키마라는 용어는 영국의 바틀렛(Bartlett, 1932)에 의해 심리학에서 처음 사용되었고, 스위스의 장 피아제(Jean Piaget)도 지식이 지식 구조인 스키마로 형성되어 있다고 생각했다. 이들의 관념은 미국의 인지심리학 연구에 큰 영향을 미쳤다. 인공지능에 대한 연구도 스키마 이론의 발달에 기여한 바가 크다. 오늘날의 심리학자들은 스키마를 골격 구조와 같은 것으로 생각하고 있다. 그리고 스키마라는 지식 표상 구조는 경험의 구체적인 속성을 조직하는 데 필요한 틀로 작용한다는 것이 인지심리학자들의 생각이다. 스키마 이론은 지식이 조직되는 방식을 다루는 대표적 이론으로, 인공지능학자인 민스키(Minsky)와 인지심리학자 러멜하트(Rumelhart) 등이 대표적인 연구자이다. 민스키는 스키마를 '프레임(frame)'이라고 부른다. 러멜하트는 스키마를 '기억에 저장된 개념을 나타내기 위한 데이터 구조'라고 정의하며, 앤더슨은 스키마를 '추상적인 지식 구조'로 정의한다. 메딘과 러스는 스키마를 '이해하는 데 사용되는 일반적인 지식 구조'라고 정의한다.

 

 

HTTP 상태 코드

아래는 HTTP(하이퍼텍스트 전송 프로토콜) 응답 상태 코드의 목록이다.

IANA가 현재 공식 HTTP 상태 코드 레지스트리를 관리하고 있다.

모든 HTTP 응답 코드는 5개의 클래스(분류)로 구분된다. 상태 코드의 첫 번째 숫자는 응답의 클래스를 정의한다. 마지막 두 자리는 클래스나 분류 역할을 하지 않는다. 첫자리에 대한 5가지 값들은 다음과 같다.

  • 1xx (정보): 요청을 받았으며 프로세스를 계속한다
  • 2xx (성공): 요청을 성공적으로 받았으며 인식했고 수용하였다
  • 3xx (리다이렉션): 요청 완료를 위해 추가 작업 조치가 필요하다
  • 4xx (클라이언트 오류): 요청의 문법이 잘못되었거나 요청을 처리할 수 없다
  • 5xx (서버 오류): 서버가 명백히 유효한 요청에 대해 충족을 실패했다

 

출처 : 위키백과

'팀프로젝트 지식 > 용어' 카테고리의 다른 글

전사적 자원 관리ERP  (0) 2021.07.22

객체를 컴퓨터에 저장했다가 꺼내쓰는것과 컴퓨터간에 서로 객체를 주고받을 수 있게 해 주는것을 직렬화를 통해 가능하게한다.

 

직렬화(serialization)란 객체를 데이터 스트림으로 만드는 것을 뜻한다. 객체에 저장된 데이터를 스트림에 쓰기(write)위해 연속적인(serial) 데이터로 변환하는 것을 말한다. 반대로 스트림으로부터 데이터를 읽어서 객체를 만드는 것을 역직렬화(deserialization)이라고 한다.

객체는 클래스에 정의된 인스턴스변수의 집합이다. 객체는 클래스변수나 메서드가 포함되지 않는다. 객체는 오직 인스턴스변수들로만 구성되어 있다. 인스턴스변수는 인스턴스마다 다른 값을 가질 수 있어야하기 때문에 별도의 메모리공간이 필요하지만 메서드는 변하는 것이 아니라 인스턴스마다 같은 내용의 코드를 포함시킬 이유는 없다.

객체를 저장한다는 것은 바로 객체의 모든 인스턴스변수의 값을 저장한다는 것이다. 어떤 객체를 저장하고자 한다면, 현재 객체의 모든 인스턴스 변수의값을 저장하기만 하면 된다. 그리고 저장했던 객체를 다시 생성하려면, 객체를 생성한 후에 저장했던 값을 읽어서 생성한 객체의 인스턴스변수에 저장하면 되는 것이다.

클래스에 정의된 인스턴스변수가 단순히 기본형일 때는 인스턴스변수의 값을 저장하는 일이 간단하지만, 인스턴스변수의 타입이 참조형 일 때는 그리 간단하지 않다. 그러나 우리에게는 직렬화/역직렬화를 할 수 있는 ObjectInputStream/ObjectOutputStream을 사용하는 방법만 알면된다.

두 객체가 동일한지 판단하는 기준이 두 객체의 인스턴스변수의 값들이 같고 다름이라는 것을 기억하자.

 

 

 

ObjectInputStream, ObjectOutputStream

직렬화(스트림에 객체를 출력)에는 ObjectOutputStream을 사용하고 역직렬화(스트림으로부터 객체를 입력)에는 ObjectInputStream을 사용한다.

ObjectInputStream과 ObjectOutputStream은 각각 InputStream과 OutputStream을 직접 상속받지만 기반스트림을 필요로하는 보조스트림이다. 그래서 객체를 생성할 때 입출력(직렬화/역직렬화)할 스트림을 지정해 주어야 한다.

ObjectInputStream(InputStream in)
ObjectOutputStream(OutputStream out)

만일 파일에 객체를 저장(직렬화)하고 싶다면 다음과 같이 하면 된다.

FileOutputStream fos = new FileOutputStream("objectfile.ser");
ObjectOutputStream out = new ObjectOutputStream(fos);
out.writeObject(new UserInfo());

위의 코드는 objectfile.ser이라는 파일에 UserInfo객체를 직렬화하여 저장한다. 출력할 스트림(FileOutputStream)을 생성해서 이를 기반스트림으로하는 ObjectOutputStream을 생성한다.

ObjectOutputStream의 writeObject(Object obj)를 사용해서 객체를 출력하면, 객체가 파일에 직렬화되어 저장된다.

역직렬화 방법은 입력스트림을 사용하고 wrieteObject(Object obj)대신 readObject()이기 때문에 객체 원래의 타입으로 형변환 해주어야 한다.

ObjectInputStream과 ObjectOutputStream에는 readObject()와 writeObject()이외에도 여러 가지 타입과 값을 입출력할 수 있는 메서드를 제공한다.

ObjectInputStream ObjectOutputStream
void
int
int
boolean
byte
char
double
float
int
long
short
Object
int
int
Object
string
defaultReadObject()
read()
read(byte[]buf, int off, int len)
readboolean()
readByte()
readChar()
readDouble()
readFloat()
readInt()
readLong()
readShort()
readObject()
readUnsignedByte()
readUnsignedShort()
readUnshared()
readUTF()
void defaultWriteObject
void write(byte[] buf)
void write(byte[] buf, int off, int len)
void write(int val)
void writeBoolean(boolean val)
void writeByte(int val)
void writeBytes(String str)
void writeChar(int val)
void writeChars(String str)
void writeDouble(double val)
void writeFloat(float val)
void writeInt(int val)
void writeLong(long val)
void writeObject(Object obj)
void writeShort(int val)
void writeUnshared(Object obj)
void write UTF(String str)

이 메서드들은 직렬화와 역직렬화를 직접 구현할 때 주로 사용되며, defaultReadObject(0와 defaultWriteObject()는 자동 직렬화를 수행한다. 객체를 직렬화/역직렬화하는 작업은 객체의 모든 인스턴스변수가 참조하고 있는 모든 객체에 대한 것이기 때문에 상당히 복잡하며 시간도 오래 걸린다. readObject()와 writeObject()를 사용한 자동 직렬화가 편리하기는 하지만 직렬화 작업시간을 단축시키려면 직렬화하고자 하는 객체의 클래스에 추가적으로 다음과 같은 2개의 메서드를 직접 구현해주어야 한다. 

private void writeObject(ObjectOutputStream out)
	throws IOException {
	}
private void readObject(ObjectInputStream in)
	throws IOException, ClassNotFoundExceaption{
    }

 

 

 

직렬화가 가능한 클래스 만들기 - Serializable, transient

직렬화가 가능한 클래스를 만드는 방법은 간단하다. 직렬화하고자 하는 클래스가 java.io.Serializable인터페이스를 구현하도록 하면 된다.

 예를 들어 왼쪽과 같이 UserInfo라는 클래스가 있을 때, 이 클래스를 직렬화가 가능하도록 변경하려면 오른쪽과 같이 Serializable인터페이스를 구현하도록 변경하면 된다.

public class UserInfo {
	String name;
	String password;
	int age;
}
public class UserInfo
	implements java.io.Serializable {
		String name;
		String password;
		int age;
}

Serializable 인터페이스는 아무런 내요도 없는 빈 인터페이스이지만, 직렬화를 고려하여 작성한 클래스인지를 판단하는 기준이 된다.

public interface Serialzable{ }

아래와 같이 Serializable을 구현한 클래스를 상속받는다면, Serializable을 구현하지 않아도 된다. UserInfo는 Serializable을 구현하지 않았지만 조상인 SuperUserInfo가 Serializable를 구현하였으므로 UserInfo역시 직렬화가 가능하다.

public class SuperUserInfo implement Serializable {
	String name;
	String password;
}
public class UserInfo extends SuperUserInfo{
	int age;
}

위의 경우 UserInfo객체를 직렬화하면 조상인 SuperUserInfo에 정의된 인스턴스변수name, password도 함께 직렬화된다.

 

그러나 조상클래스가 Serializable을 구현하지 않았다면 자손클래스를 직렬화할 때 조상클래스에 정의된 인스턴스변수 name과 password는 직렬화 대상에서 제외된다.

public class SuperUserInfo {
	String name;
	String password;
}
public class UserInfo extends SuperUserInfo implements Serializable {
	int age;
}

조상클래스에 정의된 인스턴스변수 name과 password를 직렬화 대상에 포함시키기 위해서는 조상클래스가 Serializable을 구현하도록 하던가, UserIInfo에서 조상의 인스턴스변수들이 직렬화되도록 처리하는 코드를 직접 추가해 주어야 한다. 

public class UserInfo implements Serializable {
	String name;
	String password;
	int age;
	Object obj = new Object(); // Object객체는 직렬화할 수 없다.
}

이 경우에는 직렬화 될 수 없다.

public class UserInfo implements Serializable {
	String name;
	String password;
	int age;
	Object obj = new String("abc");	// String은 직렬화될 수 없다.
}

인스턴스변수 obj의 타입이 직렬화가 안 되는 Objct이긴 하지만 실제로 저장된 객체는 직렬화가 가능한 String인스턴스이기 때문에 직렬화가 가능하다. 

 

직렬화하고자 하는 객체의 클래스에 직렬화가 안 되는 객체에 대한 참조를 포함하고 있다면, 제어자 transient를 붙여서 직렬화 대상에서 제외되도록 할 수 있다.

 또는 password와 같이 보안상 직렬화되면 안 되는 값에 대해서 transient를 사용할 수 있다. 다르게 표현하면 transient가 붙은 인스턴스변수의 값은 그 타입의 기본값으로 직렬화된다고 볼 수 있다.

즉, UserInfo객체를 역직렬화하면 참조변수인 obj와 password의 값은 null이 된다.

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

class SuperUserInfo{
	String name;
	String password;
	
	public SuperUserInfo(){
		this("Unknown", "1111");
	}
		
	public SuperUserInfo(String name, String password){
		this.name = name;
		this.password = password;
	}
}

public class UserInfo2 extends SuperUserInfo implements Serializable{
	/**
	 * 
	 */
	private static final long serialVersionUID = -7739307153548748307L;
	int age;
	String addr;
	
	public UserInfo2() {
		this("Unknown", "1111",0);
	}
	public UserInfo2(String name, String password, int age) {
		super(name, password);
		this.age = age;
	}
	@Override
	public String toString() {
		return "UserInfo2 [age=" + age + ", name=" + name + ", password=" + password + "]";
	}
	
	private void writeObject(ObjectOutputStream oos) throws IOException{
		oos.writeUTF(name);
		oos.writeUTF(password);
		oos.defaultWriteObject();
	}
	private void readObject(ObjectInputStream ois) throws Exception {
		name = ois.readUTF();
		password = ois.readUTF();
		ois.defaultReadObject();
	}
	public static void main(String[] args) throws Exception {
		
		List<UserInfo2> list = new ArrayList<UserInfo2>();
		list.add(new UserInfo2("1길동", "1111", 10));
		list.add(new UserInfo2("2길동", "1212", 20));
		
		new ObjectOutputStream(new FileOutputStream("abcd.ser")).writeObject(list);
		
		List<UserInfo2> list2 = (List<UserInfo2>) new ObjectInputStream(new FileInputStream("abcd.ser")).readObject();
		
		list2.forEach(System.out::println);
	}
}

아래는writeObject()와 readObject()를 추가해서 조상으로부터 상속받은 인스턴스변수인 name과 password가 직접 직렬화되도록 해야 한다. 이 메서드들은 직렬화/역직렬화 작업시에 자동적으로 호출된다.

 

 

 

직렬화가능한 클래스의 버전관리

 

직렬화된 객체를 역직렬화할 때는 직렬화 했을 때와 같은 클래스를 사용해야한다. 그러나 클래스의 이름이 같더라도 클래스의 내용이 변경된 경우 역직렬화는 실패한다.

역직렬화를 이용해 클래스의 버전을 비교함으로써 직렬화할 때의 클래스 버전과 일치하는지 확인할 수 있다. 그러나 static변수나 상수 transient가 붙은 인스턴스변수가 추가되는 경우에는 직렬화에 영향을 미치지 않기 때문에 클래스의 버전을 다르게 인식하도록 할 필요는 없다.

 

표준입출력 - System.in, System.out, System.err

표준입출력은 콘솔(console, 도스창)을 통한 데이터 입력과 콘솔로의 데이터 출력을 의미한다. 자바에서는 표준 입출력(standard I/O)을 위해 3가지 입출력 스트림, System.in, System.out, System.err을 제공하는데, 이 들은 자바 어플리케이션의 실행과 동시에 사용할 수 있게 자동적으로 생성되기 때문에 개발자가 별도의 스트림을 생성하는 코드를 작성하지 않고도 사용이 가능하다.

System.in 콘솔로부터 데이터를 입력받는데 사용
System.out 콘솔로 데이터를 출력하는데 사용
System.err 콘솔로 데이터를 출력하는데 사용

 

System클래스의 소스에서 알 수 있듯이, in, out, err은 System클래스에 선언된 클래스변수(static변수)이다. 선언부분만을 봐서는 out, err, in의 타입은 InputStream과 PrintStream이지만 실제로는 버퍼를 이용하는 BufferedInputStream과 BufferedOutputStream을 사용한다(속도가 빠르다)

public final class System {
	public final static InputStream in = nullInputStream();
	public final static PrintStream out = nullPrintStream();
	public final static PrintStream err = nullPrintStream();
	...
}

Editplus나 이클립스와 같은 에디터에서는 콘솔로의 출력을 중간에 가로채서 에디터에 뿌려주는 것이다. Editplus의 설정화면에서 'Capture Output'옵션을 선택하면 콘솔에 출력하는 내용이 Editplus의 하단에 출력된다.

 

 

public class StandardIOEx1 {
	public static void main(String[] args) {
		try {
			int input = 0;

			while ((input = System.in.read()) != -1) {
				System.out.println("input :" + input + ", (char)input : " + (char) input);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

콘솔입력은 버퍼를 가지고 있기 때문에 Backspace키를 이용해서 편집이 가능하며 한 번에 버퍼의 크기만큼 입력이 가능하다.

콘솔에 데이터를 입력하고 Enter키를 누르면 입력대기상태에서 벗어나 입력된 데이터를 읽기 시작하고 입력된 데이터를 모두 읽으면 다시 입력대기 상태가 된다.

이러한 과정이 반복되다가 사용자가 ctrl+z를 입력하면, read()는 입력이 종료되었음을 인식하고 -1을 반환하여 while문을 벗어나 프로그램이 종료된다.

enter키를 두개 누르는 것은 두 개의 특수문자'\r'과'\n'이 입력된 것으로 간주된다. '\r'은 캐리지리턴(carriage return), 즉 커서를 현재 라인의 첫 번째 컬럼으로 이동시키고'\n'은 커서를 다음 줄로 이동시키는 줄바꿈(new line)을 한다.

그래서 Enter키를 누르면, 캐리지리턴과 줄바꿈이 수행되어 다음 줄의 첫 번째 칼럼으로 커서가 이동하는 것이다.

 

 

 

표준입출력 대상변경 - setOut(), setErr(), setln()

초기에는 System.in, System.out, System.err의 입출력대상이 콘솔화면이지만, setln(), setOut(), setErr()를 사용하면 입출력을 콘솔 이외에 다른 입출력 대상으로 변경하는 것이 가능하다.

 

메서드 설명
static void setOut(PrintStream out) System.out의 출력을 지정된 PrintStream으로 변경
static void setErr(PrintStream err) System.err의 출력을 지정한 PrintStream으로 변경
static void setln(InputStream in) System.in의 입력을 지정한 InputStream으로 변경

 

public class StandardIOEx2 {
	public static void main(String[] args) {
		System.out.println("out : Hello World!");
		System.err.println("err : Hello World!");
	}
}

 

 

 

RandomAccessFile

자바에서는 입력과 출력이 각각 분리되어 별도로 작업을 하도록 설계되어 있는데 RandomAccessFile만은 하나의 클래스로 파일에 대한 입력과 출력을 모두 할 수 있도록 되어 있다.

InputStream이나 OutputStream으로 상속받지 않고, DataInput인터페이스와 DataOutput인터페이스를 모두 구현했기 때문에 읽기와 쓰기가 모두 가능하다.

 

DataInputStream은 DataInput인터페이스를, DataOutputStream은 DataOutput인터페이스를 구현했다. 이 두 클래스의 기본 자료형(primitive data type)을 읽고 쓰기위한 메서드들은 모두 이 2개의 인터페이스에 정의되어있는 것들이다.

따라서, RandomAccessFile클래스도 DataInputStream과 DataOutputStream처럼, 기본자료형 단위로 데이터를 읽고 쓸 수 있다. 

RandomAccessFile클래스의 가장 큰 장점은 파일의 어느 위치에나 읽기/쓰기가 가능하다는 것이다.

이것은 RandomAccessFile클래스 내부의 파일포인터를 사용하는데, 입출력 시에 작업이 수행되는 곳이 바로 파일 포이터가 위치한 곳이 된다.

파일 포인터의 위치는 파일의 제일 첫 부분(0부터 시작)이며, 일기 또는 쓰기를 수행할 때 마다 작업이 수행된 다음 위치로 이동하게 된다. 순차적으로 읽기나 쓰기를 한다면, 파일 포인터를 이동시키기 위해 별도의 작업이 필요하지 않지만, 파일의 임의의 위치에 있는 내용에 대해서 작업하고자 한다면, 먼저 파일 포인터를 원하는 위치로 옮긴 다음 작업을 해야 한다.

현재 작업 중인 파일에서 파일 포인터의 위치를 알고 싶을 때는 getFilePointer()를 사용하면 되고, 파일 포인터의 위치를 옮기기 위해서는 seek(long pos)나 skipBytes(int n)를 사용하면 된다.

모든 입출력에 사용되는 클래스들은 입출력 시 다음 작업이 이루어질 위치를 저장하고 있는 포인터를 내부적으로 갖고 있다. 다만 내부적으로만 사용될 수 있기 때문에 작업자가 포인터의 위치를 마음대로 변경할 수 없다는 것이 RandomAccessFile과 다른 점이다.

 

생성자/메서드 설명
RandomAccessFile(File file, String mode)
RandomAccessFile(String fileName, String mode)
주어진 file에 읽기 또는 읽기+쓰기를 하기 위한
RandomAccessFile인스턴스를 생성한다. mode의 값은 "r", "rw", "rws", "rwd"가 지정가능하다.
"r" - 파일로부터 읽기(r)만 수행할 때
"rw" - 파일로부터 읽기(r)와 쓰기(w)를 수행할 때
"rws - rw+출력내용(파일의 내용 + 메타정보)을 파일에 지연없이 바로 쓰이게 한다. 
"rwd"- rw+출력내용(파일의 내용만)을 파일에 지연없이 바로 쓰이게 한다. 
FileChannel getChannel() 파일의 파일 채널을 반환한다.
FileDescriptor getFD() 파일의 파일 디스크립터를 반환한다.
long getFilePointer() 파일의 포인터의 위치를 알려 준다.
long length() 파일의 크기를 얻을 수 있다.(byte단위)
void seek(long pos) 첫 부분부터 pos크기만큼 떨어진 곳까지 파일 포인터의 위치를 변경한다. 
void setLength(long newLength) 파일의 크기를 지정된 길이로 변경한다.(byte단위)
int skipBytes(int n) 지정된 수만큼 byte를 건너뛴다.

RandomAccessFile의 인스턴스를 "rw" mode로 생성할 때, 지정된 파일이 없으면 새로운 파일을 생성한다.

 

public class RandomAccessFileEx1 {
	public static void main(String[] args) {
		try {
			RandomAccessFile raf = new RandomAccessFile("test.dat", "rw");
			System.out.println("파일 포인터의 위치: " + raf.getFilePointer());
			raf.writeInt(100);
			System.out.println("파일 포인터의 위치: " + raf.getFilePointer());
			raf.writeLong(100L);
			System.out.println("파일 포인터의 위치: " + raf.getFilePointer());

		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

 

파일 포인터의 위치: 0
파일 포인터의 위치: 4
파일 포인터의 위치: 12

이 예제는 파일에 출력작업이 수행되었을 때 파일 포인터의 위치가 어떻게 달라지는지에 대해서 보여 준다.

 

 

 

File

파일은 기본적이면서도 가장 많이 사용되는 입출력 대상이기 때문에 중요하다.

그래서 관련된 기본적인 내용뿐 만 아니라 다양한 활용예제들을 실었다. 이 들을 응용해서 다양한 예제들을 만들어 보면 실력향상에 많은 도움이 될 것이다.

자바에서는 File클래스를 통해서 파일과 디렉토리를 다룰 수 있도록 하고 있다. 그래서 File인스턴스는 파일 일 수도 있고 디렉토리일 수도 있다.

생성자/메서드 설명
File(String fileName) 주어진 문자열(fileName)을 이름으로 갖는 파일을 위한 File인스턴스를 생성한다.파일 뿐만 아니라 디렉토리도 같은 방법으로 다룬다.
여기서 fileName은 주로 경로(path)를 포함해서 지정해주지만, 파일 
File(String pathName, String fileName)
File(File pathName, String fileName)
파일의 경로와 이름을 따로 분리해서 지정할 수 있도록 한 생성자. 이 중 두 번째 것은 경로를 문자열이 아닌 File인스턴스인 경우를 위해서 제공된 것이다.
File(URI uri) 지정된 uri로 파일을 생성
String getName() 파일이름을 String으로 반환
String getPath() 파일의 경로(path)를 String으로 반환
String getAbsolutePath()
File getAbsoluteFile()
파일의 절대경로를 String으로 반환
파일의 절대경로를 File로 반환
String getParent()
File getParentFile()
파일의 조상 디렉토리를 String으로 반환
파일의 조상 디렉토리를 File로 반환
String getCanonicalPath()
File getCanonicalFile()
파일의 정규경로를 String으로 반환
파일의 정규경로를 File로 반환

 

멤버변수 설명
static String pathSeparator OS에서 사용하는 경로(path) 구분자. 윈도우";", 유닉스"."
static char pathSeparatorChar OS에서 사용하는 경로(path) 구분자.
윈도우에서는 ';', 유닉스':'
static String separator OS에서 사용하는 이름 구분자. 윈도우 "\", 유닉스"/"
static char separatorChar OS에서 사용하는 이름 구분자. 윈도우"\", 유닉스"/"

파일의 경로(path)와 디렉토리나 파일의 이름을 구분하는 데 사용 되는 구분자가 OS마다 다를 수 있기 때문에, OS독립적으로 프로그램을 작성하기 위해서는 반드시 위의 멤버변수들을 이용해야한다. 만일 윈도우에서 사용하는 구분자를 코드에 직접 적어 놓았다면, 이 코드는 다른 OS에서는 오류를 일으킬 수 있다.

 

1. 이미 존재하는 파일을 참조할 때 :
File f = new File("c:\\jdk1.8\\work\\ch15", "FileEx1.java");
2. 기존에 없는 파일을 새로 생성할 때 :
File f = new File("c:\\jdk1.8\\work\\ch15", "NewFile.java");
f.creadteNewFile();

 

 

 

메서드 설명
boolean canRead() 읽을 수 있는 파일인지 검사한다.
boolean canWrite() 쓸 수 있는 파일인지 검사한다.
boolean canExecute() 실행할 수 있는 파일인지 검사한다.
int compareTo(File pathname) 주어진 파일 또는 디렉토리를 비교한다. 같으면 0을 반환하며, 다르면 1 또는 -1을 반환한다.(Unix시스템에서는 대소문자를 구별하며, Windows에서는 구별하지 않는다)
boolean exists() 파일이 존재하는지 검사한다.
boolean isAbsolute() 파일 또는 디렉토리가 절대경로명으로 지정되었는지 확인한다.
boolean isDirectory() 디렉토리인지 확인한다.
boolean isFile() 파일인지 확인한다.
boolean isHidden() 파일의 속성이 '숨김(Hidden)'인지 확인한다.
또한 파일이 존재하지 않으면 false를 반환한다.
boolean creadteNewFile() 아무런 내용이 없는 새로운 파일을 생성한다.(단, 생성하려는 파일이 이미 존재하면 생성되지 않는다.)
File f = new File("c:\\jdk1.8\\work\\test3.java");
f.createNewFile();
static File createTempFile
(String prefix, String suffix)
임시파일을 시스템의 임시 디렉토리에 생성한다.
System.out.println(File.createTempFile("work",".tmp"));
결과 : c:\windows\TEMP\work14247.tmp
static File createTempFile
(String prefix, String suffix, File directory)
임시파일을 시스템의 지정된 디렉토리에 생성한다.
boolean delete() 파일을 삭제한다.
void deleteOnExite() 응용 프로그램 종료시 파일을 삭제한다. 주로 실행 시 작업에 사용된 임시파일을 삭제하는데 사용된다.
boolean equals(Object obj) 주어진 객체(주로 File인스턴스)가 같은 파일인지 비교한다. (Unix시스템에서는 대소문자를 구별하며, Windows에서는 구별하지 않는다.)
long lastModified() 파일의 마지막으로 수정된 시간을 지정된 시간으로 반환
long length() 파일의 크기를 반환한다.
String[] list() 디렉토리의 파일목록(디렉토리 포함)을 String배열로 반환한다.
String[] list(FilenameFilter filter)
File[] list(FilenameFilter filter)
FilenameFilter인스턴스에 구현된 조건에 맞는 파일을 String배열(File배열)로 반환한다.
File[] listFiles()
File[] listFiles(FileFilter filter)
File[] listFiles(FilenameFilter f)
디렉토리의 파일목록(디렉토리 포함)을 File배열로 반환(filter가 지정된 경우에는 filter의 조건과 일치하는 파일만 반환)
static File[] listRoots()
long getFreeSpace()
long getTotalSpace()
long getUsableSpace()
컴퓨터 파일시스템의 root의 목록(floppy, CD-ROM, HDD drive)을 반환(예: A:\, D:\)
get으로 시작하는 메서드들은 File이 root일 때, 비어있는 공간, 전체 공간, 사용가능한 공간을 바이트 단위로 반환
boolean mkdir()
boolean mkdrs()
파일에 지정된 경로로 디렉토리(폴더)를 생성, 성공하면 true mkdirs는 필요하면 부모 디렉토리까지 생성
boolean renameTo(File dest) 지정된 파일(dest)로 이름을 변경
boolean setExcutable(boolean excutable)
boolean setExcutable(boolean excutable, boolean ownerOnly)
boolean setReadable(boolean readable)
boolean setReadable(boolean readable, boolean wonerOnly)
boolean setReadOnly()
boolean setWritable(boolean writable)
boolean setWritable(boolean writable, boolean ownerOnly)
파일의 속성을 변경한다.
OwnerOnly가 true면, 파일의 소유자만 해당 속성을 변경할 수 있다.
boolean setLastModified(long t) 파일의 마지막으로 수정된 시간을 지정된 시간(t)로 변경
Path toPath() 파일을 Path로 변환해서 반환
URI toRUI() 파일 URI로 변환해서 반환

 

+ Recent posts