scala读取HDFS文件,每次读取一定的字节数

用scala读取一个只有字符的文件,该文件是已经清洗完的数据,有规律,一行是一条数据。
现在的需求是一次读取文件中的一部分,依次读取完。
 
如果有疑问,或者找出错误的解决方案,请和我联系。一起研究讨论
import java.io.IOException
import java.net.URI

import org.apache.hadoop.conf.Configuration
import org.apache.hadoop.fs.{FSDataInputStream, FileSystem, Path}

/**
  * Created by wx on 2017/7/20.
  */
object HDFSUtil {
  val conf: Configuration = new Configuration
  var fs: FileSystem = null
  var hdfsInStream: FSDataInputStream = null

  def getFSDataInputStream(path: String): FSDataInputStream = {
    try {
      fs = FileSystem.get(URI.create(path), conf)
      hdfsInStream = fs.open(new Path(path))
    } catch {
      case e: IOException => {
        e.printStackTrace
      }
    }
    return hdfsInStream
  }

  def close {
    try {
      if (hdfsInStream != null) {
        hdfsInStream.close
      }
      if (fs != null) {
        fs.close
      }
    }
    catch {
      case e: IOException => {
        e.printStackTrace
      }
    }
  }
}

import java.util
import org.apache.hadoop.fs.FSDataInputStream

/**
  * 用scala读取一个只有字符的文件,该文件是已经清洗完的数据,有规律,一行是一条数据。
  * 现在的需求是一次读取文件中的一部分,依次读取完。
  * Created by wx on 2017/7/21.
  */
object ReadHDFSFile {
  def main(args: Array[String]) {
    var inputStream: FSDataInputStream = null

    try {
      inputStream = HDFSUtil.getFSDataInputStream("hdfs://master:9000/csw/TestData/aviation9/part-00000")
      //每次读取的字节长度
      val readLength = 1024
      //创建一个字节数组
      var ioBuffer: Array[Byte] = new Array[Byte](readLength)
      //先读取一个1024字节的数据
      var readLen = inputStream.read(ioBuffer)
      //因为每次读取1024个字节,会遇到一行读取一半,剩下的一半下一次读取。
      //在这设置个临时变量来存放前面读取的一半,然后和后面读取到的拼接起来
      var tmp = ""
      //只做一个计数
      var count = 1
      while (readLen != -1) {
        //将读取到字节转成字符串
        var str = new String(ioBuffer, 0, readLen)
        /*这里是处理,当读取中文时,因为中文是两个字节,回读取一半,
        这样在转码的时候就会报错,当遇到这样的情况,需要再往后读取一个字节,然后和之前的组成新的字节数组
        这样可以避免出现读取一半的情况,但是我的数据量很多,即使这样处理,还是会偶尔遇到乱码,
        最后我又改进了,一次读取一行。*/
        val b2: Array[Byte] = str.getBytes("utf8")
        if (b2(b2.length - 1) == -67) {
          var b3: Array[Byte] = new Array[Byte](1)
          inputStream.read(b3);
          val temp: Byte = b3(0)
          b3 = util.Arrays.copyOf(ioBuffer, b3.length + ioBuffer.length)
          b3(b3.length - 1) = temp;
          str = new String(b3)
        }
        //按换行符切割
        val arr = str.split("\n")
        val arrLength = arr.length
        //获取数据还剩多少字节可读
        var available = inputStream.available()
        println(available + "剩余可读字节数")
        //在这个里进行数据的判断,将一整行数据输出,将不完整的数据进行存放和拼接
        for (i <- 0 until arrLength) {
          if (i == 0) {
            println(count + "\t" + tmp + arr(i) + "\t我再这")
            count += 1
          } else if (i == arrLength - 1 && available != 0) {
            tmp = arr(arrLength - 1)
          } else {
            println(count + "\t" + arr(i) + "\t我再这")
            count += 1
          }
        }
        //判断当可读字节小于一开始设定的字节
        if (available < readLength) {
          //最后一次读取,按照未读的字节的长度新建一个byte数组,这样可以避免最后会重复读取数据。
          ioBuffer = new Array[Byte](available)
          readLen = inputStream.read(ioBuffer)
        } else {
          readLen = inputStream.read(ioBuffer)
        }
        //让程序暂停睡眠一下
        Thread.sleep(500)
      }
    } catch {
      case e: Exception => {
        e.printStackTrace()
      }
    } finally {
      if (inputStream != null) {
        HDFSUtil.close
      }
    }
  }
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值