我使用 InetAddress 来解析 IP 地址,但现在如果 IP 不可用,则需要存储主机名。所以我介绍了一个班级Host。
case class Host(name:String, ip:InetAddress) {
import Host.{addressToBytes, compareSeqs}
override def toString:String = if (ip!=null) {ip.getHostName} else {name}
}
object Host {
implicit def stringToPattern(s:String): Pattern = Pattern.compile(s)
val separators = Seq[Pattern]("\\.", ":")
def separatedStrToBytes(s:String, separator:Pattern): Array[Byte] = {
val fields = separator.split(s)
var rv = new Array[Byte](fields.length);
fields.map(_.toInt.toByte).copyToArray(rv, 0)
rv
}
implicit def strToBytes(s:String): Array[Byte] = {
for (sep <- separators)
if (sep.matcher(s).find())
return separatedStrToBytes(s, sep)
null
}
implicit def strToHost(s:String):Host = {
var name = s
var ip:InetAddress = null
try {
val bytes = strToBytes(s)
if (bytes != null) {
ip = InetAddress.getByAddress(bytes)
// println( "parsed ip: "+s)
}
} catch {
case e:UnknownHostException =>
}
if (ip==null) {
ip = InetAddress.getByName(s)
}
new Host(name, ip)
}
}
进行此更改后,我的软件开始失败,并在 sepedStrToBytes 中显示“java.lang.OutOfMemoryError:超出 GC 开销限制”。我在这里犯过任何内存处理错误吗?
我感谢任何有关设计的评论。由于需要 Array[Byte] 作为 InetAddress.getByAddress 参数,我无法缩短解析时间。目标平台有Scala 2.7.7。
EDIT:我已经用假人替换了解析,并发现我的程序稍后在其他地方仍然无法解析几兆字节的数据。每次用 Pattern.split(s:String) 和预编译模式替换 String.split(s:String) 都会使其运行时间稍微长一些。这并不能解决我的问题,但这个问题现在可能已经结束了。不过我仍然需要设计评论。
您的代码在 2.8.0 上运行得很好(您应该考虑迁移到它,因为它已经是最终版本并且非常稳定) - 没有检测到 OutOfMemory。
您要求的一些优化:
implicit def strToBytes(s:String)= (for {separator <- separators find(_.matcher(s).find)} yield separatedStrToBytes(s, separator)) getOrElse null
implicit def separatedStrToBytes(s:String, separator:Pattern) = s split separator.pattern map(Integer.parseInt(_).toByte)
scala> import Host._
import Host._
scala> strToBytes("127.0.0.1")
res9: Array[Byte] = Array(127, 0, 0, 1)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)