I/O processing in Scala

Xử lí input, output luôn là những yêu cầu thiết yếu của bất kì ngôn ngũ lập trình nào. Trong bài viết này chúng ta hãy cùng nhau tìm hiểu làm cách nào để đọc và ghi dữ liệu trong Scala.

1. Standard Input, Output

1.1 Đọc dữ liệu

Để đọc dữ liệu từ standard input, chúng ta có thể dùng các hàm của thư viện scala.io.StdIn

  • readBoolean(): Đọc dữ liệu kiểu Boolean
	scala> var i = readBoolean()
	T
	i: Boolean = true

	scala> var i = readBoolean()
	F
	i: Boolean = false

Lưu ý là nếu chúng ta nhập vào 1 trong các giá trị truetyesy (không phân biệt chữ hoa chữ thường) thì Scala sẽ hiểu đó là true, ngược lại sẽ là false.

  • readByte(): Đọc dữ liệu kiểu Byte
scala> var i = readByte()
1
i: Byte = 1
  • readChar(): Đọc dữ liệu kiểu Char
scala> var i = readChar()
a
i: Char = a
  • readDouble(): Đọc dữ liệu kiểu Double
scala> var i = readDouble()
1.2
i: Double = 1.2
  • readFloat(): Đọc dữ liệu kiểu Float
scala> var i = readFloat()
3.4
i: Float = 3.4
  • readInt(): Đọc dữ liệu kiểu Int
scala> var i = readInt()
100
i: Int = 100
  • readLine(text: String, args: Any*): Đọc 1 dòng từ standard input
scala> var i = readLine()
hello world
i: String = hello world

Chúng ta cũng có thể chỉ định nội dung in ra trước khi nhận vào input:

scala> var i = readLine("Tell me your wish: ")
Tell me your wish: Genie
i: String = Genie
  • readLong(): Đọc dữ liệu kiểu Long
scala> var i = readLong()
123456
i: Long = 123456
  • readShort(): Đọc dữ liệu kiểu Short
scala> var i = readShort()
789
i: Short = 789
  • readf(format: String): Đọc dữ liệu theo format cho trước với định dạng của java.text.MessageFormat và trả về List[Any]
scala> var i = readf("{0}/{1}/{2}")
2015/06/26
i: List[Any] = List(2015, 06, 26)
  • readf1(format: String), readf2(format: String), readf3(format: String): Đọc dữ liệu theo format cho trước với định dạng của java.text.MessageFormat và trả về 1, 2, 3 giá trị đầu tiên
	scala> var i = readf1("{0}/{1}/{2}")
	2015/06/26
	i: Any = 2015

	scala> var i = readf2("{0}/{1}/{2}")
	2015/06/26
	i: (Any, Any) = (2015,06)

	scala> var i = readf3("{0}/{1}/{2}")
	2015/06/26
	i: (Any, Any, Any) = (2015,06,26)

1.2 Xuất dữ liệu

Để xuất dữ liệu ra standard output chúng ta có thể dùng hàm print hoặc println. Điểm khác biệt giữa 2 hàm này là println thêm 1 kí tự newline nữa nên sau khi in ra thì con trỏ sẽ xuống dòng tiếp theo.

scala> println("Hi there!")
Hi there!

scala> print("Hi there!")
Hi there!

Ngoài ra chúng ta cũng có thể dùng hàm printf và format string như kiểu của C:

scala> var name = "Tung"
name: String = Tung

scala>  printf("Hi there! My name is %s.\n", name)
Hi there! My name is Tung.

scala> var i = 1.0 / 3
i: Double = 0.3333333333333333

scala> printf("i = %.2f\n", i)
i = 0.33

2. Xử lí I/O với file

2.1 Đọc dữ liệu

Với Scala chúng ta có rất nhiều cách để đọc dữ liệu từ file, dưới đây mình xin giới thiệu 1 số cách phổ biến nhất.

Giả sử mình có file text.txt với nội dung như dưới:

Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
Sunday

2.1.1 Dùng scala.io.Source (thư viện chuẩn của Scala)

Đọc và in ra từng kí tự:

scala> var file = Source.fromFile("text.txt")
file: scala.io.BufferedSource = non-empty iterator

scala> file.foreach(println)
M
o
n
d
a
y

...

Đọc và in ra từng dòng:

scala> var file = Source.fromFile("text.txt")
file: scala.io.BufferedSource = non-empty iterator

scala> var lines = file.getLines()
lines: Iterator[String] = non-empty iterator

scala> lines.foreach(println)
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
Sunday

Trong trường hợp cần chỉ định encoding của file thì có thể viết như sau:

scala> var file = Source.fromFile("text.txt", "utf-8")
file: scala.io.BufferedSource = non-empty iterator

Các bạn có thể thấy là hàm fromFile() trả về 1 object dạng scala.io.BufferedSource, để lấy ra kết quả dưới dạng string thì các bạn có thể dùng mkString():

scala> var file = Source.fromFile("text.txt")
file: scala.io.BufferedSource = non-empty iterator

scala> var str = file.mkString()
str: String =
"Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
Sunday
"

2.1.2 Dùng java.io.BufferedReader (thư viện của Java)

scala> var reader = new BufferedReader(new FileReader(new File("text.txt")))
reader: java.io.BufferedReader = java.io.BufferedReader@119a3ad

scala> var line : String = null
line: String = null

scala> while({line = reader.readLine; line != null}) {
     |   println(line)
     | }
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
Sunday

2.1.3 Dùng org.apache.commons.io.FileUtils (thư viện của Apache)

Đọc nội dung của cả file và trả về kết quả dạng string:

scala> var str = FileUtils.readFileToString(new File("text.txt"))
str: String =
"Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
Sunday
"

Đọc nội dung của cả file và in ra theo dòng:

scala> var lines = FileUtils.readLines(new File("text.txt"))
lines: java.util.List[String] = [Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday]

scala> import scala.collection.JavaConversions._
import scala.collection.JavaConversions._

scala> lines.foreach(println)
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
Sunday

2 cách trên đều đọc nội dung của cả file và lưu vào memory nên sẽ không thích hợp để đọc những file lớn. Để đọc theo từng dòng chúng ta có thể dùng lineIterator:

scala> var ite = FileUtils.lineIterator(new File("text.txt"))
ite: org.apache.commons.io.LineIterator = org.apache.commons.io.LineIterator@1393f8f

scala> ite.foreach(println)
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
Sunday

2.2 Xuất dữ liệu

Vì Scala không có một thư viện chuẩn nào dành cho việc ghi file (hucau) nên chúng ta đành dùng tạm class java.io.FileWriter của Java

scala> var writer = new FileWriter("out.txt")
writer: java.io.FileWriter = java.io.FileWriter@2696ac

scala> writer.write("Hello Scala")

scala> writer.close

Hoặc chúng ta cũng có thể dùng thư viện FileUtils

scala> FileUtils.write(new File("out.txt"), "Hello Scala")

Tài liệu tham khảo