Scala正则匹配AVRO文件首行失败,求技术指导
解决AVRO文件开头匹配问题
问题根源
你用#010616的写法不符合正则表达式中表示ASCII控制字符的规则,同时unanchored模式会忽略^锚定符,导致无法精准匹配文件开头。另外AVRO是二进制文件,直接按文本行读取可能出现字符解析错误。
解决方案
方案1:使用正则表达式匹配(注意字符编码)
Scala中,正则用\xHH(两位十六进制数)表示ASCII控制字符,同时要注意字符串中反斜杠需要转义为\\。如果要精准匹配文件开头,不要用unanchored模式:
// 正确的正则表达式,匹配AVRO开头的二进制转文本后的序列 val avroStartPattern = "^Obj\\x01\\x06\\x16avro.schema".r // 注意:读取二进制文件时需用ISO-8859-1编码,避免控制字符被转义 val fileContent = scala.io.Source.fromFile("your-file.avro", "ISO-8859-1").mkString avroStartPattern.findFirstIn(fileContent) match { case Some(_) => println("匹配到AVRO文件开头") case None => println("未匹配到") }
方案2:直接对比字节数组(更可靠)
AVRO是二进制格式,直接读取文件开头的字节序列进行对比是最准确的方式,避免正则和编码问题:
import java.io.FileInputStream // 定义AVRO开头的字节序列 val avroHeader = Array[Byte]( 'O', 'b', 'j', 0x01, 0x06, 0x16, // 对应ctl-a、ctl-f、ctl-v 'a', 'v', 'r', 'o', '.', 's', 'c', 'h', 'e', 'm', 'a' ) val fis = new FileInputStream("your-file.avro") val buffer = new Array[Byte](avroHeader.length) val readLength = fis.read(buffer) fis.close() // 对比读取的字节和目标字节序列 val isAvroFile = readLength == avroHeader.length && buffer.sameElements(avroHeader) println(if (isAvroFile) "是AVRO文件" else "不是AVRO文件")
关键注意点
unanchored模式会让正则忽略^和$锚定符,如果你要匹配文件开头,务必去掉这个模式。- 二进制文件不要用默认的UTF-8编码读取,
ISO-8859-1编码能准确映射每个字节到对应字符。 - 直接对比字节数组是处理二进制文件标识最可靠的方式,避免正则表达式带来的编码转义问题。
内容的提问来源于stack exchange,提问作者Mark Rostron
相关产品推荐
相关产品推荐

