Basic Input and Output

2024-06-09 09:38
文章标签 input output basic

本文主要是介绍Basic Input and Output,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一开始时你会以为 Ruby 提供了两组独立的 IO
例程。第一种是基本接口,目前为止我们一直都是使用它。

print "Enter your name: "
name = gets

Kernel 模块中实现了一组完整的 IO 相关方法,比如
getopenprintprintfputcputsreadlinereadlines
test,这些方法使得编写 Ruby
程序更加方便和简洁。这些方法通常对标准输入输出进行 I/O
操作,这有利于它们编写过滤器。你可以从 411 页开始查看文档。

第二种方式就是通过 IO 对象完成很多自定义的控制。

IO 对象是什么?

Ruby 定义了单独一个基础类—— IO,它可以操作输入输出。File
BasicSocket
都是它的子类,并在它的基础上实现了很多个性化的操作,不过原则是不变的。一个
IO 对象就是一个在 Ruby
程序和外部资源之间的双向通道。(对于那些想了解实现细节的人来说,这个双向通道意味着一个单独的
IO
对象有时需要管理不止一个操作系统的文件描述符。比如,如果你开启了一对管道,那一个
IO 对象就包含一个读管道和一个写管道。)也就是说一个 IO
对象比你看到的包含更多,不过在最后你可以轻松的写入其中或从其中读取。

在这章中,我们会专注于 IO 类以及它比较常用的子类—— File
类。对于在网络中使用
socket 类的细节可以看从 469 页开始的部分。

打开和关闭文件

你也许希望可以用 File.new 创建新的文件对象。

aFile = File.new("testfile", "r")# ... process the fileaFile.close

你通过只读,只写或读写的方式创建 File
对象,不同的创建文件模式根据模式字符串决定(例子中我们是通过 r
确定以只读模式打开 testfile 文件的)。可使用的模式列表在
326
页。当创建文件时你也可以随意指定它的权限,关于这里的细节可以查阅 303
页的内容。在打开文件后你便可以操作它,可以读或写自己需要的数据。最后,出于对软件的负责我们还应该关闭文件,以确认缓冲数据都已经完全写入文件并且相关资源都得到释放。

不过 Ruby 也可以使你的生活更加简单。File.open
也可以打开文件。在常规使用上它与 File.new
的行为相似。但是,如果有关联代码块需要调用的话 open
会有些区别。与返回新的 File
对象不同,它将调用代码块并以刚打开的 File
作为参数。当代码块退出时文件也将自动关闭。

File.open("testfile", "r") do |aFile|# ... process the fileend

读写文件

与基本的 I/O 类似的方法对文件对象也是有用的。所以,gets
是从标准输入读取一行内容,aFile.gets 也是从文件对象 aFile
中读取一行内容。

不过 I/O
对象喜欢一组额外的访问方法,这些方法的目的是使我们的工作更加轻松。

迭代器读取文件

和用常规循环从 IO 流中读取数据一样,你也可以使用多种 Ruby
的迭代器。IO#each_byte 会从 IO 对象中连续读取 8
位字节并调用代码块。

aFile = File.new("testfile")
aFile.each_byte {|ch| putc ch; putc ?. }

结果是:

T.h.i.s. .i.s. .l.i.n.e. .o.n.e.
.T.h.i.s. .i.s. .l.i.n.e. .t.w.o.
.T.h.i.s. .i.s. .l.i.n.e. .t.h.r.e.e.
.A.n.d. .s.o. .o.n.......
.

IO#each_line
从文件中读取下一行内容并调用代码块。下面的例子中我们会用 String#dump
让原始的换行符可见,所以你会知道我们并没有说谎。

aFile.each_line {|line| puts "Got #{line.dump}" }

结果是:

Got "This is line one\n"
Got "This is line two\n"
Got "This is line three\n"
Got "And so on...\n"

你可以将任意字符串作为行分隔符向 each_line
传参,转入内容也会按照相应的分隔符进行分隔,最后还会将每行数据至结束字符间的内容返回。这就是你可以在上个例子中看见
「\n」输出的原因。下面的例子中,我们要用
「e」作为行分隔符。

aFile.each_line("e") do |line|puts "Got #{ line.dump }"
end

结果是:

Got "This is line"
Got " one"
Got "\nThis is line"
Got " two\nThis is line"
Got " thre"
Got "e"
Got "\nAnd so on...\n"

如果你结合迭代器和使用代码块时文件会自动关闭的特点就会产生
IO.foreach。这个方法需要将 I/O
资源的名称作为入参,将其打开并调用迭代器对文件的每行内容读取,再自动关闭文件。

IO.foreach("testfile") { |line| puts line }

结果是:

This is line one
This is line two
This is line three
And so on...

或者如果你喜欢,你也可以将文件内容收集为行的数组。

arr = IO.readlines("testfile")
arr.length             »4
arr[0]                 »"This is line one\n"

不要忘记 I/O
在非必然世界中不一定有必然的结果,有时许多错误情况都会导致异常,你应该为捕捉它们并做出合适的反应作好准备。

写入文件

我们所写的例子中几乎都调用了 putsprint
方法,并且传递任意的对象,然后只能依赖 Ruby
会做正确的行为(当然,它确实也做到了)。不过它是怎么准确做到的呢?

答案非常简单。除了少量的例外情况,每个传递给 putsprint
的对象都是通过调用对象的 to_s
方法转换为字符串的。如果由于某些原因 to_s
方法没有返回有效字符串,将会创建一个包含对象类名及 id
的字符串返回,像 <ClassName:0x123456> 这样。

异常情况也比较常见。nil
对象会作为字符串「nil」打印,传参给 puts
的数组将对其中的每个元素分别打印。

如果你想输出二进制数据又不希望 Ruby
弄乱它,需要怎么做?一般情况下你可以用 IO#print
并将包含字节码的字符串传入。不过你也可以通过低级别的输入输出例程完成此功能,可以查阅
335 页的 IO#sysreadIO#syswrite 方法。

首先你要怎样将二进制数据转换为字符串呢?有两个类似功能的方法,一种是将字节码按字节码的方式输入,另一种是通过
Array#pack 方法。

str = ""                     »""
str << 1 << 2 << 3           »"\001\002\003"
[ 4,str 5, 6 ].pack("c*")    »"\004\005\006"

但我忘记了 C++ 输入输出流

有时个人品味是没法解释的。不过,既然可以通过 <<
操作符将对象附加至 Array,也可以将对象到输出的 IO 流中。

endl = "\n"
$stdout << 99 << " red balloons" << endl

结果是:

99 red balloons

再说明一下,<< 方法会在将参数传递之前通过它们的 to_s
方法将它们转换为字符串。

与网络交流

无论是低级别还是高级别的网络协议的使用上,Ruby
都表现出了流畅性。

对于喜欢在网络级别上钻研的人,Ruby 为他们在 socket
库中准备了一系列相关的类。这些类可以帮助你访问 TCP,UDP,SOCKS
及 Unix
主要网络接口,以及架构上支持的任何网络接口类型。库中也提供了帮助类,可以使用帮助类很方便地编写服务器。下面是一个简单的例子,我们通过
finger 协议从本地机器上获得关于「oracle」用户的相关信息。

require 'socket'
client = TCPSocket.open('localhost', 'finger')
client.send("oracle\n", 0)    # 0 means standard packet
puts client.readlines
client.close

结果是:

Login: oracle         Name: Oracle installation
Directory: /home/oracle             Shell: /bin/bash
Never logged in.in
No Mail.
No Plan.

在更高层中,net 库模块提供了相关的处理类对应用层协议(一般有 FTP, HTTP,
POP, SMTP, 和网络)进行操作。相关文档可从 482
页开始查阅。例如,下面的程序将列举 Pragmatic Programmer
主页显示的图片。

require 'net/http'h = Net::HTTP.new('www.pragmaticprogrammer.com', 80)
resp, data = h.get('/index.html', nil)
if resp.message == "OK"data.scan(/<img src="(.*?)"/) { |x| puts x }
end

结果是:

images/title_main.gif
images/dot.gif
images/dot.gif
images/dot.gif
images/aafounders_70.jpg
images/pp_cover_thumb.png
images/ruby_cover_thumb.png
images/dot.gif
images/dot.gif

本文翻译自《Programming Ruby》,主要目的是自己学习使用,文中翻译不到位之处烦请指正,如需转载请注明出处

本章原文为 Basic Input and
Output

这篇关于Basic Input and Output的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1044817

相关文章

查看Excel 中的 Visual Basic 代码,要先设置excel选项

1. excel VB的简单介绍 百度安全验证 2.excel选项设置 excel表格中在选项->自定义功能区域,选择开发工具,visual baisc/查看代码,即可看到代码。 3.excel已经设置,可以直接查看

vue中oninput和@input区别

使用oninput绑定,此方法会导致中文输入法情况下,v-model和value不一致,原因是在中文输入法情况下vue中的v-model会自动return,v-mode绑定的值不变,value绑定的值可变。 :οninput="value=value.replace(/\D/g,'')" @input="row[item.prop]=row[item.prop].replace(/\D/g,'

Caused by: java.lang.NumberFormatException: For input string: “?2130969371“

Caused by: java.lang.NumberFormatException: For input string: "?2130969371"   题记报错。 上结论:"?2130969371" ,即:”?attr/sudScrollIndicator“, 是因为sudScrollIndicator自定义属性主题未给定值引起。   在AS工程引入setupdesign和setup

【unity实战】利用Root Motion+Blend Tree+Input System+Cinemachine制作一个简单的角色控制器

文章目录 前言动画设置Blend Tree配置角色添加刚体和碰撞体代码控制人物移动那么我们接下来调整一下相机的视角效果参考完结 前言 Input System知识参考: 【推荐100个unity插件之18】Unity 新版输入系统Input System的使用,看这篇就够了 Cinemachine虚拟相机知识参考: 【推荐100个unity插件之10】Unity最全的最详细的C

【Python报错已解决】`EOFError: Ran out of input`

🎬 鸽芷咕:个人主页  🔥 个人专栏: 《C++干货基地》《粉丝福利》 ⛺️生活的理想,就是为了理想的生活! 文章目录 引言:一、问题描述:1.1 报错示例:1.2 报错分析:1.3 解决思路: 二、解决方法:2.1 方法一:检查文件内容2.2 步骤二:使用`file.tell()`和`file.seek()`调整文件指针 三、其他解决方法

解决el-table中使用el-input无法聚焦问题

在el-table中点击单元格时使用el-input或其他表单组件编辑单条数据。会出现聚焦不上的问题,需要手动点击才能够聚焦。究其原因是因为点击单元格时页面已自动聚焦到单元格,此时无法自动聚焦到对应的表单,需要手动设置。 <template><el-table:data="tableData"@cell-click="cellclickHandle"><el-table-column

Android Studio解决Build Output乱码问题

解决方案:双击Shift键,在Actions中选择Edit Custom VM Options,然后输入-Dfile.encoding=UTF-8,重启Android Studio即可。

vue使用html2Canvas导出图片 input文字向上偏移

vue使用html2Canvas导出图片 input文字向上偏移 图中 用的是element的输入框 行高 32px,经常测试 你使用原生的input 还是会出现偏移。 解决方法:修改css样式 1.怎么实现导出 网上随便找很多 2.在第一步 获取你要导出的元素id 克隆后 修改他的样式或者 你直接在你需要打印的页面全局修改样式 3.主要是重置字体的行高,我这里输入框高度是32p

mybatis 出错:java.lang.NumberFormatException: For input string: “A“

@GetMapping("/generateOldCarModelRanking")@ApiOperation("老旧车车型排名")public Result generateOldCarModelRanking(@RequestParam(value = "year")String year,@RequestParam(value = "isCommercial")boolean isCom

文件包含PHP伪协议利用方法(file,php://filter,php://input,data://,zip://,phar://)

1、file 2、php://filter 3、php://input 使用BP抓包   4、data:// 5、zip:// 6、phar://