저에겐 맥이 네대 있습니다. 하지만 PowerPC 8500, PowerMac G3, iMac(ppc, 1.8GHz), Mac mini(Intel Core Duo 1.83GHz)입니다. PowerPC는 하실 수 있는게 거의 없으셔서 경로우대 차원에서 거의 모셔만 두고 있고 G3는 집사람이 뒤의 둘은 제가 사용합니다.

수는 많지만 슬프게도 늙고 약한 애들밖에 없습니다. 그래서 작년에 올해 초 새로운 맥북이 나온다는 소식을 듣고 제 맥 라인에 젊은 피를 공급해야 할 것 같고 비용적인 측면에서 레퍼드만 따로 사는 것 보다 새로운 노트북을 구입하는 것이 나을 것 같아서 기다리고 있었습니다.

예상대로 올 초 드디어 새로운 맥북인 맥북에어가 나왔습니다. 얇기가 예술입니다.

사용자 삽입 이미지
  
하지만 제가 바랬던 것은 기존 맥북 가격에서 해상도가 향상되고 무게가 좀 가벼운 새 노트북을 데스크탑 용도로 노트북 모니터까지 듀얼로 사용할려고 했습니다. 그런데 두께로 성능을 비롯해 희생된 것들로 인해 맥북에어는 제게 적당하지 않은 것 같습니다.

게다가 가격이 거의 200만원이니 차리리 맥북프로가 더 제 용도에 맞을 것 같습니다. 하지만 현재 맥은 아니지만 노트북이 있고, 그다지 이동하며 쓸일이 많지 않아 200만원을 들여 노트북을 사야할 필요성을 거의 느끼지 못하고 있습니다.

올초부터는 레퍼드 사용자가 될려는 계획은 언제 실현될지 알 수가 없게 되었습니다. 레퍼드만 따로 사지는 않을 것 같고 분명히 뭔가를 사서 그냥 데려올 것 같은데 그 뭔가가 뭐가 될지 모르겠습니다. 주머니는 얇고 바라는 것은 많은데다 늙어서 지름신도 잘 강림을 안하시니 난감합니다.

사용자 삽입 이미지
이러니 애플 사이트만 들락 거리며 이런 바보 같은 상상을 하곤 합니다.

돈많은 사람들은 왜 맥프로 + 듀얼 30인치 애플시네마 + 블루투스 키보드, 마우스 + 타임캡슐 + 사운드스틱2를 구입하지 않는 것일까?

환갑때는 반드시 당시 애플의 최고급 시스템을 써 볼 생각입니다. 물론 그 때까지 애플이 존재한다면요. 이제 현실이 될 수 있도록 일이나 열심히 해야겠습니다.
AND

유닉스 계열에서는 실제 파일뿐만 아니라 소켓, 파이프, 장치등 모든 것을 파일로 간주하고 관리합니다. (pipe에서의 사용예는 제 블로그의 pipe를 이용한 간단한 프로세스간의 통신에서 확인하실 수 있습니다.)

NSFileHandle은 코코아 파운데이션 프레임워크에 포함된 저수준의 File Descriptor와  그와 관련된 open, close, read, write등의 관련된 함수들의 래퍼 클래스입니다.

코코아에서는 겍체의 아카이브를 지원하고 xml등 데이터 타입에 따라 파일이나 URL로 부터 편리하게 읽고 쓸 수 있게 하는 클래스들이 있기 때문에, 일반적인 파일에 관련된 작업에서는 NSFileHandle을 사용하여 직접 파일을 제어할 경우는 그다지 많지 않습니다.

NSFileHandle은 데이터를 읽고 쓰는데 1바이트 바이너리로 데이터를 저장하는 NSData를 사용합니다. NSData는 많은 클래스들에서 용도에 맞게 변경하는 초기화 메소드를 제공하므로 필요에 따라 사용하시면 됩니다.

1. 파일에서 텍스트 읽기
기존에 존재하는 test.txt 텍스트 파일을 읽어 출력하는 간단한 예입니다.

* 파일 핸들러 얻기  
fileHandleForReadingAtPath로 읽기전용으로 파일을 오픈합니다. 실패시에는 nil을 반환합니다.

* 파일읽기
readDataToEndOfFile로 파일의 전체를 읽어 오고 readDataOfLength로 특정 크기만큼 읽어 올 수 있습니다.

* 파일닫기
사용을 완료하였을 경우에는 closeFile을 이용해서 열려 있는 파일을 닫습니다.

NSFileHandle *readFile;

readFile = [NSFileHandle fileHandleForReadingAtPath:@"test.txt"];
if(readFile == nil)
{
    NSLog(@"fail to read file");
    return 1;
}
   
NSData *data = [readFile readDataToEndOfFile];
NSString* text = [[NSString alloc] initWithData: data
                                                        encoding: NSUTF8StringEncoding];
NSLog(@"%@", text);

[text release];
[readFile closeFile];

2. 파일에 텍스트 쓰기
new.txt 텍스트 파일을 만들어 "new text..."란 텍스트를 입력하는 예입니다.

* 파일 생성
[[NSFileManager defaultManager] createFileAtPath:@"new.txt"
    contents: data attributes:nil];

두번째 인자인 contents에 data를 지정하여 data의 내용으로 파일이 생성됩니다. 빈 파일 생성시에는 nil로 설정합니다. 생성 후에 [writeFile writeData: data] 메소드를 이용하여 파일에 입력할 수 있습니다. NSFileManager에 관해서는 다음 포스팅에서 자세히 설명하겠습니다.

* NSFileHandle없이 파일 제어
[NSData dataWithContentsOfFile:@"new.txt"]

NSFileHandle을 거치지 않고 NSData에서 바로 파일을 읽어 올 수 있습니다. 반대로 저장도 가능합니다. 위에 언급한 것과 같이 클래스들이 파일에 관련된 메소드를 가지고 있습니다. NString도 NSData를 거치지 않고 아래와 같이 텍스트 파일에서 내용을 바로 읽어 올 수 있습니다.

NSString* readText =[NSString stringWithContentsOfFile:@"new.txt"
            encoding:NSUTF8StringEncoding error:NULL];

NSString* text = @"new text...";
NSFileHandle *writeFile;
NSData *data = [NSData dataWithBytes:[text cString]
    length:[text cStringLength]];   

[[NSFileManager defaultManager] createFileAtPath:@"new.txt"
    contents: data attributes:nil];

writeFile = [NSFileHandle fileHandleForWritingAtPath:@"new.txt"];
if(writeFile == nil)
{
    NSLog(@"fail to open file");
    return 1;
}
   
[writeFile closeFile];

/** 기록된 파일 확인 */
NSData* readData = [NSData dataWithContentsOfFile:@"new.txt"];
NSString* readText = [[NSString alloc] initWithData: readData
    encoding: NSUTF8StringEncoding];

NSLog(@"READ: %@", readText);

3. 기존 파일 변경
파일 포인터(offset) 이동
seekToFileOffset은 C에서 fseek, lseek와 같이 파일의 특정위치로 이동하게 해줍니다. 아래에 사용된 [writeFile seekToFileOffset: 2]는 파일 포인터를 두번째 바이트에 위치시키며 이후로 writeData로 기록할 때는 두번째 바이트 뒤로부터 파일에 쓰여집니다. 이와 유사하게 seekToEndOfFile는 파일의 마지막으로 파일포인터를 이동합니다.

아래는 위에서 생성한 new.txt 파일의 세번째 바이트 위치부터 test.txt 파일의 내용을 추가하는 예입니다.
NSFileHandle *readFile;
NSFileHandle *writeFile;

readFile = [NSFileHandle fileHandleForReadingAtPath:@"test.txt"];
if(readFile == nil)
{
    NSLog(@"fail to read file");
    return 1;
}

writeFile = [NSFileHandle fileHandleForWritingAtPath:@"new.txt"];
if(writeFile == nil)
{
    NSLog(@"fail to open file");
    return 1;
}

NSData *data = [readFile readDataToEndOfFile];

[writeFile seekToFileOffset: 2];
[writeFile writeData: data];

[readFile closeFile];
[writeFile closeFile];
AND

웜즈나 포트리스와 비슷한 방식의 턴제로 돌아가며 공격을 하는 게임입니다. 네트워크를 통한 멀티플레이어 게임이 가능하고 Linux, Windows, Mac, FreeBSD의 다양한 OS를 지원하며 소스도 공개되어 있습니다. 물론 공짜입니다.

2명에서 4명까지 플레이할 수 있습니다. 팀이름이 Tux, Gnu, FireFox, Thunderbird, PHP등으로 리눅스 사용자들이 아주 좋아할 만한 이름들이 입니다.

아래와 같이 Teams 메뉴에서 플레이어의 수와 팀, 이름, 케릭터 숫자를 설정할 수 있습니다. Map에서 다양한 맵들을 선택할 수 있습니다.
사용자 삽입 이미지

게임방법은 간단합니다. 플레이어들이 돌아가며 정해진 시간내에 자신의 케릭터들중 하나를 선택하여 상대방을 공격합니다.
사용자 삽입 이미지

간단한 조작 방법은 아래와 같습니다.

  • 좌우 방향키 - 이동
  • 상하 방향키 - 조준 (상세 조준:+shift)
  • space - 발사
  • 마우스 우클릭 - 무기, 아이템 선택
  • Return - 점프
  • b - 뒤로 점프
  • delete (Backspace) - 높이 점프
  • c - 현재 선택된 캐릭터를 화면중앙에 위치

캐릭터들이 귀엽게 생겨 아이들이나 여성분들도 좋아 하는 것 같습니다. 가족이나 친구들끼리 모여서 오손도손 시간 보내기에 좋은 아기자기한 게임 입니다. 현재 0.8b4 버젼(OS X는 0.8b3)까지 나와 있으며 Wormux 홈페이지에서 다운로드 받으실 수 있습니다.
AND