java.nio.ByteBuffer wrap 方法部分与 sbt 一起使用 运行
java.nio.ByteBuffer wrap method partly working with sbt run
我有一个问题,我从一个大文件 ~ (100MB) 中读取了一个字节流,并且在一些整数之后我得到了值 0(但仅限于 sbt 运行 )。当我点击 IntelliJ 上的播放按钮时,我得到了我期望的 > 0 的值。
我的猜测是环境有所不同。但是我看不出有什么不同。
// DemoApp.scala
import java.nio.{ByteBuffer, ByteOrder}
object DemoApp extends App {
val inputStream = getClass.getResourceAsStream("/HandRanks.dat")
val handRanks = new Array[Byte](inputStream.available)
inputStream.read(handRanks)
inputStream.close()
def evalCard(value: Int) = {
val offset = value * 4
println("value: " + value)
println("offset: " + offset)
ByteBuffer.wrap(handRanks, offset, handRanks.length - offset).order(ByteOrder.LITTLE_ENDIAN).getInt
}
val cards: List[Int] = List(51, 45, 14, 2, 12, 28, 46)
def eval(cards: List[Int]): Unit = {
var p = 53
cards.foreach(card => {
println("p = " + evalCard(p))
p = evalCard(p + card)
})
println("result p: " + p);
}
eval(cards)
}
HandRanks.dat可以在这里找到:(我把它放在一个名为资源的目录中)
https://github.com/Robert-Nickel/scala-texas-holdem/blob/master/src/main/resources/HandRanks.dat
build.sbt 是:
name := "LoadInts"
version := "0.1"
scalaVersion := "2.13.4"
在我的 windows 机器上,我使用 sbt 1.4.6 和 Oracle Java 11
您会看到 evalCard
调用将工作 4 次,但在第五次之后 return 值为 0。它应该大于 0,这是在使用 IntelliJ 的播放按钮时.
您没有阅读全部内容。这个
val handRanks = new Array[Byte](inputStream.available)
仅分配 InputStream
缓冲区,然后您使用
读取缓冲区中的数量
inputStream.read(handRanks)
根据默认设置,您将处理不同数量的数据,但它们永远不会是 100MB 的数据。为此,您必须将数据读入循环中的某个结构(坏主意)或分块处理(使用迭代器、流等)。
import scala.util.Using
// Using will close the resource whether error happens or not
Using(getClass.getResourceAsStream("/HandRanks.dat")) { inputStream =>
def readChunk(): Option[Array[Byte]] = {
// can be done better, but that's not the point here
val buffer = new Array[Byte](inputStream.available)
val bytesRead = inputStream.read(buffer)
if (bytesRead >= 0) Some(buffer.take(bytesRead))
else None
}
@tailrec def process(): Unit = {
readChunk() match {
case Some(chunk) =>
// do something
process()
case None =>
// nothing to do - EOF reached
}
}
process()
}
我有一个问题,我从一个大文件 ~ (100MB) 中读取了一个字节流,并且在一些整数之后我得到了值 0(但仅限于 sbt 运行 )。当我点击 IntelliJ 上的播放按钮时,我得到了我期望的 > 0 的值。
我的猜测是环境有所不同。但是我看不出有什么不同。
// DemoApp.scala
import java.nio.{ByteBuffer, ByteOrder}
object DemoApp extends App {
val inputStream = getClass.getResourceAsStream("/HandRanks.dat")
val handRanks = new Array[Byte](inputStream.available)
inputStream.read(handRanks)
inputStream.close()
def evalCard(value: Int) = {
val offset = value * 4
println("value: " + value)
println("offset: " + offset)
ByteBuffer.wrap(handRanks, offset, handRanks.length - offset).order(ByteOrder.LITTLE_ENDIAN).getInt
}
val cards: List[Int] = List(51, 45, 14, 2, 12, 28, 46)
def eval(cards: List[Int]): Unit = {
var p = 53
cards.foreach(card => {
println("p = " + evalCard(p))
p = evalCard(p + card)
})
println("result p: " + p);
}
eval(cards)
}
HandRanks.dat可以在这里找到:(我把它放在一个名为资源的目录中) https://github.com/Robert-Nickel/scala-texas-holdem/blob/master/src/main/resources/HandRanks.dat
build.sbt 是:
name := "LoadInts"
version := "0.1"
scalaVersion := "2.13.4"
在我的 windows 机器上,我使用 sbt 1.4.6 和 Oracle Java 11
您会看到 evalCard
调用将工作 4 次,但在第五次之后 return 值为 0。它应该大于 0,这是在使用 IntelliJ 的播放按钮时.
您没有阅读全部内容。这个
val handRanks = new Array[Byte](inputStream.available)
仅分配 InputStream
缓冲区,然后您使用
inputStream.read(handRanks)
根据默认设置,您将处理不同数量的数据,但它们永远不会是 100MB 的数据。为此,您必须将数据读入循环中的某个结构(坏主意)或分块处理(使用迭代器、流等)。
import scala.util.Using
// Using will close the resource whether error happens or not
Using(getClass.getResourceAsStream("/HandRanks.dat")) { inputStream =>
def readChunk(): Option[Array[Byte]] = {
// can be done better, but that's not the point here
val buffer = new Array[Byte](inputStream.available)
val bytesRead = inputStream.read(buffer)
if (bytesRead >= 0) Some(buffer.take(bytesRead))
else None
}
@tailrec def process(): Unit = {
readChunk() match {
case Some(chunk) =>
// do something
process()
case None =>
// nothing to do - EOF reached
}
}
process()
}