2013년 9월 11일 수요일

Perl 제대로배우기 - 13장(File and Directory handle)

13. File and Directory handle

파일 제거
unlink 함수를 사용 한다.
** 하드링크를 별도로 만들지 않았다면
unlink 함수의 리턴형은 삭제된 파일 수
여러 파일 삭제
예)
unlink (“cow”,”boy”); #두 파일 삭제
unlink <*.o>; #쉘에서 rm *.o와 동일

foreach $file (<*.o>){
 unlink($file) || warn “having trouble deleting $file: $!”;
}
foreach (<*.o>){
 unlink || warn “having trouble deleting $_: $!”;
}

파일 이름 변경
rename 함수를 사용 , 리턴값은 성공 - true(not zero), 실패 - false (0)
rename (“huni”,”yuni”) || die “Can’t rename huni to yuni : $!”;
rename (“yuni”,”dana/yuni”) || die “Can’t rename yuni to dana/yuni : $!”;
mv와 틀리게 반드시 dana라는 디렉토리가 존재해야 한다.
파일에 대한 다른 이름 생성: 링킹
링킹이란 : 한 파일에 대한 다른 이름을 만드는 연산
링킹의 두가지 유형 : 하드링크 와 심볼릭(소프트)링크
하드링크와 소프트링크에 대해
OS(POSIX) 특정 시간(임의의)에 하드 링크에 대한 계수(count)를 유지 한다. 처음 생성되면 하나의 링크를 생긴다.
** 하드링크는 디렉토리에는 제한 됩니다. (생성불가)
심볼릭링크 : 경로명을 데이터로 담고 있는 특별한 종류의 파일

Perl로 하드링크와 소프트링크 생성하기
하드링크 생성 명령 : ln file link_name
심볼릭링크 생성 명려어 : ln -s file link_name
link ("huni","huni_hLink") || die "can't link huni to huni_hLink:$!";
symlink ("huni","huni_sLink") || die "can't symlink huni to huni_sLink:$!";

정보 읽기 (심볼릭링크만 읽을수 있다.)
if(defined($x = readlink(“huni_sLink”))){
 print “huni_sLink points(symlink) at ‘$x’\n”;
}

디렉토리 생성과 제거
mkdir 함수 : 디렉토리 생성
예) mkdir(“huni_dir”,0777) || die “can’t mkdir huni_dir:$!”;
rmdir 함수 : 디렉토리 삭제
예) rmdir(“huni_dir) || die “can’t rmdir huni_dir:$!”;
** 지울 디렉토리에 파일 존재하면 디렉토리 삭제 불가
허가권 변경
chmod 함수 : 권한 변경
foreach $file(“fred”,”barney”){
 unless (chmod (0666,$file)){
   warn “couldn’t chmod $file:$!”;
 }
}
소유권 변경
chown 함수 : 소유권 변경
chown(1234,25,”huni”,”yuni”); # 1234 - UID, 35 - GID , ”huni”,”yuni” :: 파일명
시간표시 변경
utime 함수 : 시간표시 변경
time 함수 : 현재 시간 (단위 초단위)
** 시간은 1970/1/1 부터 경과한 초단위
$atime = $mtime = time() - 20 * 60; 현재 부터 20분전에 시간으로 변경해요
utime ($atime ,$mtime ,”huni”);
$atime : access time (1)
$mtime : modify time (2)
** 마지막 inode 수정 시간 : 설정 방법이 없다.

Perl 제대로 배우기 - 12장(Directory Access)

12. Directory Access
디렉토리 트리에서의 이동
  • shell ::  cd
  • system call :: chdir
  • perl :: chdir
ex) chdir(“/etc”) || die “cannot change directory /ect ($!)”;

print “where do you want to go?”;
chomp ($where = <STDIN>);
if (chdir $where){
# success
}else{
# fail
}

글로빙
shell : * 명령행 인수를 받아서 이를 현재 디렉토리에 있는 파일이름의 리스트로 바꾼다.
즉 쉘에서 * 명령행 인수를 실행하는 것과 같다.
@a = </etc/host*>;  --> 정규식 방식
혹은 @a = glob(“/etc/host*”);
만약 존재하지 않으면 공백리스트를 리턴 한다. 그러므로 defined 함수를 사용하여 존재 유무를 파악한다.
복수개의 패턴을 허용함.
while(defined($nextname = </etc/host*>)){
print “one of the files is $nextname\n”;
}

<${var}>를 사용하라 .. <$var>가 아니라.

디렉토리 핸들
- os에서 readdir를 제공할 경우 Perl은 디렉토리 핸들을 제공한다.
디렉토리 핸들 열고 닫기
예)
opendir (ETC,”/etc”) || die “Cannot opendir /etc : $!”; #열기
closedir(ETC); #닫기
디렉토리 핸들 읽기
opendir 이후 readdir를 이용하여 이름 목록을 읽을 수 있다.
** readdir는 단지 파이 이름만을 리턴 한다. 더이상 디렉토리가 없으면 undef를 리턴 한다.
예)
opendir (ETC,”/etc”) || die “no exist etc : $!”;
while ($name = readdir(ETC)){
print “$$name = $name\n”;
}
closedir(ETC);
알파벳 순서로 읽는 방법
foreach $name (sort readdir(ETC)) 로 변경 합니다.
여기서는 . 도 포함 한다. <*>는 .을 포함하지 않는다.

2013년 9월 10일 화요일

[Head First]Servlets & JSP 내용정리-13장

Chapter.13

필터와 랩터


필터
  • 전체 웹 애플리케이션 기능을 확장. 예) 보안, 혹은 , 요청에 대한 로그
  • 일반 자바 컴포넌트, 서블릿으로 요청 처리전 , 클라이언트에게 넘겨가기전 응답을 가로채어 처리 할 수 있다.
  • Request 필터로 처리 할만것들
    • 보안 관련 내용을 체크
    • 요청 헤더와 바디 포맷팅을 수정
    • 요청을 감시하거나 기록으로 남김
  • Response 필터로 처리 할만것들
    • 응답스트림을 압축
    • 응답스트림에 내용을 추가하거나 수정함.
    • 완전 다른 새로운 응답을 만듬.
  • 필터 인터페이스는 Filter 하나 임.
  • 모듈식으로 DD에서 설정
  • Servlet와 비슷한 3 가지
    • 컨테이너가 이들 API를 알고 있음.
    • 컨테이너가 생명주기를 관리함.
    • DD에 설정함.
  • 필터는 누가 자신을 불렀는지 자기 다음에 누구인지 모름
  • 필터의 생명주기
    • 제일 먼저 init() : FilterConfig 객체를 저장하는 역할이 주
    • doFiler() 처리할 것이 많음.
    • 마지막으로 destroy() : 필터 삭제전에 할 작업
  • 필터는 컨테이너에 의해서 stack 처럼 처리 된다.
  • DD에서 필터 설정으로 할 수 3가지 내용
    • 필터의 정의
    • 필터링해야 할 리소스와 필터를 맵핑 할수 있음.
    • 순서대로 필터가 호출될 수 있도록 정렬 할 수 있음.


DD에서 필터 설정
필터 정의
<filter>
 <filter-name>BeerRequest</filter-name>
 --------------------------------------
 필수 - 필터 이름
 <filter-class>com.example.web.BeerRequestFilter</filter-class>
 -------------------------------------------------------------
 필수 - 필터 클래스 이름(패키지명 포함)
 <dispatcher>REQUEST | INCLUDE | FORWARD | ERROR </dispatcher>
 -------------------------------------------------------------
 2.4 부터 가능함. (0..4) 포함 가능함.
  • REQUEST : 클라이언트의 요청 (기본값 : 항목이 없는 경우)
  • INCLUDE : include에 적용
  • FORWARD : 클라이언트의 요청을 다른 곳으로 넘길때(forward)
  • ERROR   : error 핸들러를 호출하였을 때
 <init-param>
    <param-name>LogFileName</param-name>
    <param-value>UserLog.txt</param-value>
 </init-param>
 -------------
 선택 - 여러개 존재해도 됨.
</filter>


URL 패턴과 필터 맵핑 선언하기
<filter-mapping>
 <filter-name>BeerRequest</filter-name>
 --------------------------------------
 필수 - filter의 <filter-name>에 존재해야 함.
 <url-pattern>*.do</url-pattern>
 -------------------------------
 필수 - <url-pattern> 혹은 <servlet-name> 중 하나는 존재해야 함.
</filter-mapping>


서블릿 이름에 필터 맵핑 선언하기
<filter-mapping>
 <filter-name>BeerRequest</filter-name>
 <servlet-name>AdviceServlet</servlet-name>
</filter-mapping>



중요 컨테이너가 필터 순서를 정하는 규칙 : 하나의 리소스에 대한 여러 개의 필터가 적용되는 경우
  1. URL 패턴으로 적용되는 필터가 제일 먼저 옴.DD에 정의된 순서대로 체인에 하나씩 들어간 다음 실행됨.
  2. URL 패턴이후에 <servlet-name>으로 정의된 필터를 찾아 정의된 순서대로 체인에 등록함.


버젼 2.4 부터 요청 디스패처로 들어오는 것도 필터에 적용할 수 있음.
forward, include , request , dispatch ,error


압축필터에 대한 의사 코드(응답필터)
class MyCommpressionFilter implement Filter{
 init();
 
 public void doFilter(request, response,chain){
   // 요청에 대한 처리가 들어감.
   chain.doFilter(request,response); //서블릿이 자기 한일을 함.
   // 압축로직이 들어갈 자리
 }
}


새로운 응답 객체를 만들어 하는 이유
  • 클라이언트로 넘어가는 것을 제어 하기 위해서
  • Wrapper 클래스를 사용하는 새로운 Response 객체를 생성한다.


Wrapper Basic
  • 원본 request, response 객체를 내부에 감싸고, 자신에게 들어오는 모든 메소드를 바로 이 객체로 위임하는 식으로 메소드를 구현함.
  • 개발자의 역할은 랩퍼 클래스를 상속하고 필요한 메소드를 재정의 함.
  • 대표적인 랩퍼 클래스들 : AWT의 Event Listener Adapter 클래스들
  • 서블릿에서 제공하는 4개의 랩퍼 클래스
    • ServletRequestWrapper
    • HttpServletRequestWrapper
    • ServletResponseWraper
    • HttpServletResponseWraper
실제 압축 필터 코드
압축 필터 코드 예제)
... 생략 패키지 구문 및 import 구문


public classs CompressionFilter implements Filter{
 private ServletContext ctx;
 private FilterConfig cfg;
 public void init(FilterConfig cfg) throws ServletException{
   this.cfg = cfg;
   ctx = cfg.getServletContext();
   ctx.log(cfg.getFiltername() + “ initialized.”);
 }
 public void doFilter(ServletRequest req,ServletResponse resp,FilterChain fc) throws IOException, ServletException {
   HttpServletRequest request = (HttpServletRequest)req;
   HttpServletResponse response = (HttpServletResponse)resp;


   String valid_encodings = request.getHeader(“Accept-Encoding”);
   if( valid_encodings.indexOf(“gzip”) > -1){
     CompressionResponseWrapper wrappedResp =
        new CompressionResponseWrapper(response);
     -------------------------------------------
     압축 랩퍼 클래스 생성
     wrappedResp.setHeader(“Content-Encoding”,”gzip”);
     -------------------------------------------------
     응답 컨덴츠가 gzip으로 인코딩됨을 선언하는 부분
     fc.doFilter(request,wrappedResp);
     ---------------------------------
     체인에 있는 다음 컴포넌트를 호출합니다.


     GZIPOutputStream gzos = wrappedResp.getGZIPOutputStream();
     gzos.flush();
     -------------
     원본 스트림으로 모든 테이터를 전송합니다.
     ctx.log(cfg.getFilterName() + “: finished the request.”);
   }else{
     ctx.log(cfg.getFilterName() + “: no encoding performed.”);
   }
 }
 public void destroy(){
   // 인스턴스 변수들을 null 처리 한다.
   cfg = null; ctx = null;
 }
}


압축이 HTTP를 만났을 때

  • 브라우저가 보내는 헤더 중 하나인 “Accept-Endcoing:gzip”은 서버에게 이런 컨덴츠를 다룰 수 있다고 할려 주는 것입.
  • 브라우저가 압축 데이터를 처리할 수 있으면 서버는 헤더에 “Content-Encoding:gzip”을 추가해서 컨덴츠가 압축되었음. 알려 주어야 한다.
  • 브라우저를 위 정보를 확인 하고 화면을 출력하면 압축을 풀어야 함을 알게된다.