特徴などの紹介

DOSのコマンドでディレクトリの情報を表示するコマンドといえば、

メリット

JavaScript?のPrototype.jsにインスパイアされて、名前をつけました。

使用例

ProcessMain?.scala

package test
object ProcessMain {
   def main(args: Array[String]): Unit = {
       //Prototype.scalaを用意した後、次の一行で呼び出す。
       import Prototype._
       println("--例1 直接こんな感じでシェルを呼び出せます。--")
       "dir ".exe //ディレクトリの情報が表示される
       
       println("--例2 値を文字列変数で取得可能です。--")
       println("dir /w".exeresult)

       println("--使い方3--")
       "dir /w".exe_eachLine{line =>
         	println(line)
       }
       
       "使い方4".p
       "文字列の表示はprintlnと同じ意味のpを用意しました。違いは値を返します。".p
       
       "2回表示して実行する例".p
       "echo aaaa".p.p.exe
       
       "実行ごとにプロセスが生成されるので、ディレクトリの移動は意味がありません".p
       "echo zzzz".exe
       "cd c:\\".exe
       "dir".exe
       
       println(currentdir)
       
   }
}

Prototype.scala

package test
import java.io._
import scala.util.DynamicVariable
import java.lang.Process
import java.util.ArrayList 

//--------------------------------
//   Object記述部分
//--------------------------------

object Prototype {
 	var currentdir :String= ""
      
   implicit def wrapBufferedReader(src: BufferedReader) = {
	    new WrapBufferedReader(src)
   }
   
   implicit def wrapString(src: String) = {
	    new WrapText(src)
   }

   implicit def wrapList_String(src: List[String]) = {
	    new WrapList_String(src)
   }
   
   implicit def wrapList_Object(src: List[Object]) = {
	    new WrapList_Object(src)
   }
   
   implicit def wrapArray_String(src: Array[String]) = {
	    new WrapArray_String(src)
   }
   
   def init_currentdir ={

		if (currentdir == ""){
		    currentdir = "cd".exeresult.chomp
		    //("カレントディレクトリを" + currentdir + "にしました").p
		} 
   }
   init_currentdir
}

//--------------------------------
//   class記述部分
//--------------------------------

//BufferedReaderにeachLineメソッドを拡張する
class WrapBufferedReader(src: BufferedReader) {
   def eachLine(f: String => Unit) {
	  var line:String = null
     while({line = src.readLine ; line != null}){
       f(line)
     }
   }
}

//Stringを拡張するメソッド
class WrapText(string : => String){
   //行末の改行を削除します。
   def chomp() :String = {
       gsub("\n$","")
   }

   //実行して結果を出力する
   def exe(current :String)  :String= {
       var result = exeresult(current)
       println(result)
       result
   }
   
   
   //実行して結果を出力する
   def exe() :String = {
   	var result = exeresult
       println(result)
       result
   }
       
   //プロセスを実行し結果の文字列を返す。
   def exeresult(current :String) :String = {
       import Prototype._
       var process:ProcessScala =  new ProcessScala
       process.current = current
       var result :String = ""
       if (string.length > 3 && string.substring(0,3)=="cd ") {
       	result = process.exeresult(string + " & cd")
       	currentdir = result
       } else {
       	result = process.exeresult(string)
       }
       result
   }    

   //プロセスを実行し結果の文字列を返す。
   def exeresult() :String = {
       exeresult("")
   }
   

   
   implicit def wrapArray_String(array: Array[String]) = {
	    new WrapArray_String(array)
   }  
   
   //実行して結果を出力する
   def exe_eachLine(current :String)(f: String => Unit) {
     val lines = exeresult(current).split("\n")
     lines.each{line=>
       f(line)
     }
   }
   
   //実行して結果を出力する
   def exe_eachLine(f: String => Unit) {
     val lines = exeresult.split("\n")
     lines.each{line=>
       f(line)
     }
  }    
   
   
   //文字列を置換します。
   def gsub(pat : String,afterstring :String) :String = {
   	string.replaceAll(pat,afterstring)
   }
   
   //List要素化
   def l() :List[String] = {
       List(string)
   }
   
   //表示println
   def p() :String = {
       println(string)
       string
   }
   
   //ファイルとして返します。
   def toFile :File = {
       new File(string)
   }
   
}

//Array[String]を拡張するクラス
class WrapArray_String(array : Array[String]){
	def each(f: String => Unit){
	   for (item <- array){
	     f(item)
	   }
   }
}

//List[String]を拡張するクラス
class WrapList_String(list : List[String]) {
 	def toArrayList() :ArrayList[String] ={
 	   var result : ArrayList[String] = new ArrayList[String]()
      for(item <- list){
   	   result.add(item)
      }
      result
 	}
}



//List[Object]を拡張するクラス
class WrapList_Object(list : List[Object]) {
 	def toList_String() :List[String] ={
      list.asInstanceOf[List[String]]
 	}
  
   def flat(): List[Object]={
       flatten(list).asInstanceOf[List[Object]]
   }
   
	def flatten(l: List[Any]): List[Any] = l flatMap {
	    case l: List[_] => flatten(l)
	    case e => List(e)
	  }
}






case class ProcessScala(currentdir :String, charset :String) {
	val dynamicvariable= new DynamicVariable[Process](null)
	var current = currentdir
	var stdout :BufferedReader = null;
   var stderr :BufferedReader = null;
	//var stdin :BufferedWriter = null;
    
   import Prototype._
   
	//デフォルトのキャラクタコードを使う
	def this() = this("","")
	
	//自動的にDestroyするProcess
	def exec(cmd:String)(block : => Unit){
      var process :Process = null
      var processbuilder = new ProcessBuilder

      //カレントディレクトリの設定
      def setting_current = {
         //値がcurrentに格納されているのなら、作業ディレクトリをセットします。
 		  if ("" != current){
       	 processbuilder.directory(current.toFile)
         }
      }
      
      //プロセスを開始します。
      def startProcess(processbuilder :ProcessBuilder){
        process = processbuilder.start
	  	 stdout = getBufferdReader(process.getInputStream(),"")
	     stderr = getBufferdReader(process.getErrorStream(),"")
      }
      
      //プロセスを作成します。
      def makeprocessByList(commands:List[String]){
		 setting_current
        processbuilder.command(commands.toArrayList())
        startProcess(processbuilder)
      } 

      //プロセスを作成します。
  	   def makeprocess(command:String) = {
		 setting_current
        processbuilder.command(command)
        startProcess(processbuilder)
      }
      
      
	   try {
	     //プロセスを作成します。コマンドラインの場合はcatchされます。
	     makeprocess(cmd)
        dynamicvariable.withValue(process){block}
	   } catch {
	      //コマンドラインをためしてみる。
	      case e:java.io.IOException =>{
	        try {
		        if (cmd.length < 7 || !(cmd.substring(0,6) == "cmd /c")){
		           //cmd /cを追加してみる
		           var commands = ("cmd".l :: "/c".l :: cmd.l).flat;
                  makeprocessByList(commands.asInstanceOf[List[String]])
				   dynamicvariable.withValue(process){block}
		        }
	        } catch { 
	          case e =>println (cmd + " is exsits?")
	            throw e
           }
         }
	   } finally {
	     //子プロセス呼び出し後は,必ず,ストリームを閉じる
	     	if (process != null) {
		        process.getErrorStream().close();
		        process.getInputStream().close();
		        process.getOutputStream().close();
		        process.destroy();
	        }
           if (stdout != null) {
           	try {stdout.close} catch {case e:IOException => }
           }
           if (stderr != null) {
           	try {stderr.close} catch {case e:IOException => }
           }
	   }
	}

	//実行結果の戻り値を返します。
	def exeresult(command :String) = {
		var result = ""
		exec(command){
	      var line:String = null
	      while({line = stdout.readLine ; line != null}){
	        result = result + line + "\n"
	      }
	   }
      result
	}


   //get dynamic variable's value
   def $_()={
       dynamicvariable.value
   } 
   
   def getBufferdReader(is:InputStream, charset :String):BufferedReader = {
       if (charset == "") {
       	new BufferedReader(new InputStreamReader(is));
       } else {
			try {
				new BufferedReader(new InputStreamReader(is, charset));
			} catch {
				case e: UnsupportedEncodingException => {
					throw new RuntimeException(e);
				}
			}   
       }
   }
}

今後の方針

トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS