热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Scala(12)scala读写数据

1.读取数据在Scala语言的Source单例对象中中,提供了一些非常便捷的方法,从而使开发者可以快速的从指定数据源(文本文件,URL地址等)中获取数据,在使用Source单例对

1. 读取数据

在Scala语言的 Source 单例对象中 中, 提供了一些非常便捷的方法, 从而使开发者可以快速的从指定数据源(文本文件, URL地址等)中获取数据, 在使用 Source 单例对象 之前, 需要先导包, 即 import scala.io.Source .


1.1 按行读取

我们可以以 行 为单位, 来读取数据源中的数据, 返回值是一个 迭代器类型的对象 . 然后通过 toArray, toList 方法, 将这些数据放到数组或者列表中即可.
注意: Source类扩展自Iterator[Char]

格式

//1. 获取数据源文件对象.
val source:BufferedSource = Source.fromFile("数据源文件的路径","编码表")
//2. 以行为单位读取数据.
val lines:Iterator[String] = source.getLines()
//3. 将读取到的数据封装到列表中.
val list1:List[String] = lines.toList
//4. 千万别忘记关闭Source对象.
source.close()

需求


  1. 在当前项目下创建data文件夹, 并在其中创建1.txt文本文件, 文件内容如下:

好好学习 , 天天向上!
Hadoop, Zookeeper, Flume, Spark
Flink, Sqoop, HBase

  1. 以行为单位读取该文本文件中的数据, 并打印结果.

参考代码

import scala.io.Source
//案例: 演示读取行.
object ClassDemo01 {def main(args: Array[String]): Unit &#61; {//1. 获取数据源对象.val source &#61; Source.fromFile("./data/1.txt")//2.通过getLines()方法, 逐行获取文件中的数据.var lines: Iterator[String] &#61; source.getLines()//3. 将获取到的每一条数据都封装到列表中.val list1 &#61; lines.toList//4. 打印结果for(s <- list1) println(s)//5. 记得关闭source对象.source.close()}
}

1.2 按字符读取

Scala还提供了 以字符为单位读取数据 这种方式, 这种用法类似于迭代器, 读取数据之后, 我们可以通过 hasNext(),next()方法 , 灵活的获取数据.

格式

//1. 获取数据源文件对象.
val source:BufferedSource &#61; Source.fromFile("数据源文件的路径","编码表")
//2. 以字符为单位读取数据.
val iter:BufferedIterator[Char] &#61; source.buffered
//3. 将读取到的数据封装到列表中.
while(iter.hasNext) {print(iter.next())
}
//4. 千万别忘记关闭Source对象.
source.close()

注意:
如果文件不是很大, 我们可以直接把它读取到一个字符串中.


val str:String &#61; source.mkString

需求


  1. 在当前项目下创建data文件夹, 并在其中创建1.txt文本文件, 文件内容如下:

好好学习 , 天天向上!
Hadoop, Zookeeper, Flume, Spark
Flink, Sqoop, HBase

  1. 以行为单位读取该文本文件中的数据, 并打印结果.

参考代码

import scala.io.Source
//案例: 演示读取单个字符.
object ClassDemo02 {def main(args: Array[String]): Unit &#61; {//1. 获取数据源对象.val source &#61; Source.fromFile("./data/1.txt")//2. 获取数据源文件中的每一个字符.val iter &#61; source.buffered //这里, source对象的用法相当于迭代器.//3. 通过hasNext(), next()方法获取数据.while(iter.hasNext) {print(iter.next()) //细节, 这里不要用println(), 否则输出结果可能不是你想要的.}//4. 通过mkString方法, 直接把文件中的所有数据封装到一个字符串中.val str &#61; source.mkString//5. 打印结果.println(str)//6. 关闭source对象, 节约资源, 提高效率.source.close()}
}

1.3 读取词法单元和数字

所谓的词法单元指的是 以特定符号间隔开的字符串 , 如果数据源文件中的数据都是 数字形式的字符串 , 我们可以很方便的从文件中直接获取这些数据, 例如:

10 2 5
11 2
5 1 3 2

格式

//1. 获取数据源文件对象.
val source:BufferedSource &#61; Source.fromFile("数据源文件的路径","编码表")
//2. 读取词法单元.
// \s表示空白字符(空格, \t, \r, \n等)
val arr:Array[String] &#61; source.mkString.split("\\s&#43;")
//3. 将字符串转成对应的整数
val num &#61; strNumber.map(_.toInt)
//4. 千万别忘记关闭Source对象.
source.close()

需求


  1. 在当前项目下创建data文件夹, 并在其中创建2.txt文本文件, 文件内容如下:

10 2 5
11 2
5 1 3 2

  1. 读取文件中的所有整数, 将其加1后, 把结果打印到控制台.

参考代码

import scala.io.Source
//案例: 读取词法单元和数字.
object ClassDemo03 {def main(args: Array[String]): Unit &#61; {val source &#61; Source.fromFile("./data/2.txt")// \s表示空白字符(空格, \t, \r, \n等)val strNumber &#61; source.mkString.split("\\s&#43;") //将字符串转成对应的整数val num &#61; strNumber.map(_.toInt)for(a <- num) println(a &#43; 1)}
}

1.4 从URL或者其他源读取数据

Scala中提供了一种方式, 可以让我们直接从指定的URL路径, 或者其他源(例如: 特定的字符串)中直接读取数据。

格式


  • 从 URL地址中读取数据

//1. 获取数据源文件对象.
val source &#61; Source.fromURL("http://www.erainm.com")
//2. 将数据封装到字符串中并打印.
println(source.mkString)

  • 从其他源读取数据

//1. 获取数据源文件对象.
val str &#61; Source.fromString("好好学习")
println(str.getLines())

需求


  1. 读取 网址 (http://www.erainm.com) 页面的数据, 并打印结果.
  2. 直接读取字符串 好好学习 , 并打印结果.

参考代码

import scala.io.Source
//案例: 从URL或者其他源读取数据
object ClassDemo04 {def main(args: Array[String]): Unit &#61; {val source &#61; Source.fromURL("http://www.erainm.com")println(source.mkString)val str &#61; Source.fromString("好好学习")println(str.getLines())}
}

1.5 读取二进制文件

Scala没有提供读取二进制文件的方法, 我们需要通过Java类库来实现.

需求
已知项目的data文件夹下有 01.png 这张图片, 请读取该图片数据, 并将读取到的字节数打印到控制台上.

参考代码

// 案例: 读取二进制文件数据.
object ClassDemo05 {def main(args: Array[String]): Unit &#61; {val file &#61; new File("./data/01.png")val fis &#61; new FileInputStream(file)val bys &#61; new Array[Byte](file.length().toInt)fis.read(bys)fis.close()println(bys.length)}
}

2. 写入数据

Scala并没有内建的对写入文件的支持, 要写入数据到文件, 还是需要使用Java的类库.


2.1 往文件中写入指定数据

需求
往项目下的data文件夹的3.txt文本文件中, 编写一句话, 内容如下:

好好学习 ,
天天向上!

参考代码

// 案例: 写入数据到文本文件.
object ClassDemo06 {def main(args: Array[String]): Unit &#61; {val pw &#61; new FileOutputStream("./data/3.txt")pw.write("好好学习,\r\n".getBytes())pw.write("天天向上!".getBytes())pw.close()}
}

2.2 序列化和反序列化

在Scala中, 如果想将对象传输到其他虚拟机, 或者临时存储, 就可以通过 序列化和反序列化 来实现了.


  • 序列化 : 把对象写到文件中的过程.
  • 反序列化 : 从文件中加载对象的过程.
    注意: 一个类的对象要想实现序列化和反序列化操作, 则该类必须继承 Serializable 特质 .

需求:


  1. 定义样例类Person, 属性为姓名和年龄.
  2. 创建Person样例类的对象p.
  3. 通过序列化操作将对象p写入到项目下的data文件夹下的4.txt文本文件中.
  4. 通过反序列化操作从项目下的data文件夹下的4.txt文件中, 读取对象p.

参考代码

// 案例: 演示序列化和反序列化操作.
object ClassDemo07 {case class Person(var name:String, var age:Int)def main(args: Array[String]): Unit &#61; {//序列化操作./*val p &#61; new Person("张三", 23)val oos &#61; new ObjectOutputStream(new FileOutputStream("./data/4.txt"))oos.writeObject(p)oos.close()*///反序列化操作.val ois &#61; new ObjectInputStream(new FileInputStream("./data/4.txt"))var p: Person &#61; ois.readObject().asInstanceOf[Person]println(p)}
}

3. 案例: 学员成绩表


3.1 概述


  1. 已知项目下的data文件夹的student.txt文本文件中, 记录了一些学员的成绩, 如下:

格式为: 姓名 语文成绩 数学成绩 英语成绩


张三 37 90 100
李四 90 73 81
王五 60 90 76
赵六 89 21 72
田七 100 100 100

  1. 按照学员的总成绩降序排列后, 按照 姓名 语文成绩 数学成绩 英语成绩 总成绩 的格式, 将数据写到项目下的data文件夹的stu.txt文件中.

3.2 目的

考察 流 , 样例类, 以及函数式编程 相关内容.


3.3 步骤


  1. 定义样例类Person, 属性为: 姓名, 语文成绩, 数学成绩, 英语成绩, 且该类中有一个获取总成绩的方法.
  2. 读取指定文件(./data/student.txt)中所有的数据, 并将其封装到List列表中.
  3. 定义可变的列表ListBuffer[Student], 用来记录所有学生的信息.
  4. 遍历第二步获取到的数据, 将其封装成Person类的对象后, 并添加到ListBuffer中.
  5. 对第4步获取到的数据进行排序操作, 并将其转换成List列表.
  6. 按照指定格式, 通过BufferWriter将排序后的数据写入到目的地文件中(./data/stu.txt)
  7. 关闭流对象.

3.4 参考代码

// 案例: 按照学员的总分降序排列.
object ClassDemo08 {//1. 定义样例类Person, 属性: 姓名, 语文成绩, 数学成绩, 英语成绩, 且该类中有一个获取总成绩的方法.case class Student(name:String, chinese:Int, math:Int, english:Int) {def getSum() &#61; chinese &#43; math &#43; english
}def main(args: Array[String]): Unit &#61; {//2. 获取数据源文件对象.val source &#61; Source.fromFile("./data/student.txt")//3. 读取指定文件(./data/student.txt)中所有的数据, 并将其封装到List列表中.var studentList: Iterator[List[String]] &#61; source.getLines().map(_.split("")).map(_.toList)//4. 定义可变的列表ListBuffer[Student], 用来记录所有学生的信息.val list &#61; new ListBuffer[Student]()//5. 遍历第二步获取到的数据, 将其封装成Person类的对象后, 并添加到ListBuffer中.for(s <- studentList) {list &#43;&#61; Student(s(0), s(1).toInt, s(2).toInt, s(3).toInt)}//6. 对第5步获取到的数据进行排序操作, 并将其转换成List列表.val sortList &#61; list.sortBy(_.getSum()).reverse.toList//7. 按照指定格式, 通过BufferWriter将排序后的数据写入到目的地文件中(./data/stu.txt)val bw &#61; new BufferedWriter(new FileWriter("./data/stu.txt"))for(s <- sortList) bw.write(s"${s.name} ${s.chinese} ${s.math} ${s.english} ${s.getSum()}\r\n")//8. 关闭流对象bw.close()}
}

推荐阅读
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文介绍了pack布局管理器在Perl/Tk中的使用方法及注意事项。通过调用pack()方法,可以控制部件在显示窗口中的位置和大小。同时,本文还提到了在使用pack布局管理器时,应注意将部件分组以便在水平和垂直方向上进行堆放。此外,还介绍了使用Frame部件或Toplevel部件来组织部件在窗口内的方法。最后,本文强调了在使用pack布局管理器时,应避免在中间切换到grid布局管理器,以免造成混乱。 ... [详细]
  • OpenMap教程4 – 图层概述
    本文介绍了OpenMap教程4中关于地图图层的内容,包括将ShapeLayer添加到MapBean中的方法,OpenMap支持的图层类型以及使用BufferedLayer创建图像的MapBean。此外,还介绍了Layer背景标志的作用和OMGraphicHandlerLayer的基础层类。 ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 使用Ubuntu中的Python获取浏览器历史记录原文: ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 本文介绍了Perl的测试框架Test::Base,它是一个数据驱动的测试框架,可以自动进行单元测试,省去手工编写测试程序的麻烦。与Test::More完全兼容,使用方法简单。以plural函数为例,展示了Test::Base的使用方法。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • importjava.util.ArrayList;publicclassPageIndex{privateintpageSize;每页要显示的行privateintpageNum ... [详细]
  • 关键词:Golang, Cookie, 跟踪位置, net/http/cookiejar, package main, golang.org/x/net/publicsuffix, io/ioutil, log, net/http, net/http/cookiejar ... [详细]
  • Android JSON基础,音视频开发进阶指南目录
    Array里面的对象数据是有序的,json字符串最外层是方括号的,方括号:[]解析jsonArray代码try{json字符串最外层是 ... [详细]
  • 本文介绍了Swing组件的用法,重点讲解了图标接口的定义和创建方法。图标接口用来将图标与各种组件相关联,可以是简单的绘画或使用磁盘上的GIF格式图像。文章详细介绍了图标接口的属性和绘制方法,并给出了一个菱形图标的实现示例。该示例可以配置图标的尺寸、颜色和填充状态。 ... [详细]
  • 大数据Hadoop生态(20)MapReduce框架原理OutputFormat的开发笔记
    本文介绍了大数据Hadoop生态(20)MapReduce框架原理OutputFormat的开发笔记,包括outputFormat接口实现类、自定义outputFormat步骤和案例。案例中将包含nty的日志输出到nty.log文件,其他日志输出到other.log文件。同时提供了一些相关网址供参考。 ... [详细]
  • 本文介绍了在sqoop1.4.*版本中,如何实现自定义分隔符的方法及步骤。通过修改sqoop生成的java文件,并重新编译,可以满足实际开发中对分隔符的需求。具体步骤包括修改java文件中的一行代码,重新编译所需的hadoop包等。详细步骤和编译方法在本文中都有详细说明。 ... [详细]
author-avatar
手机用户2602920905
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有