首页 > 其他分享 >Scala——文件和正则表达式

Scala——文件和正则表达式

时间:2023-08-04 17:37:01浏览次数:30  
标签:文件 读取 val Scala 正则表达式 Source 使用 new


读取文件



import scala . io . Source
val source = Source . fromFile ( fileName , "UTF-8" )
// 第一个参数可以是文件名或java.io.File
// 如果没有第二个参数将会使用当前平台缺省的字符编码
 
val lineIterator = source . getLines    // 结果是一个迭代器
// 迭代器可以转换成Array等
 
val contents = source . mkString    // 整个文件读取成一个字符串
使用完Source后,记得需要close。


读取字符

要读取单个字符,可以直接从Source对象中进行迭代。Source类扩展自Iterator[Char]。



for ( c < - source )

如果想要查看接下来的字符,但是不对其进行处理(也就是说迭代器不移动位置),可以调用Source的buffered方法,返回一个collection.BufferedIterator[Char],然后使用这个对象的head方法查看下一个字符。


val source = Source . fromFile ( "myfile.txt" , "UTF-8" )
val iter = source . buffered
 
while ( iter . hasNext ) {
   if ( iter . head == someChar )
     deal with iter . next
   else
     . . .
}
 
source . close ( )

读取词法单元和数字


// 一个快而脏的方式
val tokens = source . mkString . sqlit ( "\\s+" )    // 根据正则读取词法单元
 
// 转换成数字
val numbers = for ( w < - tokens ) yield w . toDouble
val numbers = tokens . map ( _ . toDouble )

还可以使用java.util.Scanner类来读取文件中的文本和数字。


从非文件源读取


// 从URL读取,需要注意字符编码
val source1 = Source . fromURL ( "http://horstmann.com" , "UTF-8" )
val source2 = Source . fromString ( "Hello, world!" )    // 从指定的字符串读取,调试时很有用
val source3 = Source . stdin    // 从标准输入读取

读取二进制文件

Scala没有提供读取二进制文件的方法,需要使用Java类库。


val file = new File ( filename )
val in = new FileInputStream ( file )
val bytes = new Array [ Byte ] ( file . length . toInt )
in . read ( bytes )
in . close ( )


写入文本文件

Scala也没有对写入文件的内建支持,依旧可以使用Java类库来实现。如:



val out = new PrintWriter ( "numbers.txt" )
for ( i < - 1 to 100 ) out . println ( i )
out . close ( )

但是在使用这里printf方法时,传递AnyVal(比如各种数字)类型给方法时,编译器会要求将其转换成AnyRef:


out . printf ( "%6d %10.2f" , quantity . asInstanceOf [ AnyRef ] ,
   price . asInstanceOf [ AnyRef ] )
 
// 为了避免这个麻烦,可以使用String类的format方法
out . printf ( "%6d %10.2f" . format ( quantity , price ) )


访问目录

目前没有“正式的”用来访问目录中所有文件,或递归遍历所有目录的类。(本章各种没有内建没有正式是闹哪样啊!也无所谓了,用Java类库就是了。)下面探讨一下替代方案。


遍历某目录下所有子目录的函数:


import java . io . File
def subdirs ( dir : File ) : Iterator [ File ] = {
   val children = dir . listFiles . filter ( _ . isDirectory )
   children . toIterator ++ children . toIterator . flatMap ( subdirs _ )
}

不是很好懂,可能需要查阅API文档来帮忙。


如果使用了Java 7,可以使用java.nio.file.Files类的walkFileTree方法。该类用到了FileVisitor接口。


这里提到了Java的nio包,让我记起来的确需要去学一学了,io包大概已经真满足不了现在的需求了。


在Scala中通常更偏好用函数对象来指定工作内容,而不是接口(但在本例中接口可以有更细粒度的控制)。


以下隐式转换让函数可以与接口相匹配:


import java . nio . file . _
implicit def makeFileVisitor ( f : ( Paht ) = > Unit ) = new SimpleFileVisitor [ Path ] {
   override def visitFile ( p : Path , attrs : attribute . BasicFileAttributes ) = {
     f ( p )
     FileVisitResult . CONTINUE
   }
}
 
// 调用打印出所有的子目录
Files . walkFileTree ( dir . toPaht , ( f : Path ) = > println ( f ) )

这个真心有点超出太多了,放着先吧,等学了相关的知识再回来看。


序列化

使用序列化来将对象传输,或者是临时存储,序列化并不适合长期存储,会因为类的更新而出现问题。


在Scala中的序列化类:



@SerialVersionUID ( 42L ) class Person extends Serializable

如果可以接受缺省的UID,可以不要@SerialVersionUID注解。


序列化和反序列化:



val fred = new Person ( . . . )
import java . io . _
val out = new ObjectOutputStream ( new FileOutputStream ( "/tmp/test.obj" ) )
out . writeObject ( fred )
out . close ( )
 
val in = new ObjectInputStream ( new FileInputStream ( "/tmp/test.obj" ) )
val savedFred = in . readObject ( ) . asInstanceOf [ Person ]
in . close ( )


进程控制(A2)

Scala设计目标之一是能在简单的脚本话任务和大型程序之间保持良好的伸缩性。


scala.sys.process包提供了用于与shell程序交互的工具。这样一来,就可以使用Scala编写shell脚本。(虽然我用了Linux不少时间了,但我还是不会bash编程啊!怎么会有这么多东西需要学啊!~来不及的感觉…)


简单例子:



import sys . process . _
"ls -al .."!

ls -al ..命令将会被执行,然后将结果在标准输出中显示。


sys.process包内有从字符串到ProcessBuilder对象的隐式转换。!操作符执行的就是这个ProcessBuilder对象。返回的结果是被执行程序的返回值:成功执行是0;否则是显示错误的非0值。


如果使用!!操作符,输出会以字符串的形式返回:



val result = "ls -al .." ! !

还可以使用管道(不了解什么是管道的,请先学习一下Linux基础),使用#!操作符。



// 管道,使用#|
"ls -al .." # | "grep sec" !
// 重定向到文件,使用#>
"ls -al .." # > new File ( "output.txt" ) !
// 追加到文件,使用#>>
"ls -sl .." # >> new File ( "output.txt" ) !
// 将文件内容作为输入,使用#<
"grep sec" # < new File ( "output.txt" ) !    // 也可以使用URL

另外还可以使用#||和#&&来控制进程。不过这种功能还是直接使用Scala来实现更好。


可以自己指定执行进程的目录和环境变量;设置环境变量用的是一系列的对偶。



val p = Process ( cmd , new File ( dirName ) , ( "LANG" , "en_US" ) )
"echo 42" # | p !    // 执行

个人认为这个功能还是很强大的,可以使用现有的命令来做到大量的事情。不过是否会带来安全上的影响,以及可能会使程序变得与平台有关,还是要慎重使用。


正则表达式

与正则表达式相关的类是scala.util.matching.Regex类。要构造一个Regex对象,使用String类的r方法即可。如果正则表达式中包含反斜杠或引号之类的需要转义的字符,那么最好是使用原始(raw)字符串,以三个”号包围。



val numPattern = "[0-9]+" . r
val wsnumwsPattern = "" "\s+[0-9]+\s+" "" . r


// findAllIn方法返回遍历所有匹配项的迭代器
for ( matchString < - numPattern . findAllIn ( "99 bottles, 98 bottles" ) )
 
// 找到首个匹配项
val m1 = wsnumwsPattern . findFirstIn ( "99 bottles, 98 bottles" )
// 返回Some(" 98 ")
// findFirstIn方法返回Option[String]

用findPrefixOf方法检查某个字符串的开始部分是否能够匹配。


可以用相应的replace方法来替换掉匹配的部分。


正则表达式组

分组使得获取正则表达式的子表达式更加方便。在想要提取的子表达式两侧加上圆括号:



val numitemPattern = "([0-9]+) ([a-z]+" . r

匹配组将正则表达式对象当做“提取器”来使用:




val numitemPattern ( num , item ) = "99 bottles"
// num被赋值为"99",item被赋值为"bottles"

相关资源:Scala中正则表达式以及与模式匹配结合(多种方式)_scala正则表达式...


标签:文件,读取,val,Scala,正则表达式,Source,使用,new
From: https://blog.51cto.com/u_2650279/6964998

相关文章

  • 编制招标文件的“四步法”
    招标文件是合同缔约过程的要约邀请文件,是招标人按照招标投标法及其配套规范的规定,向投标人明确招标条件、提出响应要求并以此为依据对投标人的投标文件进行评审比较、择优选用的具有法律效力的文件。 招标文件的质量,直接决定了招标投标活动的质量;招标投标活动的质量,直接决定了......
  • web实现文件夹的上传和下载
    ​  上周遇到这样一个问题,客户上传高清视频(1G以上)的时候上传失败。一开始以为是session过期或者文件大小受系统限制,导致的错误。查看了系统的配置文件没有看到文件大小限制,web.xml中seesiontimeout是30,我把它改成了120。但还是不行,有时候10分钟就崩了。同事说,可能是客户这......
  • Linux文件与目录的三种时间状态(mtime,atime,ctime)区别
    最后一次修改文件或目录的时间最后一次改变文件或目录(改变的是原数据即:属性)的时间如:记录该文件的inode节点被修改的时间。touch命令除了-d和-t选项外都会改变该时间。而且chmod,chown等命令也能改变该值。最后一次访问文件或目录的时间对于文件:当修改mtime时,c......
  • Windows校验文件MD5和SHA值的方法
    1、需求背景下载或传输文件后,需要计算文件的MD5、SHA256等校验值,以确保下载或传输后的文件和源文件一致2、校验方法如上图所示,可以使用Windows自带的certutil命令来计算一个文件的校验值命令格式为:certutil-hashfile文件名校验值类型certutil命令支持的校验值类型......
  • Aapache Tomcat AJP 文件包含漏洞(CVE-2020-1938)
    AapacheTomcatAJP文件包含漏洞(CVE-2020-1938)【项目中遇到过】1.背景简述java是目前WEB开发中主流的编程语言,而Tomcat是当前流行的Java中间件服务器之一。Ghostcat(幽灵猫)是由长亭科技安全研究员发现的存在于Tomcat中的安全漏洞,由于TomcatAJP协议设计上存在缺陷,攻击者通......
  • 如何在python中执行另一个py文件
    使用命令:os.system(‘pythonfile_name.py’)解释:os.system是执行当前的系统命令1、拿windows系统举例:#由于ipconfig/all在windows中是查看ip地址#所以将此命令运行在os.system中,即可查看系统的ip地址等信息importosos.system('ipconfig/all')#因为pythonfile_name.p......
  • csharp实现文件夹的上传和下载
    ​ javaweb上传文件上传文件的jsp中的部分上传文件同样可以使用form表单向后端发请求,也可以使用ajax向后端发请求    1.通过form表单向后端发送请求         <formid="postForm"action="${pageContext.request.contextPath}/UploadServlet"method="post"e......
  • 接口测试之文件上传
    在日常工作中,经常有上传文件功能的测试场景,因此,本文介绍两种主流编写上传文件接口测试脚本的方法。首先,要知道文件上传的一般原理:客户端根据文件路径读取文件内容,将文件内容转换成二进制文件流的格式传输给服务端,而服务端接受客户端传过来的二进制文件流以及文件名称等信......
  • 配置文件定义值引用
    1.yml中写自己定义的一些固定值,定义为一个数组:system:default-role:-SUPER_ADMIN-DEVICE_WB_LEADER_ROLE-WEIXIU_ROLE-WX_TEAM_LEADER-FAULT_AUDIT_ROLE-FAULT_PINDOWN_ROLE-XY_VERIFICATION_ROLE-DEVICE_WBGCS_ROLE2.定义到一个实......
  • ActiveMQ任意文件写入漏洞(CVE-2016-3088)
    ActiveMQ任意文件写入漏洞(CVE-2016-3088)【现实项目遇到过】1.环境搭建cdvulhub-master/activemq/CVE-2016-3088docker-composeup-ddocker-composeconfig#查看靶场环境相关的配置信息docker-composedown#关闭靶场环境环境监听61616端口和8161端口,其中8......