2011-03-31 4 views
1

저는 배우를 배우기 위해 간단한 제작자 클래스를 작성하려고했습니다. 필자는 File 객체로 표현 된 디렉토리로 시작하여 파일을 처리하기 위해 다른 액터로 메시지를 보내는 제작자를 원했습니다. 처음에는 파일의 내용을 읽었지 만 단순하게하기 위해 이제는 경로 만 수집하고 있습니다. 다시 한 번 말하지만, 이것은 현실 세계에서 가치가 없지만 배우가 더 잘 이해할 수있게 해 주므로 실용적인 가치가 있습니다. 여기에 지금까지 무엇을 : 그것은 지금 상태에서이 간단한 제작자 액터 예제가 작동하도록하려면 어떻게해야합니까?

import java.io._ 
import java.util.concurrent._ 
import scala.actors.Actor 
import scala.io.Source 
import java.util.concurrent.locks.ReentrantLock 
import java.util.concurrent.atomic.AtomicLong 

case class FileSystemObject(path:File) 
case class FileContent(content:String) 

case object Stop 
case object Processed 

class ResultAcumulator extends Actor { 

    var results:List[String] = Nil 
    var finished = false 

    def act() = { 
     loop { 
      react { 
       case FileContent(content) => { 
        results ::= content 
       } 
       case Stop => { 
        finished = true; 
        exit 
       } 
      } 
     } 
    } 
} 

class FileSystemReader(accumulator:Actor) extends Actor { 
    def act() = { 
     loop { 
      react { 
       case FileSystemObject(path) => { 
        if(path.isFile) { 
         accumulator ! FileContent(path.toString) 
         sender ! Processed 
        } 
       } 
       case Stop => exit 
      } 
     } 
    } 
} 

class FileSystemProducer(start:File,acumulator:Actor,reader:Actor) extends Actor { 
    var totalFilesProcessed = 0 

    def act() = { 
     val files = start.listFiles 
     files.foreach{ f => 
      (reader ! FileSystemObject(f)) 
     } 
     loop { 
      react { 
       case Processed => { 
        totalFilesProcessed += 1 
        if(totalFilesProcessed == files.length) { 
         reader ! Stop 
         acumulator ! Stop 
         Xo.decrementLatch 
        } 
       } 
      } 
     } 

    } 
} 
object Xo { 

    var latch = new CountDownLatch(1) 

    def decrementLatch = latch.countDown 

    def main(args : Array[String]) = { 

     val acumulator = new ResultAcumulator 
     val fsReader = new FileSystemReader(acumulator) 
     val producer = new FileSystemProducer(new File("d:/rails/a"),acumulator,fsReader) 

     acumulator.start 
     fsReader.start 
     producer.start 

     latch.await 

     acumulator.results.foreach(println) 

    } 
} 

, 영원히 실행하고 나는 어떤 출력을 볼 수 없습니다. 아, 한 가지 더. 프로그램이 끝나기 전에 "처리 된"결과를 나열하고 싶습니다. 나는 조금 주위를 조사하고 CountDownLatch 클래스를 발견했다. 이 루프를 구현하는 유지하고 싶습니다/반응하는 대신 잠깐 /받습니다. 나는 문제가 나는이 라인을 가지고 있다는 사실에 의해 발생 확신 :

files.foreach{ f => 
    (reader ! FileSystemObject(f)) 
} 

내가 조금 낮은 반응 루프를 가지고,하지만 난 아무 단서 어떻게 고치는 갈해야합니다.

답변

3

는 I은 관련 부분 경우 FileSystemObject를 (경로) => { 경우 (path.isFile) { 어큐뮬레이터라고 생각한다! FileContent (path.toString) 보낸 사람! 처리 됨 } } "정상적인 파일"이 아닌 디렉토리 (예 : 디렉토리)는 누적기로 보내지지 않습니다. "d :/rails/a"에 서브 디렉토리가있는 경우 totalFilesProcessed == files.length 테스트는 항상 실패합니다.

+0

네가 맞아! 나는 그것을 어떻게 놓쳤는가? 그러나 그것이 유일한 문제는 아닌 것 같습니다. 거기도 출구가 필요했습니다. – Geo

관련 문제