Scala文件操作示例代码讲解

目录
  • 1. 读取数据
    • 1.1 按行读取
    • 1.2 按字符读取
      • Scala使用source.buffered方法按字符读取文件
      • 一个示例
    • 1.3 读取词法单元和数字
    • 1.4 从URL或者其他源读取数据
    • 1.5 读取二进制文件
  • 2. 写入文件
    • 2.1 使用java.io.PrintWriter类
    • 2.2 使用java.io.FileWriter类
    • 2.3 使用java.io.FileOutputStream类
    • 2.4 几种写入的区别
    • 2.5 使用第三方库
  • 3. Scala序列化和反序列化
    • 3.1 什么是序列化和反序列化
    • 3.2 如何实现序列化和反序列化
    • 3.3 一个示例
    • 3.4 使用注解
  • 案例-学员成绩表

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()

需求

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

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

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

参考代码

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

1.2 按字符读取

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

Scala使用source.buffered方法按字符读取文件

什么是source.buffered方法

source.buffered方法是scala.io.Source类的一个成员方法,它可以将一个Source对象转换为一个BufferedSource对象。BufferedSource对象是一个实现了BufferedIterator特质的对象,它可以提供一个缓冲区,用来存储未被消费的元素。这样可以提高读取文件的效率,也可以方便地查看下一个元素而不消费它。

如何使用source.buffered方法

要使用source.buffered方法,首先需要导入scala.io.Source类,并创建一个Source对象,然后调用其buffered方法,得到一个BufferedSource对象。例如,以下代码创建了一个从文件中获取的Source对象,并转换为一个BufferedSource对象:

import scala.io.Source
// 创建一个从文件中获取的Source对象
val source = Source.fromFile("demo.txt")
// 调用buffered方法,得到一个BufferedSource对象
val buffered = source.buffered

然后,可以使用BufferedSource对象的各种方法来按字符读取文件。例如,以下代码使用head方法来查看下一个字符,使用next方法来消费下一个字符,并打印出来:

// 使用head方法查看下一个字符
println(buffered.head)
// 使用next方法消费下一个字符
println(buffered.next())
// 继续使用head方法查看下一个字符
println(buffered.head)
// 继续使用next方法消费下一个字符
println(buffered.next())

最后,需要关闭Source对象,释放资源:

// 关闭Source对象source.close()

一个示例

下面给出一个完整的示例,演示如何使用source.buffered方法来按字符读取文件,并打印出来。

首先,准备一个文本文件demo.txt,内容如下:

Hello, Scala!
你好,Scala!

然后,编写以下代码:

import scala.io.Source
// 创建一个从文件中获取的Source对象,并转换为一个BufferedSource对象
val buffered = Source.fromFile("demo.txt").buffered
// 循环判断是否有下一个元素
while (buffered.hasNext) {
  // 打印出当前元素,并消费掉
  print(buffered.next())
}
// 关闭Source对象
buffered.close()

最后,运行程序,可以看到输出结果如下:

Hello, Scala!
你好,Scala!

1.3 读取词法单元和数字

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

10 2 5

11 2

5 1 3 2

格式

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

参考代码

将上面的数字存入2.txt

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

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

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

格式 从URL地址中读取数据

//1. 获取数据源文件对象.
val source = Source.fromURL("https://www.csdn.net")
//2. 将数据封装到字符串中并打印.
println(source.mkString)

从其他源读取数据

//1. 获取数据源文件对象.
val str = Source.fromString("CSDN")
println(str.getLines())

需求

  • 读取https://www.csdn.net 页面的数据, 并打印结果.
  • 直接读取字符串 CSDN, 并打印结果.

参考代码

import scala.io.Source
object ClassDemo04 {
	def main(args: Array[String]): Unit = {
	val source = Source.fromURL("https://www.csdn.net")
	println(source.mkString)
	val str = Source.fromString("CSDN")
	println(str.getLines())
	}
}

1.5 读取二进制文件

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

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

object ClassDemo05 {
	def main(args: Array[String]): Unit = {
	val file = new File("./data/04.png")
	val fis = new FileInputStream(file)
	val bys = new Array[Byte](file.length().toInt)
	fis.read(bys)
	fis.close()
	println(bys.length)
	}
}

2. 写入文件

2.1 使用java.io.PrintWriter类

java.io.PrintWriter类是Java提供的一个用于写入文本文件的类。它可以接受一个文件、一个输出流或一个字符串作为参数,然后通过调用其write方法来向文件中写入数据。例如,以下代码可以向文件hello.txt中写入一行文本:

import java.io._
val pw = new PrintWriter(new File("hello.txt"))
pw.write("Hello, world")
pw.close()

使用PrintWriter类写入文件时,有两个需要注意的问题:

  • PrintWriter类不会抛出异常,而是设置一个布尔标志来表示是否发生了错误。可以通过调用其checkError方法来检查是否有错误发生。
  • PrintWriter类默认使用平台的字符编码,这可能导致不同平台之间的不一致。可以通过指定字符编码来避免这个问题。例如,以下代码使用了UTF-8编码:
val pw = new PrintWriter(new File("hello.txt"), "UTF-8")

2.2 使用java.io.FileWriter类

java.io.FileWriter类是Java提供的另一个用于写入文本文件的类。它是OutputStreamWriter的子类,可以接受一个文件或一个字符串作为参数,然后通过调用其write方法来向文件中写入数据。例如,以下代码可以向文件test.txt中写入一行文本:

import java.io._
val file = new File("test.txt")
val bw = new BufferedWriter(new FileWriter(file))
bw.write("We are learning Scala programming language")
bw.close()

使用FileWriter类写入文件时,有两个需要注意的问题:

  • FileWriter类会抛出IOExceptions异常,所以需要使用try-catch-finally语句来处理异常和关闭文件。
  • FileWriter类默认使用平台的字符编码,这可能导致不同平台之间的不一致。FileWriter类没有提供指定字符编码的构造器,所以如果需要指定字符编码,可以使用OutputStreamWriter类代替。例如,以下代码使用了UTF-8编码:
val file = new File("test.txt")
val bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8"))
bw.write("We are learning Scala programming language")
bw.close()

2.3 使用java.io.FileOutputStream类

FileOutputStream是Java提供的一个用于写入二进制文件的类,它是OutputStream的子类,可以接受一个文件或一个字符串作为参数,然后通过调用其write方法来向文件中写入字节数据。例如,以下代码可以向文件data.bin中写入一个整数:

import java.io._
val file = new File("data.bin")
val fos = new FileOutputStream(file)
fos.write(42)
fos.close()

FileOutputStream类会抛出IOExceptions异常,所以需要使用try-catch-finally语句来处理异常和关闭文件。

已收到消息. FileOutputStream是Java提供的一个用于写入二进制文件的类,它是OutputStream的子类,可以接受一个文件或一个字符串作为参数,然后通过调用其write方法来向文件中写入字节数据。例如,以下代码可以向文件data.bin中写入一个整数: scala import java.io._ val file = new File("data.bin") val fos = new FileOutputStream(file) fos.write(42) fos.close() FileOutputStream类会抛出IOExceptions异常,所以需要使用try-catch-finally语句来处理异常和关闭文件。

2.4 几种写入的区别

因为FileOutputStream类有两种构造器,一种接受一个文件对象作为参数,一种接受一个字符串作为参数。如果接受一个字符串作为参数,那么它会自动创建一个文件对象。所以,以下两种写法是等价的:

val pw = new FileOutputStream(new File("./data/3.txt"))
val pw = new FileOutputStream("./data/3.txt")

但是,如果使用PrintWriter类或FileWriter类,那么就必须使用一个文件对象作为参数,不能使用一个字符串。所以,以下两种写法是不等价的:

val pw = new PrintWriter(new File("./data/3.txt"))
val pw = new PrintWriter("./data/3.txt") // 错误

2.5 使用第三方库

除了Java提供的类之外,还有一些第三方库可以用来写入文件,例如Apache Commons IO1和os-lib2等。这些库通常提供了更简洁和高效的API,也支持更多的功能和格式。例如,以下代码使用了Apache Commons IO库的FileUtils类来写入文件,并指定了字符编码:

import org.apache.commons.io.FileUtils
FileUtils.writeStringToFile(new File("test.txt"), "Hello, world", "UTF-8")

以下代码使用了os-lib库的os.File对象来写入文件,并返回一个字节长度:

import os._
os.write(os.pwd / "test.txt", "Hello, world")

3. Scala序列化和反序列化

3.1 什么是序列化和反序列化

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

  • 序列化:把对象写到文件中的过程。
  • 反序列化:从文件中加载对象的过程。

3.2 如何实现序列化和反序列化

一个类的对象要想实现序列化和反序列化操作,则该类必须继承Serializable特质。Serializable特质是一个空特质,它没有任何方法和字段,只是用来标记一个类是否可以被序列化和反序列化。

要实现序列化操作,可以使用java.io.ObjectOutputStream类,它是一个用于写入对象的输出流。它可以接受一个输出流作为参数,然后通过调用其writeObject方法来写入对象。

要实现反序列化操作,可以使用java.io.ObjectInputStream类,它是一个用于读取对象的输入流。它可以接受一个输入流作为参数,然后通过调用其readObject方法来读取对象。

3.3 一个示例

下面给出一个简单的示例,演示如何使用case class和object来实现序列化和反序列化操作。

首先,定义一个case class Person,属性为姓名和年龄。注意,case class会自动继承Serializable特质,所以不需要显式地写出来。

// 定义一个case class Person
case class Person(var name: String, var age: Int)

然后,创建Person样例类的对象p,并通过序列化操作将对象p写入到项目下的data文件夹下的4.txt文本文件中。

// 创建Person样例类的对象p
val p = Person("张三", 23)
// 创建一个ObjectOutputStream对象,传入一个输出流作为参数
val oos = new ObjectOutputStream(new FileOutputStream("./data/4.txt"))
// 调用writeObject方法,将对象p写入到输出流中
oos.writeObject(p)
// 关闭输出流
oos.close()

最后,通过反序列化操作从项目下的data文件夹下的4.txt文件中,读取对象p,并打印出来。

// 创建一个ObjectInputStream对象,传入一个输入流作为参数
val ois = new ObjectInputStream(new FileInputStream("./data/4.txt"))
// 调用readObject方法,从输入流中读取对象,并转换为Person类型
var p: Person = ois.readObject().asInstanceOf[Person]
// 打印对象p
println(p)
// 关闭输入流
ois.close()

3.4 使用注解

除了使用Serializable特质之外,还可以使用@SerialVersionUID注解来指定一个版本号。这样可以避免不同版本的类之间的兼容性问题。例如,以下代码定义了一个普通的类,并添加了注解:

import java.io._
// 使用@SerialVersionUID注解指定版本号为100L
@SerialVersionUID(100L)
// 定义一个普通的类,并继承Serializable特质
class Person(var name: String, var age: Int) extends Serializable

然后,可以使用相同的方式进行序列化和反序列化操作:

val p = new Person("张三", 23)
val oos = new ObjectOutputStream(new FileOutputStream("./data/4.txt"))
oos.writeObject(p)
oos.close()
val ois = new ObjectInputStream(new FileInputStream("./data/4.txt"))
var p: Person = ois.readObject().asInstanceOf[Person]
println(p)

案例-学员成绩表

概述

已知项目下的data文件夹的student.txt文本文件中, 记录了一些学员的成绩, 如下: 格式为: 姓名 语文成绩 数学成绩 英语成绩

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

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

** 步骤**

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

参考代码

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

到此这篇关于Scala文件操作示例代码讲解的文章就介绍到这了,更多相关Scala文件操作内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • scala当中的文件操作和网络请求的实现方法

    1.读取文件当中每一行的数据 def main(args: Array[String]): Unit = { //注意文件的编码格式,如果编码格式不对,那么读取报错 val file: BufferedSource = Source.fromFile("F:\\files\\file.txt","GBK"); val lines: Iterator[String] = file.getLines() for(line <- lines){ println(li

  • Scala文件操作示例代码讲解

    目录 1. 读取数据 1.1 按行读取 1.2 按字符读取 Scala使用source.buffered方法按字符读取文件 一个示例 1.3 读取词法单元和数字 1.4 从URL或者其他源读取数据 1.5 读取二进制文件 2. 写入文件 2.1 使用java.io.PrintWriter类 2.2 使用java.io.FileWriter类 2.3 使用java.io.FileOutputStream类 2.4 几种写入的区别 2.5 使用第三方库 3. Scala序列化和反序列化 3.1 什么

  • python操作toml文件的示例代码

    # -*- coding: utf-8 -*- # @Time : 2019-11-18 09:31 # @Author : cxa # @File : toml_demo.py # @Software: PyCharm import toml import os BASE_DIR = os.path.dirname(os.path.abspath(__file__)) class FileOperation: def __init__(self): self.dic = dict() self

  • python读写文件操作示例程序

    文件操作示例 复制代码 代码如下: #输入文件f = open(r'D:\Python27\pro\123.bak') #输出文件fw = open(r'D:\Python27\pro\123e.bak','w')#按行读出所有文本lines = f.readlines()num = -1for line in lines:    str = '@SES/%i/' %num    line = line.replace('@SES/1/',str)    num = num + 1    #写入

  • PHP5.6读写excel表格文件操作示例

    本文实例讲述了PHP5.6读写excel表格文件操作.分享给大家供大家参考,具体如下: 测试环境:php5.6.24.这块没啥兼容问题. 需要更多栗子,请看PHPExcel的examples.还是蛮强大的. 读取excel文件: 第一步.下载开源的PHPExcel的类库文件,官方网站是http://www.codeplex.com/PHPExcel.里面也有很多示例包. 或者从本站下载:https://www.jb51.net/codes/194070.html 第二步.读取的基本代码示例: <

  • Java使用sftp定时下载文件的示例代码

    sftp简介 sftp是Secure File Transfer Protocol的缩写,安全文件传送协议.可以为传输文件提供一种安全的网络的加密方法.sftp 与 ftp 有着几乎一样的语法和功能.SFTP 为 SSH的其中一部分,是一种传输档案至 Blogger 伺服器的安全方式.其实在SSH软件包中,已经包含了一个叫作SFTP(Secure File Transfer Protocol)的安全文件信息传输子系统,SFTP本身没有单独的守护进程,它必须使用sshd守护进程(端口号默认是22)

  • Java实现图片转换PDF文件的示例代码

    最近因为一些事情,需要将一张简单的图片转换为PDF的文件格式,在网上找了一些工具,但是这些工具不是需要注册账号,就是需要下载软件. 而对于只是转换一张图片的情况下,这些操作显然是非常繁琐的,所以作者就直接使用Java写了一个图片转换PDF的系统,现在将该系统分享在这里. 引入依赖 <!--该项目以SpringBoot为基础搭建--> <parent> <groupId>org.springframework.boot</groupId> <artifa

  • c# 遍历获取所有文件的示例代码

    在使用C#进行桌面应用开发中,经常会有对文件进行操作的情况,这时可能会需要对文件夹进行文件扫描,获取所有文件 做法如下 /// <summary> /// 遍历获取所有文件 /// </summary> /// <param name="filePathByForeach"></param> /// <param name="result"></param> public static void

  • Java定时调用.ktr文件的示例代码(解决方案)

    1.Maven依赖 <!-- Kettle --> <dependency> <groupId>pentaho-kettle</groupId> <artifactId>kettle-core</artifactId> <version>7.1.0.0-12</version> </dependency> <dependency> <groupId>pentaho-kettl

  • C/C++ QT实现解析JSON文件的示例代码

    JSON是一种轻量级的数据交换格式,它是基于ECMAScript的一个子集,使用完全独立于编程语言的文本格式来存储和表示数据,简洁清晰的的层次结构使得JSON成为理想的数据交换语言,Qt库为JSON的相关操作提供了完整的类支持. 创建一个解析文件,命名为config.json我们将通过代码依次解析这个JSON文件中的每一个参数,具体解析代码如下: { "blog": "https://www.cnblogs.com/lyshark", "enable&qu

  • C语言示例代码讲解栈与队列

    目录 栈 栈的定义 顺序栈 顺序栈的定义 顺序栈的初始化 顺序栈的入栈 顺序栈的出栈 取顺序栈的栈顶元素 链栈 队列 队列的定义 队列的顺序表达与实现 队列顺序存储结构 假溢出 循环队列 循环队列的初始化 循环队列的入队 循环队列的出队 链队列 链栈的初始化 链栈的入队 链栈的出队 上文详细的讲解了顺序表与链表的实现,相信大家在顺序表与链表的指基础上,很容易就能学会站和队列,废话不多说,我们马上开始! 栈 栈的定义 栈是一种线性表,但限定这种线性表只能在某一端进行插入和删除操作 假设栈 [s =

随机推荐