談?wù)剆cala 的模式匹配

在 java 中我倒是較少使用 switch case 缭召,大部分都是if else 搞定
但是在 scala 中 模式匹配 可以說是登峰造極了,你可以用它完成之前很多繁瑣機(jī)械的問題蟋座,最主要是靈活多變,總有一款適合你
先講講最簡(jiǎn)單的
我這里有一個(gè)需求
把 hdfs 上的原始日志數(shù)據(jù)進(jìn)行壓縮假勿,其中壓縮方式 有 snappy gzip lzo defalte 大致四種这吻,原先我把每一種壓縮方式都寫了一個(gè)獨(dú)立的方法,驗(yàn)證都可以正常使用般堆,寫代碼要時(shí)刻有重構(gòu)的想法在孝,我一看大部分 流程都一致,可以把這些合四為一,把單獨(dú)不一致的內(nèi)容拿出來淮摔,做case 判斷識(shí)別
比如
單個(gè)的 snappy 壓縮

  /**
    * hdfs 文件  snappy 壓縮
    *
    * @param fs
    * @param conf
    * @param inpath
    * @param outPath
    */
  def hdfsFileCompressBySnappyCodec(fs: FileSystem, conf: Configuration, inpath: String, outPath: String): Unit = {
    //壓縮時(shí) 讀取fsdata流  寫入 compress流【fs-buff-compress]
    val inputPath: Path = new Path(inpath)
    val inFsData: FSDataInputStream = fs.open(inputPath)
    val snappyCC: SnappyCodec = new SnappyCodec()
    //val snappyComp:SnappyCompressor=new SnappyCompressor()
    snappyCC.setConf(conf)

    // val snappyFile :String= getFileOriginName(inpath) +snappyCC.getDefaultExtension
    val inSubPath: String = getOutFileSubPath(inpath)
    var nOutPath = ""
    if (outPath.endsWith("/")) {
      nOutPath = outPath.substring(0, outPath.length - 1)
    } else {
      nOutPath = outPath
    }
    val snappyFile: String = nOutPath + inSubPath + snappyCC.getDefaultExtension
    val outdir: Path = new Path(snappyFile)
    val fsDataOutStream: FSDataOutputStream = fs.create(outdir)
    val fsBufferOutStream: BufferedOutputStream = new BufferedOutputStream(fsDataOutStream)
    val compressOutStream: CompressionOutputStream = snappyCC.createOutputStream(fsBufferOutStream)
    val bufInpStream: BufferedInputStream = new BufferedInputStream(inFsData)
    val ioBuffer: Array[Byte] = new Array[Byte](64 * 1024)
    var readLen: Int = 0
    val start = System.currentTimeMillis()
    println("snappy codec begining  ||  " + snappyFile)
    try {
      while ( {
        readLen = bufInpStream.read(ioBuffer)
        readLen != -1
      }) {
        compressOutStream.write(ioBuffer, 0, readLen)
      }
    } catch {
      case e: Exception => e.printStackTrace()
    } finally {
      compressOutStream.flush()
      compressOutStream.finish()
      compressOutStream.close()
      IOUtils.closeStream(inFsData)
      IOUtils.closeStream(fsDataOutStream)
      //fs.close()
    }
    val end = System.currentTimeMillis()
    val timeCause = end - start
    println("snappy codec finish   ||  " + snappyFile + " || 時(shí)間消耗   " + timeCause + " ms")

  }


其實(shí)就是 不同壓縮格式 創(chuàng)建不同的 codec
所以我做了 case就是創(chuàng)建不同codec 私沮,通過 查詢 發(fā)現(xiàn) 這些 codec
都 是 CompressionCodec的子類,
所以就這樣辦了
方法增加一個(gè) 輸入的參數(shù) string codecMethod作為制定 壓縮格式

 val codec:CompressionCodec =codecMethod match {
      case "SNAPPY" => new SnappyCodec()
//     { codec.asInstanceOf[SnappyCodec].setConf(conf)
//      }
      case "GZIP" => new GzipCodec()
      case "LZO" => new Lz4Codec()
      case "DEFALTE" => new DefaultCodec()
      case _ => new DefaultCodec()
    }

這樣一來 剩下的流程都一致和橙,可以做一些 一致的處理
仔燕,
除了上邊的,其實(shí)我還有另一種case的使用 就是在一個(gè)方法中 通過
case 調(diào)用不同的方法魔招,
我前面講過 我在最開始前分別寫了 四個(gè)獨(dú)立的壓縮方法晰搀,這四個(gè)方法相當(dāng)于壓縮算子,只能對(duì)單獨(dú)文件進(jìn)行 壓縮办斑,可是我們 在hdfs上 往往都是 目錄嵌套好幾層外恕,直接從最外層 開始?jí)嚎s杆逗,一口氣可能就是成千上萬個(gè)文件了,所以我寫了一個(gè) 目錄壓縮方法鳞疲,來對(duì)目錄嵌套下的文件進(jìn)行壓縮罪郊,并且我在 目錄壓縮方法中使用了 遞歸,簡(jiǎn)直 不能再好了
尚洽,當(dāng)然在目錄壓縮方法中也是可以指定 壓縮格式的悔橄,我在這里 是通過調(diào)用獨(dú)立的壓縮算子方法實(shí)現(xiàn) 的


 codec match {
          case "SNAPPY" => hdfsFileCompressBySnappyCodec(fs, conf, inpath, outPath)
          case "GZIP" => hdfsFileCompressByGzipCodec(fs, conf, inpath, outPath)
          case "LZO" => LZOCodecHdfsFileCompressBy(fs, conf, inpath, outPath)
          case "DEFALTE" =>deflateCompressForHdfsFile(fs,conf,inpath,outPath)
          case _ => deflateCompressForHdfsFile(fs,conf,inpath,outPath)
        }

具體的目錄壓縮方法

/**
    * 按目錄對(duì)文件  進(jìn)行 snappy  gzip  lzo  壓縮
    * @param fs
    * @param conf
    * @param inpath 輸入目錄
    * @param outPath 輸出目錄
    * @param codec  壓縮格式 縮寫  SNAPPY  GZIP LZO  DEFALTE 默認(rèn)為defalte
    * @param propertiesPath  壓縮文件類型刷選 屬性文件路徑
    */
  def DirCompressBySnappyGzipLzoCodec(fs: FileSystem, conf: Configuration, inpath: String, outPath: String, codec: String="GZIP")(propertiesPath: String="/usr/local/info.properties"): Unit = {
    val inputPa: Path = new Path(inpath)
    val fsStatus: FileStatus = fs.getFileStatus(inputPa)
    var flag = false
    try{

    if (fsStatus.isFile) {
      flag = CompressUtils.boolFilePrefixContains(inpath, propertiesPath)
      if (flag) {
        codec match {
          case "SNAPPY" => hdfsFileCompressBySnappyCodec(fs, conf, inpath, outPath)
          case "GZIP" => hdfsFileCompressByGzipCodec(fs, conf, inpath, outPath)
          case "LZO" => LZOCodecHdfsFileCompressBy(fs, conf, inpath, outPath)
          case "DEFALTE" =>deflateCompressForHdfsFile(fs,conf,inpath,outPath)
          case _ => deflateCompressForHdfsFile(fs,conf,inpath,outPath)
        }
      }
    } else if (fsStatus.isDirectory) {
      val listFs: Array[FileStatus] = fs.listStatus(inputPa)
      listFs.foreach(fil => {
        val fsiN = fil.getPath.getName
        println("path dir name  " + fsiN)
        println("path parent  " + fil.getPath.getParent)
        val uriPath = fil.getPath.getParent.toString
        var newInp = ""
        if (uriPath.contains(":9000/")) {
          val uriIndex = uriPath.indexOf(":9000/")
          newInp = uriPath.substring(uriIndex + 5) + "/" + fsiN
        } else {
          newInp = uriPath + "/" + fsiN
        }
        if (fil.isFile) {
          flag = CompressUtils.boolFilePrefixContains(newInp, propertiesPath)
          if (flag) {
            codec match {
              case "SNAPPY" => hdfsFileCompressBySnappyCodec(fs, conf, newInp, outPath)
              case "GZIP" => hdfsFileCompressByGzipCodec(fs, conf, newInp, outPath)
              case "LZO" => LZOCodecHdfsFileCompressBy(fs, conf, newInp, outPath)
              case "DEFALTE" =>deflateCompressForHdfsFile(fs,conf,inpath,outPath)
              case _ => deflateCompressForHdfsFile(fs,conf,inpath,outPath)
            }
          }
        } else {
          DirCompressBySnappyGzipLzoCodec(fs, conf, newInp, outPath, codec)(propertiesPath)
        }
      })
    }

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市腺毫,隨后出現(xiàn)的幾起案子癣疟,更是在濱河造成了極大的恐慌,老刑警劉巖拴曲,帶你破解...
    沈念sama閱讀 219,270評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件争舞,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡澈灼,警方通過查閱死者的電腦和手機(jī)竞川,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來叁熔,“玉大人委乌,你說我怎么就攤上這事∪倩兀” “怎么了遭贸?”我有些...
    開封第一講書人閱讀 165,630評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)心软。 經(jīng)常有香客問我壕吹,道長(zhǎng),這世上最難降的妖魔是什么删铃? 我笑而不...
    開封第一講書人閱讀 58,906評(píng)論 1 295
  • 正文 為了忘掉前任耳贬,我火速辦了婚禮,結(jié)果婚禮上猎唁,老公的妹妹穿的比我還像新娘咒劲。我一直安慰自己,他們只是感情好诫隅,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,928評(píng)論 6 392
  • 文/花漫 我一把揭開白布腐魂。 她就那樣靜靜地躺著,像睡著了一般逐纬。 火紅的嫁衣襯著肌膚如雪蛔屹。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,718評(píng)論 1 305
  • 那天风题,我揣著相機(jī)與錄音判导,去河邊找鬼嫉父。 笑死,一個(gè)胖子當(dāng)著我的面吹牛眼刃,可吹牛的內(nèi)容都是我干的绕辖。 我是一名探鬼主播,決...
    沈念sama閱讀 40,442評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼擂红,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼仪际!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起昵骤,我...
    開封第一講書人閱讀 39,345評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤树碱,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后变秦,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體成榜,經(jīng)...
    沈念sama閱讀 45,802評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,984評(píng)論 3 337
  • 正文 我和宋清朗相戀三年蹦玫,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了赎婚。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,117評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡樱溉,死狀恐怖挣输,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情福贞,我是刑警寧澤撩嚼,帶...
    沈念sama閱讀 35,810評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站挖帘,受9級(jí)特大地震影響完丽,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜拇舀,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,462評(píng)論 3 331
  • 文/蒙蒙 一舰涌、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧你稚,春花似錦、人聲如沸朱躺。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽长搀。三九已至宇弛,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間源请,已是汗流浹背枪芒。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評(píng)論 1 272
  • 我被黑心中介騙來泰國打工彻况, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人舅踪。 一個(gè)月前我還...
    沈念sama閱讀 48,377評(píng)論 3 373
  • 正文 我出身青樓纽甘,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國和親抽碌。 傳聞我的和親對(duì)象是個(gè)殘疾皇子悍赢,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,060評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容