import java.io.FileNotFoundException
import java.io.File
import java.io.FileInputStream
import scala.collection.mutable.HashMap
class InvalidArgumentException extends Exception {}
class GetOpt(f:String) {
var _params:List[Tuple2[String,Boolean]] = null
var _opt:HashMap[Any,Any] = null
var _rest:Array[String] = null
_params = f.toList.foldLeft(List[Tuple2[String,Boolean]]()) { (l,c) =>
c match {
case ':' => l match {
case List() => throw new InvalidArgumentException
case h::r => (h._1,true)::r
}
case k => (k.toString,false)::l
}
}.reverse
def parse(a:Array[String]):GetOpt = {
def _parse(o:HashMap[Any,Any],l:List[String]):Tuple2[HashMap[Any,Any],List[String]] = l match {
case List() => (o,List())
case h::r => h.toList match {
case '-'::k => {
_params.find { e => e._1 == new String(k.toArray) } match {
case Some(Tuple2(_,true)) => {
if (r.size == 0) throw new InvalidArgumentException
o.update(new String(k.toArray),r.head)
_parse(o,r.tail)
}
case Some(Tuple2(_,false)) => {
o.update(new String(k.toArray),true)
_parse(o,r)
}
case _ => throw new InvalidArgumentException
}
}
case _ => (o,l)
}
}
_parse(new HashMap[Any,Any],a.toList) match {
case Tuple2(o,r) => { _opt = o; _rest = r.toArray }
}
this
}
def getopt(k:String):Any = _opt.isDefinedAt(k) match {
case true => _opt.apply(k)
case _ => false
}
def rest:Array[String] = _rest
}
class CTail(n:Int,f:Boolean,i:File) {
val s:FileInputStream = new FileInputStream(i)
def this(o:GetOpt) =this(o.getopt("n") match { case Some(false) => 10; case n => n.asInstanceOf[String].toInt },o.getopt("f").asInstanceOf[Boolean],new File(o.rest.apply(0)))
def tailn:Unit = {
val BUF_SIZE:Int = 4096
val e:Long = i.length
def _tailn(p:Long,n:Int,b:Array[Byte]):Array[Byte] = {
var t:Array[Byte] = null
var l:Int = n
(p > BUF_SIZE) match {
case true => {
t = new Array[Byte](BUF_SIZE)
s.getChannel.position(p - BUF_SIZE)
s.read(t,0,BUF_SIZE)
}
case _ => {
t = new Array[Byte](p.toInt)
s.read(t,0,p.toInt)
}
}
t = t.reverse.takeWhile { c => if (c == '\n') l = l - 1; (l > 0) }.reverse
((p <= BUF_SIZE) || (l == 0)) match {
case true => t ++ b
case _ => _tailn(p - BUF_SIZE, l, t ++ b)
}
}
print(new String(_tailn(e, n, new Array[Byte](0))))
s.getChannel.position(e)
}
def tailf:Unit = {
def _tailf(b:List[Byte]):List[Byte] = {
val c:Int = s.read
(c >= 0) match {
case true => _tailf(b + c.toByte)
case _ => b
}
}
print(new String(_tailf(List[Byte]()).toArray))
Thread.sleep(100)
tailf
}
def tail:CTail = {
tailn
if (f) tailf
this
}
def close:Unit = s.close
}
object Tail {
def main(args:Array[String]):Unit = {
try {
val o:GetOpt = new GetOpt("n:f").parse(args)
(new CTail(o)).tail.close
} catch {
case e:InvalidArgumentException => println("usage: scala Tail [-n <number of lines>] [-f] file")
case e:FileNotFoundException => print("file not found.")
case e:Exception => e.printStackTrace
}
}
}
lunlumo #7505() [ Scala ] Rating0/0=0.00
オプションの処理にかなり場所をとられてしまっていますが...。
import java.io.FileNotFoundException import java.io.File import java.io.FileInputStream import scala.collection.mutable.HashMap class InvalidArgumentException extends Exception {} class GetOpt(f:String) { var _params:List[Tuple2[String,Boolean]] = null var _opt:HashMap[Any,Any] = null var _rest:Array[String] = null _params = f.toList.foldLeft(List[Tuple2[String,Boolean]]()) { (l,c) => c match { case ':' => l match { case List() => throw new InvalidArgumentException case h::r => (h._1,true)::r } case k => (k.toString,false)::l } }.reverse def parse(a:Array[String]):GetOpt = { def _parse(o:HashMap[Any,Any],l:List[String]):Tuple2[HashMap[Any,Any],List[String]] = l match { case List() => (o,List()) case h::r => h.toList match { case '-'::k => { _params.find { e => e._1 == new String(k.toArray) } match { case Some(Tuple2(_,true)) => { if (r.size == 0) throw new InvalidArgumentException o.update(new String(k.toArray),r.head) _parse(o,r.tail) } case Some(Tuple2(_,false)) => { o.update(new String(k.toArray),true) _parse(o,r) } case _ => throw new InvalidArgumentException } } case _ => (o,l) } } _parse(new HashMap[Any,Any],a.toList) match { case Tuple2(o,r) => { _opt = o; _rest = r.toArray } } this } def getopt(k:String):Any = _opt.isDefinedAt(k) match { case true => _opt.apply(k) case _ => false } def rest:Array[String] = _rest } class CTail(n:Int,f:Boolean,i:File) { val s:FileInputStream = new FileInputStream(i) def this(o:GetOpt) =this(o.getopt("n") match { case Some(false) => 10; case n => n.asInstanceOf[String].toInt },o.getopt("f").asInstanceOf[Boolean],new File(o.rest.apply(0))) def tailn:Unit = { val BUF_SIZE:Int = 4096 val e:Long = i.length def _tailn(p:Long,n:Int,b:Array[Byte]):Array[Byte] = { var t:Array[Byte] = null var l:Int = n (p > BUF_SIZE) match { case true => { t = new Array[Byte](BUF_SIZE) s.getChannel.position(p - BUF_SIZE) s.read(t,0,BUF_SIZE) } case _ => { t = new Array[Byte](p.toInt) s.read(t,0,p.toInt) } } t = t.reverse.takeWhile { c => if (c == '\n') l = l - 1; (l > 0) }.reverse ((p <= BUF_SIZE) || (l == 0)) match { case true => t ++ b case _ => _tailn(p - BUF_SIZE, l, t ++ b) } } print(new String(_tailn(e, n, new Array[Byte](0)))) s.getChannel.position(e) } def tailf:Unit = { def _tailf(b:List[Byte]):List[Byte] = { val c:Int = s.read (c >= 0) match { case true => _tailf(b + c.toByte) case _ => b } } print(new String(_tailf(List[Byte]()).toArray)) Thread.sleep(100) tailf } def tail:CTail = { tailn if (f) tailf this } def close:Unit = s.close } object Tail { def main(args:Array[String]):Unit = { try { val o:GetOpt = new GetOpt("n:f").parse(args) (new CTail(o)).tail.close } catch { case e:InvalidArgumentException => println("usage: scala Tail [-n <number of lines>] [-f] file") case e:FileNotFoundException => print("file not found.") case e:Exception => e.printStackTrace } } }Rating0/0=0.00-0+
[ reply ]