관리 메뉴

새로운 시작, GuyV's lIfe sTyle.

닷넷 게시판 만들기 Part 9 - 카운터 계속. 파일 다루기. MSDN 찾기 본문

ⓟrogramming/asp.net 게시판

닷넷 게시판 만들기 Part 9 - 카운터 계속. 파일 다루기. MSDN 찾기

가이브 2011. 1. 14. 18:15

2010/11/16 - [ⓟrogramming/.net] - 닷넷 게시판 만들기 Part 1
2010/11/18 - [ⓟrogramming/.net] - 닷넷 게시판 만들기 Part 2
2010/12/08 - [ⓟrogramming/.net] - 닷넷 게시판 만들기 Part 3
2010/12/16 - [ⓟrogramming/.net] - 닷넷 게시판 만들기 Part 4
2010/12/16 - [ⓟrogramming/.net] - 닷넷 게시판 만들기 Part 5
2010/12/22 - [ⓟrogramming/.net] - 닷넷 게시판 만들기 Part 6
2011/01/04 - [ⓟrogramming/.net] - 닷넷 게시판 만들기 Part 7
2011/01/12 - [ⓟrogramming/.net] - 닷넷 게시판 만들기 Part 8

1. 닷넷 개발환경 준비, 테스트
2. 닷넷 알아보기 [7/..]
3. 게시판 글쓰기
4. 게시판 글목록
5. 게시판 글읽기
6. 다듬기

이전 시간에 이어 방문객 카운터를 마무리 해보자.

이전 시간에는 파일처리를 위해 File 클래스를 Part 6에 이어 살펴보았다. 그리고 파일에 내용을 쓰려다보니 StreamWriter 라는 클래스를 만나게 되었고, MSDN에서 StreamWriter의 WriteLine() 메서드를 이용해 파일에 내용을 써보았다. 

닷넷에서 기본으로 제공하는 이런 클래스들도 사람이 만들었고, 사람이 이용하기 때문에 클래스명, 메서드명, 프로퍼티명을 읽었을 때 대충 유추할 수 있게(설명을 읽어야 확실하겠지만) 만든 것을 알 수 있다. 

닷넷 관련 서적에서도 이런 클래스에 대해 많이 설명되어 있다. 여러가지 예제를 제시하고, 그것으로 결과물을 돌출하는데, 우리 초보들은 함정을 조심해야한다. 이 강의가 지양하고 있는게 바로 소스를 쭉 뿌려주고 설명하는 '예제 위주의 설명'방식이다. 기억하는가? 결과물은 무조건 나오게 되어있다. 그러나 필자가 처음 공부할 때를 생각하면 다르다. 명령어는 이러이러하고, 이렇게 하면 파일을 작성하게 되고 요렇게 닫아주고 저렇게 하면 된다. 라는 설명은 나에게 그 함수와 철자를 외워라는 말과 같았다.

또 잡설이 좀 길어졌는데(-_-), 프로그래밍은 외우지말고, 이 강의의 목적은, 프로그래밍(학습) 과정에서 관심을 가지며 목적을 달성하기 위해 그 해결을 찾는 법을 익히는 것이다. 물론 외우기를 추천한다. 찾는 시간이 줄어들기 때문이다. 단, 슈퍼카 보다는 소형차의 악셀을 밟는 느낌으로 공부하길 바란다. 천천히 나아가는게 더 좋은게 초보다.

다음은 이전 시간에 진행하던 count.aspx 파일이다.

count.aspx

<%@ Page Language="C#" runat="server" %>
<%@ Import Namespace = "System.IO" %>
<script language="C#" runat="server">

void Page_Load()
{
     string count_path = "c:\\home\\count.txt";
     StreamWriter sw = File.CreateText(count_path);
   
   sw.WriteLine("여기에 카운터 ㅜㅜ");
 
     sw.Close();

}


</script>



StreamWriter.WriteLine(string 내용) 메서드를 이용해서 파일에 기록을 했었다.

1. 방문객이 왔다.
2. 카운터로 계산된 파일을 연다. (Open)
3. 파일에서 카운트를 읽고(Read), 파일을 닫는다. (Close)
4. 읽은 카운트에서 +1을 한다.
5. 누적된 카운트를 파일에 저장(Open, Save) 후, 닫는다. (Close)

이 과정을 기억하는가? 이제까지 우리가 한 것은 5번인 것 같다. 이제 완성시켜보자.
먼저, count.txt 파일을 삭제하고 시작하자. count.txt 파일이 없을 때가 방문객이 아무도 없다는 가정을 두고, 파일이 없다면 1을 저장하기로 한다. 그리고 방문객이 생길 때 마다 count.txt 파일을 읽어서 +1을 하고 저장하는 과정을 반복하면 되겠다.

프로그래머 입장으로 플로우 차트를 그려보자.

1. count.aspx 웹페이지가 열릴 때,
  1) count.txt 파일이 없으면 1을 저장.
  2) count.txt 파일이 있으면 count.txt 파일에 기록된 숫자에 1을 더해서 저장
2. 현재 방문수를 특정 위치에 뿌려주기.

언제나 시작전엔 이런 정도의 예상과 상상한 후 기록하고 코딩을 시작하는 버릇을 가지자.

count.txt 파일이 있는지 없는지 확인하기 위해 귀찮은(그러나 귀찮으면 절대 안되는..) 과정으로 MSDN 페이지의 File 클래스를 열자. 파일 관련인 File 클래스에서 파일이 있는지 없는지 확인해보는 메서드나 프로퍼티가 분명 있을 것 같지 않은가? 명색이 파일관련 처리인데, 파일 읽고 쓰고 지우는 등등의 대부분의 작업이 가능할 것 같은 예상을 우리는 할 수 있다. MSDN식의 용어를 좀 붙여서 생각해보면, "파일이 존재하는지 어쩌고 저쩌고.."를 찾아보자.

다음의 내용을 읽기 전에 꼭 찾아보자. MSDN의 File 클래스 멤버 페이지에서 메서드,프로퍼티의 설명을 차근차근 읽어보자. 페이지링크는 여기에 있다: http://msdn.microsoft.com/ko-kr/library/system.io.file_members(v=VS.80).aspx 

당연히 이 강의는 결국 카운터를 만들어낼 것이다. 여러분은 아직 모르는 상황이니 꼭 직접 찾아보길 바란다. 찾는 재미도 꼭 느껴보길 바란다.

(찾은 후 페이지는 닫지말고 놔두길 바란다)
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.



필자가 File클래스 멤버에서 찾은 원하는 메서드(혹은 프로퍼티?)는 다음과 같다.


File.Exists() 메서드이다. (설명 글자가 깨져 있지만 알아먹을 만 하다 ^__^)
왜 메서드일까? 필자 생각으로는, "어떤 파일이 있는지 없는지 확인"하기 때문에, 파일의 메서드에서는 경로를 요구해야 할 것이다. 그러므로 프로퍼티로는 불가능할 것이다.

MSDN의 File클래스 멤버페이지에서 필자처럼 직접 찾아서 클릭을 해보자.


예상한 대로다. File 클래스가 static이므로 메서드도 static 형식이다. 그러므로 바로 사용할 수 있으며, 매개변수 설명에서는 string 형 1개를 요구한다. "확인할 파일입니다" 라는 설명을 보더라도 알 수 있겠다. 파일을 확인하는 메서드에서 최소한으로 요구하는 인수가 무엇이겠는가? 당연하다. 그리고 File.Exists(string path) 메서드가 반환하는 값은 bool 형태인 참/거짓(true/false) 이다. "반환 값" 항목을 읽어보자. 파일이 있으면 True, 없으면 False 이다.

즉,

File.Exists("찾을파일");

이렇게 사용할 수 있고, 반환값을 받아야 하니까,

bool bExist = File.Exists("찾을파일");

이렇게 사용해서, if() 문으로 사용하면 될 것 같다.

다음과 같은 예처럼 말이다.


static bool File.IsExist(string path) 메서드 예제

string count_path = "c:\\home\\count.txt";
bool bExist = File.Exists(count_path);
if (bExist)
{
       // 파일이 있을 때의 처리
}
else
{
      // 파일없을 때의 처리
}


조금 다듬어서, bool 형의 bExist는 따로 쓸 일이 없을 것 같으니 다음처럼 수정해도 되겠다.


static bool File.IsExist(string path) 메서드 예제

string count_path = "c:\\home\\count.txt";
if (File.Exists(count_path))
{
       // 파일이 있을 때의 처리
}
else
{
      // 파일없을 때의 처리
}


File.Exists(count_path) 자체가 bool 형이라고 보면 쉽다. 리턴이 bool 이니까.
그러므로 이렇게 if() 안에 그대로 넣어버리면 되겠다.

그럼 count.aspx 소스에 적용해보자.

count.aspx


<%@ Page Language="C#" runat="server" %>
<%@ Import Namespace = "System.IO" %>
<script language="C#" runat="server">

void Page_Load()
{
  
   string count_path = "c:\\home\\count.txt";

      if (File.Exists(count_path) == false) 
      {
          // 파일이 없을 때
          StreamWriter sw = File.CreateText(count_path);   
          sw.WriteLine("1");   
          sw.Close();


      }

      else
      {
         // 파일이 있을 때
      }

}


</script>



추가된 코드는 진한 갈색이다. 파일이 없을 때 처리를 위에 놓기 위해 if()를 변형했다.

      if (File.Exists(count_path) == false)

이것은, 다음 코드와 동일하다.

      if (!File.Exists(count_path))

느낌표가 보이는가? bool 형의 앞에 느낌표를 붙여주면 바꿔준다. 파일이 없다면 false를 리턴하니, 이것을 true로 변형하면 되겠다.
if() 는 괄호안의 내용이 '참(true)'일 때 중괄호의 내용이 실행되니까.

if() 문은 다음과 같이 사용가능하다.
   
     if (조건이 참이면)
     {
           여기를 실행
      }
      else if (또다른 조건이 참이면)
      {
               여기를 실행
       } 
      else
      { 
              이도 저도 아니면 여기를 실행
      }
 
이제 (count.txt)파일이 있을 때를 처리해보도록 하자. 파일이 있을 때는 기존의 파일 내용을 읽어와야 한다. 이제 우린 어떻게 해야할까? 그렇다! MSDN을 자동반응으로 열자. 역시 File 클래스 멤버페이지를 열어서(앞에서 열어놨지 않은가? 귀찮을 것도 없다. ^^;) 이제 파일을 읽어오는 메서드를 한번 찾아보자. 역시 어떤 파일을 읽어올 것인지 정해야 되기 때문에 메서드일 가능성이 높을 것 같다.

IsExist() 메서드를 찾은 것 처럼, 이번에도 필자가 찾을 동안 여러분들도 꼭 직접 찾아보길 바란다.


설명을 보니 여러 메서드가 애매모호하게 있다. 뭐든지 이용하면 될 것 같다.
그렇다면, 여기서, 이 항목은 여러분이 필자의 다음 해결 내용을 보지 마시고 직접 파일을 읽어오는 부분을 완성하는 숙제를 내여드리겠다. ^^ 웬 숙제냐고 하지마시길. 원래 선생(?)의 마음이 다 그렇다. -_- 강의를 듣는 여러분들이 직접 무언가를 하길 바라는 심정이라고 할까?

강의를 잘 따라오셨다면 별 문제 없이 해결할 수 있으리라 생각든다.

1. OpenText() 메서드를 사용하기로 한다.
2. OpenText() 메서드는 파일을 읽는 용도로 StreamReader 클래스를 사용한다.
3. MSDN에서 StreamReader 클래스를 참고하고, 한 줄 읽어오는 메서드를 찾아본다. (이는 StreamWriter와 거의 동일할 것이다)
4. string형 변수 "now_count"에 count.txt 파일의 한 줄을 읽는다.

이정도의 힌트라면 해결할 수 있지 않을까? 성공해도 되고, 실패해도 된다. 여러분이 직접 MSDN에서 파일을 열어서 읽어오는 메서드를 알아보고 사용했다는 것이 이 강의의 어떤 부분보다 중요하다고 생각하기 때문이다.


그리고 다음의 소스를 열어보자.


StreamWriter 클래스와 거의 사용법이 동일하다.

앞에서 힌트드린 대로, File.OpenText("파일경로") 메서드는 StreamReader 클래스를 리턴하고, StreamReader 형식으로 받아서, MSDN에 나와있는 ReadLine() 메서드를 이용해 한 줄을 읽있다. ReadLine() 메서드는 한 줄 읽은 내용을 string 형식으로 리턴하므로 string변수 "now_count" 변수에 담았다. 마지막으로 파일의 점유를 끊기 위해 StreamReader.Close() 메서드로 파일을 닫아준다.

이 처럼, 아직 완성되지 않은 부분이 있다. 카운터는 기존의 파일을 읽어서 +1을 시켜야 방문객이 한명 한명 늘어나게 될 것이다. 또한 그 결과를 파일로 저장해야 할 것이다.

기존의 방문객은 now_count 라는 string 변수가 있다. 이것을 연산이 가능한 int 형으로 변환하기 위해서는 어떻게 해야할까? 또 한번 MSDN의 바다로 빠져볼까??!

IntXX.Parse() 라는 static 메서드가 있다. 앞으로 자주 사용할 Parse() 라는 메서드 시리즈인데,
C#에서 제공하는 자료형의 대부분에서 제공한다. 자료의 크기에 따라 Int16,Int32,Int64 등 모두 같은 방법으로 사용할 수 있다. 

아주 예전에 int 는 System.Int32 구조체의 축약이라고 한 것을 기억하는가? (이전 강의에서는 클래스라고 한 점을 정정합니다) short, int, long, double 등 숫자의 형식이나 크기에 따라 해당 구조체가 여러가지 있다고 했었다. 지금은 그냥 넘어가도록 하자.

http://msdn.microsoft.com/ko-kr/library/system.int32.parse(v=VS.80).aspx
여기를 클릭해서 Int32.Parse() 에 대한 메서드의 목록을 보고, 일반적으로 가장 많이 사용되는 Int32.Parse(string)의 설명을 읽어보자.

System.Int32 구조체가 int 이므로  int 형으로 리턴하고, 숫자형 문자를 정수로 변환하는 기능이니, string은 "3231", "123" 등과 같은 변환할 수 있는 숫자여야된다. 이는 꼭 숫자로만 이루어져야 하며, 해당 구조체의 형식에 맞아야 한다. Int32 형이 표현하는 숫자여야 한다는 의미이다. Int32.Parse("32,21,2") 과 같이 잘못 사용되면 오류(예외, Exception)가 발생한다.

사용하기 위한 코딩은 메서드에 대해 이제 적응이 되셨으리라 생각한다.
System은 기본적으로 참조하는 최상위 네임스페이스 이름이므로 생략가능하다. (물론 붙여줘도 잘 작동한다)

int ABC = Int32.Parse("12");             // ABC=12
int ABC = Int32.Parse("301") + 1;      // ABC=302
int ABC = Int32.Parse("5") * 10;       // ABC=50

이렇게 연산이 가능한 숫자로 변환이 가능하게 되었으니, 읽어온 now_count 변수를 Int32.Parse()로 변환하여 +1을 하도록 하자. 그리고 이를 저장하는 것까지 해서 코드부분이 완성된 카운터 소스이다.

count.aspx


<%@ Page Language="C#" runat="server" %>
<%@ Import Namespace = "System.IO" %>
<script language="C#" runat="server">

void Page_Load()
{
 string count_path = "d:\\homeasp\\count.txt";


      if (File.Exists(count_path) == false)
      {
           // 파일이 없을 때
           StreamWriter sw = File.CreateText(count_path);
           sw.WriteLine("1");
           sw.Close();
      }
      else
      {
           StreamReader sr = File.OpenText(count_path);
           string now_count = sr.ReadLine();   
           sr.Close();

           int new_count = Int32.Parse(now_count)+1;
           StreamWriter sw = File.CreateText(count_path);
           sw.WriteLine(new_count);
           sw.Close();
        
      }

}

</script>


진하게 색칠된 소스가 추가된 소스이다.

여기서 잠시, StreamWriter.WriteLine() 에 한줄 쓰는 인수로 int 형이 들어갈 수 있는 이유는 무엇인가? 우리는 앞에서 MSDN을 함께 봤다. 여러 자료형을 받을 수 있게 메소드가 오버로드 되어있기 때문에 가능한 것이다. 가져다 쓰는 사용자의 편의성을 고려했다고 할 수도 있겠다. ^^

이렇게 완성되었으면, count.txt 파일을 삭제하고 이제 실행해보자.
한번 실행 후 count.txt 파일이 잘 생성이 되었는가? 열어보고 우리가 넣었던 "1"이 잘 들어갔는지 확인하자. 그리고 다시 실행해보자. 이제부터 실행할 때마다 2, 3, 4, ... 이렇게 숫자가 증가해야 할 것이다. 잘 작동하는가?

1. count.aspx 웹페이지가 열릴 때,
  1) count.txt 파일이 없으면 1을 저장.
  2) count.txt 파일이 있으면 count.txt 파일에 기록된 숫자에 1을 더해서 저장
2. 현재 방문수를 특정 위치에 뿌려주기.

드디어 코드 부분은 완성이 된 것 같다.
이제 우리가 원하는 빨간색에 이 숫자를 뿌려줘야 한다.

예전 강의에서 훼이크 구구단 기억하는가? ^^
그 때는 뭔지 몰랐던 메서드가 있다. 화면에 무조건 뿌리는 기능을 하는 Response.Write() 라는 메서드가 그것이다.

이 메서드를 이용해서 aspx 파일에서 그대로 방문객을 뿌려보자.
그런데 소스를 가만히 보니, 파일이 없을 때는 변수가 존재하지 않는다. 파일이 있을 때의 처리는 new_count 를 뿌려주면 될 것 같지만 말이다.

그래서, 하나의 변수를 선언해서 넣기로 하자.

string count_path 변수 하단에 방문객 int형 변수를 넣자.

int new_count = 1;

기본값은 1로 주기로 하자. 왜냐면 파일이 없을 때 들어온 방문객은 첫 번째 방문객이기 때문이다. 그리고 파일이 있을 때, 즉 기존 방문객이 있었을 때에 방금 선언한 new_count 와 파일을 읽어와서 +1을 해주는 변수와 중복되므로, 변수 선언만 지워주면 잘 작동할 수 있다.

그리고 new_count 를 Response.Write() 로 찍어보자.

count.aspx -수정된 Page_Load() 그리고 출력.

void Page_Load()
{
      string count_path = "d:\\homeasp\\count.txt";
     int new_count = 1;


      if (File.Exists(count_path) == false)
      {
            // 파일이 없을 때
            StreamWriter sw = File.CreateText(count_path);
            sw.WriteLine("1");
            sw.Close();
     }
    else
    {
            StreamReader sr = File.OpenText(count_path);
            string now_count = sr.ReadLine();   
            sr.Close();

          new_count = Int32.Parse(now_count)+1;
            StreamWriter sw = File.CreateText(count_path);
            sw.WriteLine(new_count);
            sw.Close();
        
      }

         Response.Write(new_count);

}


진하게 표시된 부분이 추가되거나 수정된 부분이다.
이제 실행해보자. 여러번 실행해보고, 카운터가 잘 되는지 확인해보자.


실행결과가 위와 같다. 디자인 측면에서 우리가 원하는 결과물이 아니다.
익스플로러에서 이 결과에 대한 소스보기를 해보자.


Response.Write() 는 코드 수행 중에 출력된다. 물론 맨 마지막 줄에 넣었지만..
asp.net 의 소스코드는 어떤 무엇보다 먼저 실행되며, 태그는 그 결과물일 뿐이라고 했다. 

카운터 프로그램의 최종 완료본은 <font..></font> 태그 사이에 이 숫자를 넣는것이다.

그러나 아쉽지만, 카운터 프로그램은 여기서 끝내도록 하겠다. 왜냐고 말한다면, 필자가 언제나 강조했던 말을 기억해달라. "결과물은 언젠가는 나오게 되어 있다".


이로서, 2장인 닷넷 알아보기는 총 7회에 걸쳐서 종료를 하려고 한다.
2장의 가장 큰 목표였던, 네임스페이스, 클래스, 메서드, 프로퍼티의 간략한 설명과 MSDN에서 클래스 찾아서 사용해보기를 아주 간단하지만 중요하게 다루어 보았다. (매우 일부분이지만..)

이번 2장을 통해 여러분들이 닷넷 프로그래밍에 대한 거부감을 좀 더 덜었으면 하는 생각이다.

다음장은 우리는 asp.net 을 이용하고 있기 때문에, asp.net 의 UI(User Interface)인 컨트롤(Control)에 대해 알아보겠다. 결코 여러분들을 암기의 제왕으로 만들지 않겠다. 

어떤 컨트롤이 있는지만 알아보고, 어떻게 찾아쓰는지 알면 외운거나 마찬가지이기 때문이다.
그럼 다음장에서 만나뵙도록 하자.


수고하셨습니다. :)

반응형
Comments