从文件SCALA中读取第一个元素和下一个元素

时间:2017-08-02 15:53:44

标签: scala

我正在阅读一个包含277272行的文件,其中包含Int三元组(s,p,o),如:

10,44,22
10,47,12
15,38,3
15,41,30
16,38,5
16,44,15
16,47,18
22,38,21
22,41,42
34,44,40
34,47,36
40,38,39
40,41,42
45,38,27
45,41,30
46,44,45
46,47,48

从这个文件中我创建了一个随机访问文件对象,以便通过这个文件进行导航。但是我想提取第一列中的一些特定值,一个例子可以是我想在第一列中提取包含16的行的值,然后我选择一半的指针,类似于:

var lengthfile = (file.length().asInstanceOf[Int])
var initpointer = lengthfile/2

然后我判断第一个值是16,如果不是,我做了一个程序将指针移动到下一行,或者在后面的行中。一旦我检测到第一个值是16,我需要知道它是在第一行,第二行还是最后一行。我在这里介绍的函数是获取指针所在行的第一个值,并知道下一行的第一个值。

def firstvalue(pf: Int, file:RandomAccessFile): List[Int] ={
    //val file = new RandomAccessFile(filename, "r")
    var pointer = pf
    var flag = true
    var fline = Option("a")
    if (pointer <= file.length()-1){
      file.seek(pointer)
      fline = Option(file.readLine)
    }
    else {
      pointer = file.length().toInt-12
      file.seek(pointer)
      fline = Option(file.readLine)
    }
    while (flag)
    {
      if (fline.get != "")
      {
        if (pointer == 0)
        {
          file.seek(pointer)
          fline = Option(file.readLine)
          pointer -= 1
          flag = false
        }
        else{
          pointer -= 1
          file.seek(pointer)
          fline = Option(file.readLine)
        }
      }
      else if (fline.get == ""){
        flag = false
      }
    }
    pointer += 1
    file.seek(pointer)
    val line = Option(file.readLine)
    val spl = line.get.split(',')
    val p = spl.apply(0).toInt
    //file.close()
    val l = pointer :: p :: Nil
    l
  }
  //def nextvalue(pf: Int, filename:String): List[Int] = {
    //val file = new RandomAccessFile(filename, "r")
  def nextvalue(pf: Int, file:RandomAccessFile): List[Int] = {
    //val file = new RandomAccessFile(filename, "r")
    var pointer = pf
    var p = 0
    var flag = true
    var lastline = false
    var fline = Option ("a")
    if (pointer <= file.length()-1){
      file.seek(pointer)
      fline = Option(file.readLine)
    }

    //fline = Option(file.readLine)
    while (flag){
      if (fline.get != "")
      {
        if (fline == None)
        {
          flag = false
          lastline = true
        }
        else{
          pointer = file.getFilePointer.toInt
          fline = Option(file.readLine)
          flag = false

        }
      }
      else if (fline.get == ""){
        fline = Option(file.readLine)
        flag = false
      }
    }
    if (lastline == false)
    {

      //file.close()
      if (fline != None){
        val spl = fline.get.split(',')
        p = spl.apply(0).toInt
      }


    }
    val l = pointer :: p :: Nil
    l
  } 

但是我有一个性能问题,因为我正逐字逐句阅读,我想在很多天里解决这个问题,而且我没有解决方案。我不知道如果文件对象可能有回读行的功能,或者允许我改进此代码的东西?如何改进此代码?

1 个答案:

答案 0 :(得分:0)

  Source
   .fromFile(file)
   .getLines
   .zipWithIndex
   .filter(_._1.startsWith("16,"))

将为您提供以&#34; 16&#34;开头的所有行,以及文件中的索引。那应该更快,然后来回寻找......