Input & output in Ruby
Trong phần này chúng ta sẽ tìm hiểu về hệ thống nhập xuất trong Ruby. Khi chạy một chương trình thì chương trình có thể nhận các dòng dữ liệu đi vào, có thể là từ bàn phím, file hoặc từ chính một chương trình khác. Tương tự, chương trình cũng có thể xuất các dòng dữ liệu đi ra ngoài, thường là sẽ ...
Trong phần này chúng ta sẽ tìm hiểu về hệ thống nhập xuất trong Ruby. Khi chạy một chương trình thì chương trình có thể nhận các dòng dữ liệu đi vào, có thể là từ bàn phím, file hoặc từ chính một chương trình khác. Tương tự, chương trình cũng có thể xuất các dòng dữ liệu đi ra ngoài, thường là sẽ đi đến màn hình, đi vào một file hoặc đi vào một chương trình khác.
Xuất dữ liệu ra
Xuyên suốt series này chúng ta đã thực hiện việc xuất dữ liệu rất nhiều lần bằng các phương thức có trong Ruby. Các phương thức này tồn tại trong module Kernel. Ví dụ 1:
output1.rb print "Apple " print "Apple " puts "Orange" puts "Orange"
Hai phương thức print và puts là 2 phương thức xuất dữ liệu là các chuỗi text ra màn hình, trong đó phương thức puts sẽ in chuỗi rồi xuống dòng còn phương thức print thì không.
print "Apple
"
Nếu muốn phương thức print có xuống dòng thì chúng ta thêm kí tự vào.
Output Apple Apple Orange Orange
Ví dụ 2:
output2.rb p "Lemon" p "Lemon" printf "There are %d apples ", 3 putc 'K' putc 0xA
Chúng ta tiếp tục tìm hiểu một số phương thức in dữ liệu khác.
p "Lemon"
Phương thức p sẽ gọi phương thức inspect của đối tượng. Phương thức inspect là một phương thức của lớp Object, thường thì phương thức này sẽ in ra tên lớp cùng các thông tin liên quan.
printf "There are %d apples ", 3
Phương thức printf in chuỗi và cho phép truyền tham số vào trong chuỗi.
putc 'K' putc 0xA
Phương thức putc chỉ đơn giản là in một kí tự ra màn hình. Giá trị 0xA là giá trị của kí tự xuống dòng trong bảng mã ASCII. Tức thay vì ở đây chúng ta dùng putc " " thì chúng ta có thể in 0xA thay thế.
Output "Lemon" "Lemon" There are 3 apples K
Đọc dữ liệu vào
Ví dụ 1:
input1.rb print "Enter your name: " name = gets puts "Hello #{name}"
Để đọc dữ liệu vào thì chúng ta dùng phương thức gets.
name = gets
Phương thức gets sẽ nhận một chuỗi nhập vào từ bàn phím. Khi chạy chương trình, đến đoạn gọi phương thức gets thì chương trình sẽ dừng lại chờ chúng ta gõ một chuỗi nào đó rồi bấm ENTER thì chuỗi đó sẽ được truyền vào biến name.
Output Enter your name: thangtx Hello thangtx
Ví dụ 2:
input2.rb print "Enter a string: " str = gets puts "String size: #{str.size}"
Phương thức size sẽ trả về số lượng kí tự có trong chuỗi
Output Enter a string: abc String size: 4
Kết quả in ra là 4 trong khi chuỗi của chúng ta nhập vào chỉ là "abc" tức là chỉ có 3 chữ cái thôi, lý do là vì phương thức gets tính luôn cả kí tự ENTER mà chúng ta gõ phía sau nữa nên thành 4.
Để loại bỏ kí tự ENTER này ra khỏi chuỗithì chúng ta dùng phương thức chomp.
input2.rb print "Enter a string: " str = gets.chomp puts "String size: #{str.size}"
Như thế phương thức size sẽ cho ra đúng số lượng kí tự đã được nhập vào.
Output Enter a string: abc String size: 3
File
Tất cả các công việc nhập dữ liệu vào và xuất dữ liệu ra đều được quản lý bởi một lớp có tên là IO, ngoài ra Ruby còn có các lớp con khác kế thừa từ lớp IO nhằm mục đích thực hiện việc nhập xuất trên các dòng dữ liệu khác nhau, trong đó có lớp File dùng để nhập xuất file.
Ví dụ 1:
file_io1.rb f = File.open('C:output.txt', 'w') f.puts "The Ruby tutorial" f.close
Trong ví dụ này chúng ta thực hiện ghi dữ liệu lên file.
f = File.open('C:output.txt', 'w')
Để ghi dữ liệu vào file thì trước tiên chúng ta phải mở file đó đã bằng phương thức File.open(), phương thức này nhận vào tham số là đường dẫn đến file và chế độ mở, ở đây tên file là output.txt và chế độ mở là w (write) tức là mở file để ghi.
f.puts "The Ruby tutorial"
Phương thức open sẽ trả về một đối tượng stream, nói cho đơn giản thì bạn cứ hình dung stream chính là những thứ như Kernel vậy, nếu bạn đã từng làm việc với C++ thì stream ở đây giống như đối tượng std::cout ấy. Và ở đây chúng ta có thể dùng đối tượng stream đó để ghi dữ liệu lên file bằng phương thức puts.
f.close
Sau khi đã làm việc với file xong thì chúng ta đóng file lại bằng phương thức close.
Ví dụ 2:
file_io2.rb File.open('C:output.txt', 'w') do |f| f.puts "Ruby" f.write "Java " f << "Python " end
Nếu chúng ta mở file trong khối lệnh File.open()...end thì sau khi kết thúc chúng ta không cần phải đóng file nữa mà Ruby sẽ tự đóng cho chúng ta.
f.puts "Ruby" f.write "Java " f << "Python "
Ngoài ra ở đây chúng ta dùng thêm phương thức write và toán tử << để in chuỗi ra màn hình.
Ví dụ 3:
file_io3.rb puts File.exists? 'C: empfile' f = File.new 'C: empfile', 'w' puts File.mtime 'C: empfile' puts f.size File.rename 'C: empfile', 'C: empfile2' f.close
Lớp File ngoài việc hỗ trợ nhập xuất còn có một số phương thức khác.
puts File.exists? 'C: empfile'
Phương thức exists? kiểm tra xem một file có tồn tại hay không.
f = File.new 'C: empfile', 'w'
Phương thức new sẽ tạo một file mới trên đĩa cứng.
puts File.mtime 'C: empfile'
Phương thức mtime lấy thời gian chỉnh sửa file lần cuối cùng.
puts f.size
Phương thức size trả về kích thước của file.
File.rename 'C: empfile', 'C: empfile2'
Phương thức rename sẽ đổi tên file.
Output false 2011-11-05 16:19:36 +0100 0
Ví dụ 4:
file_io4.rb f = File.open("C:input.txt") while line = f.gets do puts line end f.close
Trong ví dụ này chúng ta sẽ đọc một file.
f = File.open("C:input")
Để đọc một file thì trước tiên chúng ta cũng phải mở file đó đã, ở đây chúng ta không đưa vào tham số chế độ mở là vì mặc định Ruby sẽ mở file theo chế độ đọc.
while line = f.gets do puts line end
Phương thức gets sẽ đọc từng dòng dữ liệu trong file, chúng ta lưu dữ liệu đó trong biến line, vòng lặp while có tác dụng kiểm tra xem biến line có rỗng hay không, tức là trong khi file vẫn còn dữ liệu để đọc thì chúng ta thực hiện đoạn code bên trong vòng lặp.
Output Ruby Java Python
Ngoài phương thức gets có chức năng đọc từng dòng thì còn có phương thức readlines sẽ đọc tất cả các dòng trong file và lưu vào một mảng. Cũng vì thế nên bạn lưu ý đối với các file có kích thước lớn.
file = 'C:input' File.readlines(file).each do |line| puts line end Output Ruby Java Python
Thư mục
Ruby có lớp Dir hỗ trợ làm việc với thư mục.
directory.rb Dir.mkdir "tmp" puts Dir.exists? "tmp" puts Dir.pwd Dir.chdir "tmp" puts Dir.pwd Dir.chdir '..' puts Dir.pwd Dir.rmdir "tmp" puts Dir.exists? "tmp"
Trong ví dụ trên chúng ta làm việc với 4 phương thức của lớp Dir.
Dir.mkdir "tmp"
Phương thức mkdir sẽ tạo một thư mục mới.
puts Dir.exists? "tmp"
Phương thức exists? kiểm tra xem một thư mục có tồn tại hay không.
puts Dir.pwd
Phương thức pwd in ra đường dẫn đến thư mục hiện tại. Đây là thư mục chứa file code Ruby mà chúng ta đang viết.
Dir.chdir '..'
Phương thức chdir thay đổi thư mục hiện tại thành thư mục khác. Ở đây dấu ".." tức là lùi về thư mục cha.
Dir.rmdir "tmp" puts Dir.exists? "tmp"
Phương thức rmdir sẽ xóa một thư mục.
Output true C:/Program Files (x86)/Notepad++ C:/Program Files (x86)/Notepad++/tmp C:/Program Files (x86)/Notepad++ false
Chuyển hướng dòng nhập xuất
Như bình thường chúng ta dùng phương thức puts, print... để in dữ liệu lên màn hình. Trong các bài trước chúng ta đã biết phương thức puts là phương thức của module Kernel, tức là gọi Kernel.puts "Ruby" sẽ tương đương với puts "Ruby". Ngoài ra Ruby còn có một số biến toàn cục tham chiếu tới các module đó nữa, biến stdout là một ví dụ, đây là biến tham chiếu tới module Kernel, tức là bây giờ chúng ta có 3 cách dùng phương thức puts khác nhau là Kernel.puts “”, stdout.puts "" hoặc puts "".
Chính vì biến $$tdout tham chiếu tới module Kernel nên phương thức puts gọi từ biến này sẽ xuất dữ liệu lên màn hình nhưng chúng ta cũng có thể chuyển hướng để biến này xuất dữ liệu ra nơi khác.
$stdout = File.open "C:output.log", "a" puts "Ruby" puts "Java" $stdout.close $stdout = STDOUT puts "Python"
Trong ví dụ trên chúng ta chuyển hướng dòng dữ liệu xuất ra từ màn hình sang file output.log.
$stdout = File.open "C:output.log", "a"
Như chúng ta đã biết, phương thức File.open sẽ trả về một đối tượng stream, chúng ta gán stream đó vào biến $$tdout.
puts "Ruby" puts "Java"
Khi chúng ta gọi phương thức puts, dữ liệu xuất ra sẽ được tự động ghi vào file thay vì ghi lên màn hình như trước.
$stdout = STDOUT puts "Python"
Nếu chúng ta chuyển hướng lại vào hằng số STDOUT thì dòng dữ liệu xuất ra từ các phương thức puts, print... sẽ lại đi vào màn hình chứ không đi vào file nữa.