在 Scala 中,如何从由字符分隔的二进制文件中读取字节?
In Scala, how to read bytes from binary file delimited by characters?
在 Scala 中,给定一个二进制文件,我有兴趣检索 Array[Byte] 项的 list。
例如,二进制文件包含由 characters/bytes 'my-delimiter' 分隔的项目。
如何获取每个项目的 Array[Byte] 列表?
功能解决方案,在java.nio
的帮助下:
import java.nio.file.{Files, Paths}
object Main {
private val delimiter = '\n'.toByte
def main(args: Array[String]): Unit = {
val byteArray = Files.readAllBytes(Paths.get(args(0)))
case class Accumulator(result: List[List[Byte]], current: List[Byte])
val items: List[Array[Byte]] = byteArray.foldLeft(Accumulator(Nil, Nil)) {
case (Accumulator(result, current), nextByte) =>
if (nextByte == delimiter)
Accumulator(current :: result, Nil)
else
Accumulator(result, nextByte :: current)
} match {
case Accumulator(result, current) => (current :: result).reverse.map(_.reverse.toArray)
}
items.foreach(item => println(new String(item)))
}
}
虽然预计此解决方案的性能不佳。这对你有多重要?您将阅读多少文件、大小以及多久阅读一次?如果性能很重要,那么您应该使用输入流和可变集合:
import java.io.{BufferedInputStream, FileInputStream}
import scala.collection.mutable.ArrayBuffer
object Main {
private val delimiter = '\n'.toByte
def main(args: Array[String]): Unit = {
val items = ArrayBuffer.empty[Array[Byte]]
val item = ArrayBuffer.empty[Byte]
val bis = new BufferedInputStream(new FileInputStream(args(0)))
var nextByte: Int = -1
while ( { nextByte = bis.read(); nextByte } != -1) {
if (nextByte == delimiter) {
items.append(item.toArray)
item.clear()
} else {
item.append(nextByte.toByte)
}
}
items.append(item.toArray)
items.foreach(item => println(new String(item)))
bis.close()
}
}
在 Scala 中,给定一个二进制文件,我有兴趣检索 Array[Byte] 项的 list。
例如,二进制文件包含由 characters/bytes 'my-delimiter' 分隔的项目。
如何获取每个项目的 Array[Byte] 列表?
功能解决方案,在java.nio
的帮助下:
import java.nio.file.{Files, Paths}
object Main {
private val delimiter = '\n'.toByte
def main(args: Array[String]): Unit = {
val byteArray = Files.readAllBytes(Paths.get(args(0)))
case class Accumulator(result: List[List[Byte]], current: List[Byte])
val items: List[Array[Byte]] = byteArray.foldLeft(Accumulator(Nil, Nil)) {
case (Accumulator(result, current), nextByte) =>
if (nextByte == delimiter)
Accumulator(current :: result, Nil)
else
Accumulator(result, nextByte :: current)
} match {
case Accumulator(result, current) => (current :: result).reverse.map(_.reverse.toArray)
}
items.foreach(item => println(new String(item)))
}
}
虽然预计此解决方案的性能不佳。这对你有多重要?您将阅读多少文件、大小以及多久阅读一次?如果性能很重要,那么您应该使用输入流和可变集合:
import java.io.{BufferedInputStream, FileInputStream}
import scala.collection.mutable.ArrayBuffer
object Main {
private val delimiter = '\n'.toByte
def main(args: Array[String]): Unit = {
val items = ArrayBuffer.empty[Array[Byte]]
val item = ArrayBuffer.empty[Byte]
val bis = new BufferedInputStream(new FileInputStream(args(0)))
var nextByte: Int = -1
while ( { nextByte = bis.read(); nextByte } != -1) {
if (nextByte == delimiter) {
items.append(item.toArray)
item.clear()
} else {
item.append(nextByte.toByte)
}
}
items.append(item.toArray)
items.foreach(item => println(new String(item)))
bis.close()
}
}