728x90

String클래스는 불변이라는 특성에 의해 지정된 문자열을 변경할 수 없지만 StringBuffer클래스의 인스턴스는 변경이 가능하다. 인스턴스 내부적으로 문자열 편집을 위한 버퍼(buffer)를 가지고 있으며, StringBuffer 인스턴스를 생성할 버퍼의 크기를 지정해줄 수 있다.

 

StringBuffer는 인스턴스를 생성할때, 버퍼의 크기를 지정해주지 않으면 16개의 문자를 저장할 수 있는 크기의 버퍼를 생성한다. 또한 문자열을 인자로 넣어 생성하면 해당 문자열의 길이 +16의 길이에 해당하는 문자열 버퍼를 생성한다.

문자열의 길이가 버퍼의 크기보다 커질경우 버퍼의 크기는 변경될수 없으므로 새로운 길이의 버퍼를 생성한후 기존의 버퍼에 저장된 데이터를 복사한다.

 

StringBuffer는 String클래스와 달리 내용을 변경할 수 있다.

ex)

StringBuffer a = new StringBuffer("abc");

a.append("def");

//a.equals("abcdef") == true

 

위와같이 String 클래스는 새로운 문자열을 만들어 해당 문자열을 가리키는 반면 StringBuffer 기존의 문자열("abc")에 "def"를 더할 수 있다.

 

StringBuffer클래스의 비교

StringBuffer클래스는 equals메소드가 오버라이딩 되어있지않아 equals메소드와 == 이 같다. 두개모두 값이아닌 주소를 비교한다. StringBuffer인스턴스의 데이터를 비교하기 위해서는 toString을 호출하여 String클래스에 저장하고 저장된 데이터를 equals 메소드를 통해 비교해야한다.

StringBuffer는 equals메소드도 비교가 불가능하기 때문에 꼭 toString()메소드를 통해 String 인스턴스를 만들어 값을 넣어주고 해당 String 인스턴스간에 equals메소드로 비교를 해준다.

 

StringBuffer클래스의 메소드

StringBuffer(int length) : length에 해당하는 길이의 버퍼를 가진 StringBuffer를 생성한다.

StringBuffer(String str) : 문자열(str)을 갖는 StringBuffer인스턴스를 생성한다. StringBuffer의 길이는 str.length + 16 이다.

 

StringBuffer append(boolean b)

StringBuffer append(char c)

StringBuffer append(char[] str)

StringBuffer append(double d)

StringBuffer append(float f)

StringBuffer append(int i)

StringBuffer append(long l)

StringBuffer append(Object obj)

StringBuffer append(String str)

입력된 매개변수의 값을 문자열로 변환하여 StringBuffer인스턴스의 문자열 뒤에 붙인다.

 

int capacity() : StringBuffer 인스턴스의 버퍼크기를 알려준다.

int length() : StringBuffer 인스턴스에 저장되어있는 문자열의 길이를 반환해준다.

 

char charAt(int index) : 지정된 위치(index)에 있는 문자를 반환한다.

StringBuffer delete(int start, int end) : 시작위치(start)부터 끝위치(end)까지의 문자열을 제거한다. 끝위치의 문자는 제외한다.

StringBuffer deleteCharAt(int index) : 지정된 위치(index)의 문자를 제거한다.

 

StringBuffer insert(int pos, boolean b)

StringBuffer insert(int pos, char c)

StringBuffer insert(int pos, char[] str)

StringBuffer insert(int pos, double d)

StringBuffer insert(int pos, float f)

StringBuffer insert(int pos, int i)

StringBuffer insert(int pos, long l)

StringBuffer insert(int pos, Object obj)

StringBuffer insert(int pos, String str)

두번째 매개변수로 받은 값을 문자열로 변환하여 지정된 위치(pos)에 추가한다. pos는 0부터 시작

 

StringBuffer replace(int start, int end, String str) : start~end의 문자열을 주어진 문자열(str)로 바꾼다. end는 포함되지 않는다.

StringBuffer reverse() : StringBuffer 인스턴스에 저장되어 있는 문자열의 순서를 거꾸로 나열한다.

void setCharAt(int index, char ch) : 지정된 위치의 문자를 주어진 문자(Ch)로 바꾼다.

void setLength(int newLength) : 문자열의 길이를 newLength길이로 변경한다. 길이를 늘리는 경우에 나머지 빈 공간을 '\u0000'로 채운다.

String toString() : StringBuffer 인스턴스의 문자열을 String 클래스로 값으로 반환한다.

String substring(int start), String substring(int start, int end) : 지정된 범위의 문자열을 String으로 뽑아서 반환한다.

시작위치(start)만 지정하면 시작위치부터 문자열 끝까지 뽑아서 반환한다.

 

StringBuffer메소드 사용

StringBuilder

StringBuffer는 멀티쓰레드에 안전하도록 동기화 되어있다. 동기화가 StringBuffer의 성능을 떨어뜨린다. 멀티쓰레드로 작성된 프로그램이 아닌 경우 StringBuffer의 동기화는 불필요하게 성능을 떨어뜨린다.

쓰레드 동기화에 의한 성능 저하를 해결하기 위해 StringBuffer에서 동기화만 제거한 StringBuilder가 새로 추가되었다. 

StringBuffer와 StringBuilder는 똑같은 기능으로 작성되어있어 성능향상을 필수로 하는경우가 아니라면 StringBuffer를 StringBuilder로 굳이 바꿀 필요는 없다.

728x90

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

ArrayList LinkedList  (0) 2021.07.29
Collections Framework  (0) 2021.07.26
String 클래스  (0) 2021.07.26
Object클래스 메서드  (0) 2021.07.18
예외처리 Exception handling  (0) 2021.07.17
728x90

String 클래스는 문자열을 저장하기 위한 char[] 를 인스턴스 변수로 정의해 놓고 있다. String 클래스 인스턴스 생성시 대입되는 문자열은 해당 인수턴스 변수에 저장된다.

String 클래스는 불변 클래스이다. 한번 생성된 String 인스턴스는 문자열을 읽기만 가능하고 변경은 불가능하다.

 

문자열 결합

ex) + 연산시

+연산시 "abc"와 "def"를 합한 String 인스턴스를 새로 생성하여 해당 인스턴스를 가리킨다.

위처럼 +연산마다 새로운 String 인스턴스가 생성되어 메모리 공간을 차지하므로 결합횟수를 줄이는 것이 메모리 사용에 좋다.

 

문자열 비교

String 클래스 간의 비교는 equals 메소드로 가능하다.

String 인스턴스를 ==으로 비교할경우 해당 인스턴스들의 주소를 비교하게된다.

str1과 str2는 문자열 리터럴 "abc"를 가리킨다. 같은 주소를 가리키는 것이다.

str3과 str4는 각각 새로 생성된 String 인스턴스 "abc"를 가리킨다.

==의경우 문자열 주소 비교이기때문에 str1과 str2는 true이고 String 인스턴스를 생성한 str3과 str4는 false가 나온다.

equals의 경우 각각 문자열을 비교하기 때문에 모두 true이다.

 

String 클래스의 메소드

char charAt(int index) : 지정된 위치(index)에 있는 문자를 알려준다. index는 0부터 시작한다.

int compareTo(String str) : str과 사전순서로 비교한다. 같으면 0을 리턴하고, 사전순으로 이전이면 음수, 이후이면 양수를 리턴한다.

String concat(String str) : 문자열(str)을 뒤에 덧붙인다. 덧붙인 String을 리턴한다.

boolean contains(CharSequence s) : 지정된 문자열(s)이 포함되었는지 검사하고 포함되어있다면 true 아니라면 false를 리턴한다.

CharSequence는 CharBuffer, String, StringBuffer등의 조상 인터페이스로 자식 클래스중 어떤것이든 인자로 들어올 수 있다.

 

boolean endsWith(String suffix) : 지정된 문자열(suffix)로 끝나는지 검사한다. 파일명을 가져와서 endsWith suffix에 ".txt"를 넣어주면 해당 파일이 텍스트 파일인지 확인 가능하다.

boolean startWith(String suffix) : 지정된 문자열(suffix)로 시작하는지 검사한다.

boolean equals(Object obj) : 매개변수로 받은 문자열(obj)과 String 인스턴스의 문자열을 비교한다. obj가 String이 아니거나 문자열이 다르면 false를 리턴한다.

boolean equalsIgnoreCase(String str) : 문자열과 String인스턴스의 문자열을 대소문자 구분없이 비교한다.

 

int indexOf(int ch) : 문자(ch)가 문자열의 어느 위치에 있는지 확인하여 위치(index)를 반환해준다. 문자열에 존재하지 않는다면 -1을 반환한다.

int indexOf(int ch, int pos) : pos위치부터 문자(ch)가 위치를 알려준다.

int indexOf(String str) : 문자열(str)이 문자열의 어느위치에 있는지 확인하여 시작하는 위치(index)를 반환해준다. 문자열(str)이 문자열에 존재하지 않는다면 -1을 반환한다.

int lastIndexOf(int ch), int lastIndexOf(String str) : 위의 함수들과 같지만 문자열의 가장 오른쪽(맨끝) 부터 왼쪽으로 이동하면서 확인한다.

 

int length() : 문자열의 길이를 반환한다.

String replace(char old, char new) : 문자열중 문자(old)를 새로운 문자(new)로 바꾼 문자열을 반환한다.

String replace(CharSequence old, CharSequence new) : 문자열중 문자열(old)을 새로운 문자열(new)로 모두 바꾼 문자열을 반환한다.

String replaceAll(String regex, String replacement) : 문자열중 지정된 문자열(regex)과 일치하는 모든 문자열을 문자열(replacement)로 변경한다.

String replaceFirst(String regex, String replacement) : 문자열중 지정된 문자열(regex)과 일치하는 것 중, 첫번째로 일치하는 문자열만 문자열(replacement)로 변경한다.

 

String[] split(String regex) : 문자열을 지정된 분리자(regex)로 나누어 문자열 배열에 담아 반환한다.

String[] split(String regex, int limit) : 문자열을 지정된 분리자(regex)로 나누어 문자열배열에 담아 반환한다. 단, 문자열 전체를 지정된 수(limit)로 자른다.

String substring(int begin), String substring(int begin, int end) : 시작위치(begin)부터 끝 위치(end) 범위에 포함된 문자열을 얻는다. 이때, 시작위치의 문자는 범위에 포함되지만, 끝 위치의 문자는 포함되지 않는다.

 

String toLowerCase() : String인스턴스에 저장되어 있는 모든 문자열을 소문자로 변환하여 반환한다.

String toUpperCase() : String인스턴스에 저장되어 있는 모든 문자열을 대문자로 변환하여 반환한다.

String toString()  : String인스턴스에 저장되어 있는 문자열을 반환한다.

String trim() : 문자열의 왼쪽 끝과 오른쪽 끝에 있는 공백을 지운 결과를 반환한다. 문자열 중간에 있는 공백은 지워지지않는다.

 

join()메소드와 StringJoiner

String의 join()메소드를 통해 여러 문자열 사이에 구분자를 넣어서 결합할 수 있다.

StringJoiner클래스를 사용해서도 문자열 결합이 가능하다.

join()메소드와 StringJoiner클래스를 사용했을때이다.

join()메소드를 통해 해당 문자열배열 사이에 "-"를 넣어 결합한형태이고

StringJoiner클래스를 통해 구분자 "/", 시작문자 "[", 끝문자"]"를 결합한 상태이다.

StringJoiner에 add메소드를 통해 각 문자열들을 결합해준다.

 

기본형 값을 String으로 변환

일반적으로 숫자를 문자로 변환할 경우에는 숫자에 빈 문자열""을 더해주는 방식으로 숫자를 문자열로 변환한다.

숫자를 문자열로 변환하는 방법으로 String클래스의 valueOf()메소드가 있다. 성능은 valueOf()메소드가 더 좋기때문에 성능향상이 필요한경우가 아니라면 빈문자열을 더하는 방법이 더 편하다.

 

반대로 문자열을 기본형 값으로 변환하는 것도 valueOf()로 가능하다.

ex)

int i = Integer.valueOf("100");

int i2 = Integer.parseInt("100");

 

문자열의 데이터에 해당하는 데이터형 클래스의 메소드의 parse를 사용해서도 해당하는 데이터로 변환가능하다.

ex)

Byte.parseByte(String s);

Short.parseShort(String s);

Integer.parseInt(String s);

Long.parseLong(String s);

Float.parseFloat(String s);

Double.parseDouble(String s);

 

위의 클래스의 각각 valueOf(string str)을 사용해도 해당 문자열을 위의 클래스로 변환이 가능하다.

parseInt나 parseDouble같은 메소드는 문자열에 공백이 포함되어있는 경우 예외가 발생할 수 있으므로 주의해야한다.

그래서 trim()메소드를 통해 공백을 제거해주기도한다.

부호를 의미하는 '+'나 float형 값을 뜻하는 'f'와 같은 자료형 접미사는 포함 가능하다.

728x90

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

Collections Framework  (0) 2021.07.26
StringBuffer클래스와 StringBuilder클래스  (0) 2021.07.26
Object클래스 메서드  (0) 2021.07.18
예외처리 Exception handling  (0) 2021.07.17
Interface를 이용한 다형성  (0) 2021.07.17
728x90

equals(Object obj) 메서드

==의 경우 두 객체의 참조변수 값의 같고 다름을 판단하기 때문에 해당 기호는 주소값의 비교이다.

Object의 equasl()메소드도 참조 변수의 값으로 판단을 하는데 이것을 객체의 값 비교로 사용하기 위해서는 적절한 오버라이딩이 필요하다.

객체에 저장된 값을 비교하기 위해서는 equals 메서드를 오버라이딩 하여 사용하는데 해당 메서드를 값비교를 위해 오버라이딩한 예제이다.

String 클래스에 저장된 문자열 비교시에도 ==이 아닌 equals 메소드를 사용한다.

생성된 객체들은 모두 주소가 다르기 때문에 ==에서 다른 값이라고 인식되고, 오버라이딩 된 equals를 통해 객체의 주소 값이 아닌 객체의 값을 비교했을 때 같은 값을 가지고 있기 때문에 같은사람이라는 출력이나온다.

 

 HashCode() 메서드

Object클래스의 hashCode메서드는 객체의 주소값으로 해쉬값을 만들기 때문에 객체마다 다른 해쉬값을 가진다.

(System.identityHashCode()와 Object클래스의 hashCode는 같은 방식으로 동작한다.)

인스턴스 값에대한 hashcode를 생성하여 같은 값은 같은 hash값을 갖기 위해서는 hashcode 메서드를 오버라이딩 하여 사용 해야한다. 

String 클래스의 경우 String객체가 가진 문자열 값을 기반으로 HashCode를 생성하도록 오버라이딩 되어있으므로 위의 예제는 같은 HashCode를 출력한다. 그러나 Object의 hashcode원리와 같이 주소값을 기반으로 hashCode를 생성할 경우 두개의 객체는 다른 값을 출력한다.

 

또한 equals()를 오버라이딩 하는 상황이라면 hashCodoe()메서드도 적절하게 오버라이딩 해주어야 한다. 같은 객체라면 HashCode()메서드의 결과값도 같아야 하기 때문이다.

 

toString() 메서드

Object 클래스에 정의된 toString()

Object클래스에 정의된 toString()메서드의 경우 클래스이름@주소기반16진수hashcode문자열이 반환된다.

하지만 위의 정보들은 사용시 유용하지 않기 때문에 toString()메서드는 일반적으로 인스턴스 클래스에 대한 정보나 인스턴스 변수들의 값을 문자열로 반환하도록 오버라이딩하여 사용된다.

 

클래스에서 toString()메서드를 오버라이딩 한경우

위와같이 인스턴스 객체의 인스턴스 변수들을 출력하게 오버라이딩 후 출력하였다. Object클래스의 toString()메서드가 public 메서드이기 때문에 오버라이딩의 경우도 public으로 해주어야 한다.

 

 clone() 메서드

clone() 메서드는 자신을 복제하여 새로운 객체를 생성하는 메서드이다.

Object클래스에 정의된 clone()은 단순히 인스턴스변수의 값만 복사하기 때문에 참조타입의 인스턴스 변수가 있는 클래스는 완전한 인스턴스 복제가 이루어지지 않는다.

 

clone()을 사용하려면, 먼저 clone메서드를 사용할 클래스가 Cloneable인터페이스를 구현해주어야한다.

Cloneable인터페이스를 구현한 클래스의 인스턴스만 clone()메서드를 사용할 수 있는 이유는 인스턴스 데이터를 보호하기 위해서이다. 해당 클래스의 인스턴스만 복제를 허용한다.

또한 clone()메서드를 호출할때는 반드시 예외처리를 해주어야한다.

 

clone()메서드는 객체에 저장된 값을 그대로 복제하지만, 객체가 참조하고있는 객체까지 복제하지 못한다. 객체가 참조하고있는 주소만을 복제할 뿐이다. 이러한 복제는 해당 객체의 주소를 복제하고 객체자체를 복제하는 것이 아니기 때문에 완전한 복제라고 보기어렵다. 객체의 주소가아닌 참조객체까지 복제하는 '깊은 복제(deep copy)'를 하기 위해서는 clone()메서드를 이용해서 적절하게 구현 해주어야한다.

shallow copy는 객체에 저장된 값을 그대로 복제하는 얕은복사이다. 참조변수 멤버가 있을경우 참조변수의 참조값 즉 주소값만 복제가된다.

deepcopy메서드의 경우 해당 참조변수 멤버의 객체값을 복사한다.

얕은 복사를 진행한 c2의 경우 원본인 c1의 값이 바뀔경우 c2의 값도 변경된다.

그러나 깊은 복사를 진행한 c3의 경우 c1이 변경되더라도 원본의 값을 유지한다. 

깊은 복사를 통해 원본이 참조하고있는 Point객체까지 복제했기 때문에 위와같은 결과가 나타난다.

 

인스턴스 변수에 참조형 변수가 없는경우 clone()메서드만으로 충분하다.

그러나 위처럼 깊은복사를 clone메소드를 통해 구현하고싶다면 참조변수의 객체를 복제가 가능하도록 깊은복사 메서드를 구현 해주어야한다.

 

getClass() 메서드

getClass()메서드는 자신이 속한 클래스의 Class 객체를 반환하는 메서드이다. Class 객체는 이름이 'Class'인 클래스 객체이다.

 

Class객체는 클래스의 모든 정보를 담고 있으며, 클래스 당 1개만 존재한다. 클래스 파일이 '클래스 로더(ClassLoader)'에 의해 메모리에 올라갈 때, 자동으로 생성된다. 클래스 로더는 실행시에 클래스를 동적으로 메모리에 로드하는 역할을 한다.

 

getClass()메서드는 파일형태로 저장되어 있는 클래스를 읽어서 Class클래스에 정의된 형식으로 변환하는 것이다.

Class 객체에 대한 참조를 얻는 방법으로 클래스명.class.newInstance()를 사용했다.

해당 Class객체를 통해 해당 객체의 클래스 이름을 얻을 수 있다.

Class객체가 실무에서 자주 쓰일지는 잘모르겠다. 뭔가 난해하고 유용한가에 대한 의문이 생긴다.

728x90

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

StringBuffer클래스와 StringBuilder클래스  (0) 2021.07.26
String 클래스  (0) 2021.07.26
예외처리 Exception handling  (0) 2021.07.17
Interface를 이용한 다형성  (0) 2021.07.17
JAVA 접근 제어자  (0) 2021.07.15
728x90

0/0을 출력하는 구문에서 ArithmeticException이 발생한다. 또한 ArithmeticException을 제외한 다른 Exception이 발생할 경우를 예상하여 catch(Exception e)를 작성해 주었다.

Exception객체는 모든 예외에 대한 부모 예외기 때문에 예상하지 못한 예외가 발생하더라도 해당 catch구문으로 들어가게된다. 

0/0에서 예외가 발생하기때문에 system.out.println(4)는 실행하지않고 catch(ArithmeticException ae)를 실행하게 된다.

true와 ArithmeticException을 출력한후 try-catch구문 이후 코드들을 실행시킨다.

 

메서드에 예외를 선언한것이다.

해당 방법은 메서드에서 예외가 발생할경우 해당 예외를 자신을 호출한 메서드에게 전달하여 예외처리를 떠맡기는 것이다.

method2에서 throw new Exception()으로 예외가 발생하게 되고 해당 메서드는 throws구문을 통해 method2를 호출한 method1로 넘어간다.

method1에서도 thrwos구문을 통해 method1을 호출한 main메소드로 예외를 떠넘긴다.

main 메소드에서 예외를 throws할경우 JVM에 예외를 떠넘긴다.

이후 JVM의 기본예외 처리기가 위와같은 출력을 한다.

 

위와 같이 메서드에서 발생한 예외를 처리하지않고 자신을 호출한 메서드에게 계속 떠넘겨줄 수 있지만 해당 행위는 예외를 처리하는 것이 아닌 단순히 전달만 하는 것이기 때문에 반드시 어느 한곳에서 try-catch구문을 통해 예외처리를 해주어야한다.

728x90

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

StringBuffer클래스와 StringBuilder클래스  (0) 2021.07.26
String 클래스  (0) 2021.07.26
Object클래스 메서드  (0) 2021.07.18
Interface를 이용한 다형성  (0) 2021.07.17
JAVA 접근 제어자  (0) 2021.07.15
728x90

다형성 특성에 의해 자식 객체에서 상속받은 부모의 클래스 또는 인터페이스의 참조변수 타입으로 자식 인스턴스를 저장할 수 있다.

이후 메소드 호출은 각각 참조변수 타입에 존재하는 메소드호출만 가능하다.

 

 

메서드의 인터페이스 타입의 매개변수가 갖는 의미는 메서드 호출시 해당 인터페이스를 구현한 클래스의 인스턴스를 매개변수로 제공해야 한다는 의미이다.

위의 경우 attack메서드에서 Fightable 인터페이스 타입이 매개변수로 지정되어 있다. 그렇다면 해당 메서드를 호출할때는 Fighter 인스턴스 객체를 매개변수로 넣어주어야한다.

 

메서드의 리턴타입으로 인터페이스 타입을 지정하는 것은 메서드가 해당 인터페이스를 구현한 클래스의 인스턴스를 반환한다는 의미이다.

Figtable getFightable 메소드의 경우 return 문에서 Fightable을 구현한 Fighter 인스턴스 객체가 반환된다. 

A클래스 코드의 변경없이도 B또는 C 클래스 즉 method 메소드의 구현부를 수정함으로써 코드변경을 최소화 하였다.

Interface를 사용하여 위와같이 코드변경을 최소화 할수 있다.

728x90

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

StringBuffer클래스와 StringBuilder클래스  (0) 2021.07.26
String 클래스  (0) 2021.07.26
Object클래스 메서드  (0) 2021.07.18
예외처리 Exception handling  (0) 2021.07.17
JAVA 접근 제어자  (0) 2021.07.15
728x90

private : 같은 클래스 내에서만 접근이 가능하다.

default : 같은 패키지 내에서만 접근이 가능하다.

protected : 같은 패키지 내에서, 그리고 다른 패키지의 자손클래스에서 접근이 가능하다.

public : 접근 제한이 전혀 없다.

 

자바의 정석을 공부하면서 좋은 예제가있어 블로그에 작성합니다.

접근제어자에 따른 접근범위를 가장 잘 보여주는 예문인것 같습니다.

 

protected 멤버의 경우 자신과 자식클래스 만 접근 가능하다고 생각했는데

같은패키지내의 다른 클래스들도 접근이 가능하다는것을 알게되었습니다.

728x90

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

StringBuffer클래스와 StringBuilder클래스  (0) 2021.07.26
String 클래스  (0) 2021.07.26
Object클래스 메서드  (0) 2021.07.18
예외처리 Exception handling  (0) 2021.07.17
Interface를 이용한 다형성  (0) 2021.07.17
728x90

디렉터리 관련 함수 및 그밖의 함수들

 

디렉터리의 생성과 소멸

디렉터리 생성함수

BOOL CreateDirectory(

   LPCTSTR lpPathName,

   LPSECURITY_ATTRIBUTES lpSecurityAttributes

);

1.lpPathName : 생성하고자 하는 디렉터리 이름을 지정한다.

2.lpSecurityAttributes : 보안 속성을 지정할 때 사용된다. 기본적으로 NULL을 전달해서 디폴트 보안속성을 지정한다.

 

디렉터리 소멸함수

BOOL RemoveDirectory(

   LPCTSTR lpPathName

);

1.소멸하고자 하는 디렉터리 이름 지정

 

CreateDirectory 첫번째 인자에 경로를 포함하지 않은 문자열만 전달할 시 해당 프로그램이 존재하는 곳에 디렉터리가 생성된다. 경로를 포함할 시 해당 경로에 디렉터리가 생성된다.

 

현재 디렉터리, 시스템 디렉터리, Windows디렉터리

현재 디렉터리(Current Directory)

현재 디렉터리는 프로그램이 존재하는 디렉터리이다.

초기에는 프로그램이 로드(Load)된 디렉터리로 설정되며, 이후 변경 가능하다.

->프로그램이 실행된 이후 현재 디렉터리는 언제든지 변경될 수 있다.

 

현재디렉터리 참조 함수

DWORD GetCurrentDirectory(

    DWORD nBufferLength,

    LPTSTR lpBuffer

);

1.nBufferLength : 두번째 인자로 전달된 버퍼의 길이를 지정한다.

2.pBuffer : 현재 디렉터리 정보를 저장할 버퍼의 주소값을 지정한다.

 

현재 디렉터리 변경함수

BOOL SetCurrentDirectory(

   LPCTSTR lpPathName

);

1.lpPathName : 변경하고자 하는 현재 디렉터리 정보를 지정한다.

 

시스템 디렉터리(System Directory) & Windows 디렉터리

시스템 디렉터리는 각종 라이브러리(DLL) 및 드라이버 파일처럼 Windows 시스템에 중요한 파일들이 존재하는 위치였고, Windows 디렉터리는 초기화 및 실행파일들이 존재하는 위치이다.

 

시스템 디렉터리와 Windows 디렉터리는 변경이 불가능 하며 변경해서는 안된다.

 

 시스템 디렉터리 위치 정보 확인 함수

UINT GetSystemDirectory(

    LPTSTR lpBuffer,

    UINT uSize

);

1.lpBuffer : 시스템 디렉터리 정보를 저장할 버퍼의 주소값을 지정한다.

2.uSize : 첫번째 인자로 전달된 버퍼의 길이를 지정한다.

 

윈도우 디렉터리 위치 정보 확인 함수

UINT GetWindowsDirectory(

   LPTSTR lpBuffer,

   UINT uSize

);

1.lpBuffer : Windows 디렉터리 정보를 저장할 버퍼의 주소값을 지정한다.

2.uSize : 첫번째 인자로 전달된 버퍼의 길이를 지정한다.

 

windef.h에 MAX_PATH가 정의되어있다. 이는 디폴트 최대경로 길이 248을 고려하여 선언된 매크로 상수이다. 따라서 파일이름(완전 경로를 포함하는)을 저장하기 위한 문자열 버퍼를 선언할 때 활용할 수 있다.

#define MAX_PATH 260

 

디렉터리에서 파일 찾기

파일의 위치정보나 특정 디렉터리 내에 존재하는 파일 정보를 얻고자 할 때 사용할 수 있는 함수들

 

SearchPath 함수는 문자열로 지정한 경로에 특정 파일이 존재하는지 확인하는 용도로 사용할 수 있다. 파일 이름을 인자로 하여 해당 파일이 저장되어 있는 완전경로를 얻고자 할 때에 사용할 수 있다.

 

DWORD SearchPath(

   LPCTSTR lpPath,

   LPCTSTR lpFileName,

   LPCTSTR lpExtension,

   DWORD nBufferLength,

   LPCTSTR lpBuffer,

   LPCTSTR* lpFilePart

);

1.lpPath : 대상 경로를 지정한다. 이 인자를 통해서 지정된 경로에서 파일을 찾게 된다. 인자로 NULL이 전달되면, 다음과 같은 순서로 파일을 찾게된다. 아래의 경로를 가리켜 표준 검색 경로라 한다.

1_실행 중인 프로그램이 로드(Load)된 디렉터리(실행 파일이 존재하는 디렉터리)

2_현재 디렉터리(Current Directory)

3_시스템 디렉터리(System Directory)

4_Windows 디렉터리

5_마지막으로 환경변수 PATH에 등록된 디렉터리

2.lpFileName : 찾고자 하는 파일 이름

3.lpExtension : 확장자를 지정하는 인자로서 첫번째 문자는 반드시 '.'으로 시작해야 한다. lpFileNAme이 확장자를 포함하고 있거나 확장자를 지정해 줄 필요가 없을 때에는 NULL을 지정한다.

4.nBufferLength : 완전 경로명을 저장할 버퍼의 길이를 요구한다.

5.lpBuffer : 완전 경로명을 저장할 버퍼의 주소를 지정한다.

6.lpFilePart : 함수 호출 결과로 얻게되는 완전경로 명(lpBuffer로 지정된 버퍼에 저장되는 완전경로명)의 마지막에는 파일 이름도 추가된다. 이 전달인자를 통해서 파일 이름이 저장된 위치 정보(포인터 값)를 얻게된다.

 

FindFirstFile 함수

HANDLE FindFirstFile(

   LPCTSTR lpFileName,

   LPWIN32_FIND_DATA lpFindFileData

);

1.lpFileName : 파일이나 디렉터리 이름 지정. 지정된 정보를 근거로 파일(혹은 디렉터리)정보를 얻게된다.

2.lpFindFileData : 발견된 파일이나 디렉터리 정보를 담을 WIN32_FIND_DATA 구조체 변수의 주소값을 전달한다.

 

FindFirstFile 함수의 반환 타입이 HANDLE이다. FindFirstFile 함수를 통해서 조건에 맞는 파일 중 가장 첫번째 검색된 파일 정보만 얻을 수 있다.

 

FindNextFile 함수

BOOL FindNextFile(

   HANDLE hFindFile, 

   LPWIN32_FIND_DATA lpFindFileData

);

1.hFindFile : FindFirstFile 함수 호출을 통해서 얻은 핸들을 전달한다. 

2.lpFindFileData : 발견된 파일이나 디렉터리의 정보를 담을 WIN32_FIND_DATA구조체 변수의 주소값을 전달한다.

 

BOOL FindClose(

   HANDLE hFindFile

);

1.hFindFile : FindFirstFile 함수를 통해서 얻은 핸들을 반환한다.

 

FindFirstFile 함수와 FindNextFile함수의 사용법은 LinkedList의 LFirst와 LNext함수 사용법과 유사하다.

FindFirstFile을 통해 조건에 부합하는 첫번째 파일에 대한 파일 정보를 두번째 인자에 저장한다.

이후 FindNextFile에 FindFirstFile함수 반환 핸들을 인자로 넣어 조건에 부합하는 다음 파일에 대한 정보를 받아온다.

이후 FindClose함수를 통해 FindFirstFile 함수 반환 핸들을 반환해 준다.

728x90
728x90

파일의 특성(Attribute) 정보 얻어오기

파일의 특성정보는 파일의 속성에서 확인할 수 있다.

파일의 특성 정보는 읽기전용, 숨김, 보관 등에 대한 정보이다. 이러한 특성 정보는 프로그램 코드 상에서도 변경 및 확인이 가능하다.

 

특성 정보 확인 함수

DWORD GetFileAttributes(

   LPCTSTR lpFileName

);

lpFileName : 특성 정보를 얻고자 하는 파일의 이름을 지정한다. 파일의 특성정보는 반환값을 통해서 얻게된다.

 

위 함수를 통해 파일 특성에 대한 정보들을 얻을 수 있다. 

 

파일 특성 정보의 표현 방식

위 그림은 32비트 자료형 DWORD을 보여주고 있다.

첫번째 비트가 1인 경우의 값 0x00000001을 "읽기 전용 특성"정보를 표현하는데 사용하기로 정의되어 있다.

 

두번째 인덱스 비트가 1인 경우에 해당하는 값 0x00000002는 "숨김 특성" 정보를 표현하는데 사용하기로 정의되어 있다.

 

위 두가지 특성정보 외에도 파일이 가질 수 있는 특성정보의 종류는 12가지정도가 더 된다.

 

따라서 반환값이 인덱스 기준으로 0번째 비트와 1번째 비트가 각각 1로 설정되어 있으면, 그 파일은 읽기 전용이자 숨김 특성까지 지닌 파일이 된다.

프로그램 구현의 용이성을 위해서 읽기 전용특성과 숨김 특성을 다음과 같이 매크로 상수로 정의해 놓고 있다.

#define FILE_ATTRIBUTE_READONLY 0x00000001

#define FILE_ATTRIBUTE_HIDDEN 0x00000002

 

파일 특성 정보 변경 함수

BOOL SetFileAttributes(

  LPCTSTR lpFileName,

  DWORD dwFileAttributes

);

1.lpFileName : 특성 정보를 변경하고픈 파일의 이름을 지정한다.

2.dwFileAttributes : 변경할 특성 정보를 전달한다.

 

GetFileAttributes함수와 SetFileAttributes 함수는 일반적인 파일 처리 함수와 차이를 보인다. 그것은 핸들을 필요로 하지 않는다는 점이다. 대신 위치 경로를 포함하는 파일의 이름을 필요로 한다.

 

 

파일의 특성(Attribute) 정보 핸들로부터 얻어오기 + α

BOOL GetFileInformationByHandle(

  HANDLE hFile,

  LPBY_HANDLE_FILE_INFORMATION lpFileInformation

);

1.hFile : 정보를 얻고자 하는 파일의 핸들을 지정한다.

2.LPBY_HANDLE_FILE_INFORMATION : 구조체 BY_HANDLE_FILE_INFORMATION의 포인터 타입이다. 여기로 전달되는 주소의 변수에 파일 정보가 채워진다.

 

GetFileInformationByHandle 함수를 통해서 얻는 정보는 파일의 시간 정보, 파일의 크기정보, 파이르이 시스템 정보들을 얻을 수 있다.

BY_HANDLE_FILE_INFORMATION 선언

typedef struct _BY_HANDLE_FILE_INFORMATION

{

   DWORD dwFileAttributes;

   FILETIME ftCreationTime;

   FILETIME ftLastAccessTime;

   FILETIME ftLastWriteTime;

   DWORD dwVolumeSerialNumber;

   DWORD nFileSizeHigh;

   DWORD nFileSizeLow;

   DWORD nNumberOfLinks;

   DWORD nFileIndexHigh;

   DWORD nFileIndexLow;

}BY_HANDLE_FILE_INFORMATION, *BYHANDLE_FILE_INFORMATION;

 

GetFileInformationByHandle 함수를 이용하여 파일에 대한 정보를 가져와 각 멤버에 접근하여 관련정보를 알 수 있다.

 

파일의 경로(Path)정보 얻어오기

DWORD GetFullPathName(

  LPCTSTR lpFileName,

  DWORD nBufferLenth,

  LPTSTR lpBuffer,

  LPTSTR* lpFilePart

);

1.lpFileName : 완전 경로(Full Path)를 확인하고자 하는 파일 이름 전달.

2.nBufferLength : 완전 경로를 저장할 버퍼에 저장 가능한 문자열 길이를 지정한다. 버퍼의 바이트 단위 크기가 아니라 저장가능한 문자열의 길이이다.

3.lpBuffer : 완전 경로를 저장할 버퍼의 주소값을 지정한다.

4.lpFilePart : 완전 경로가 문자열로 버퍼에 저장된 이후, 버퍼의 특정 위치를 가리키는 포인터 값이 저장된다. 마지막 역 슬래쉬(\)다음 번지 주소값이 저장된다.

 

파일 포인터의 이동

ANSI표준함수 fseek에 해당하는 windows 시스템 함수는 SetFilePointer이다.

 

DWORD SetFilePointer(

   HANDLE hFile,

   LONG lDistanceToMove,

   PLONG lpDistanceToMoveHigh,

   DWORD dwMoveMethod

);

1.hFile : 파일 포인터 위치를 이동시킬 대상 파일의 핸들을 지정한다.

2.lDistanceToMove : 이동시킬 거리를 지정한다. 만약에 64비트 기반으로 구현한다면, 하위 4바이트 정보를 표현하게 된다.

3.lDistatnceToMoveHigh : 64비트 기반의 대용량 파일에서만 의미를 지닌다. 상위 4바이트 정보를 표현하게 된다. 32비트 기반에서는 NULL을 전달한다.

4.dwMoveMethod : 파일 포인터 이동시 기준이 되는 위치를 지정한다.

파이르이 가장 앞부분을 기준으로 설정하고자 할 때에는 FILE_BEGIN을 인자로 전달한다. fseek 함수의 SEEK_SET에 해당한다. SEEK_CUR과 같은 의미로는 FILE_CURRENT, SEEK_END와 같은 의미로는 FILE_END를 인자로 전달한다.

 

SetFilePointer함수를 이용하여 파일 포인터 이동 후 ReadFile함수를 이용하여 파일을 읽어들이면 설정한 파일 포인터 부터 읽어들인다.

 

32비트 기반의 파일에서는 3번째 인자에 NULL을 전달하고, 64비트 기반의 대용량 파일에서는 상위 4바이트 정보를 받을 변수의 주소 값을 인자로 넣어준다.

 

 

728x90

+ Recent posts