Elixir学习笔记——输入输出和文件系统

news2024/11/24 16:23:05

本章介绍输入/输出机制、文件系统相关任务以及相关模块(如 IO、File 和 Path)。IO 系统提供了一个很好的机会来阐明 Elixir 和 Erlang VM 的一些思维模式和新奇思想。

输入输出模块

输入输出模块是 Elixir 中读写标准输入/输出 (:stdio)、标准错误 (:stderr)、文件和其他输入输出设备的主要机制。该模块的使用非常简单:

默认情况下,输入输出模块中的函数从标准输入读取并写入标准输出。我们可以通过传递 :stderr 作为参数(以便写入标准错误设备)来更改此设置:

文件模块

文件模块包含允许我们将文件作为输入输出设备打开的函数。默认情况下,文件以二进制模式打开,这要求开发人员使用输入输出模块中的特定 IO.binread/2 和 IO.binwrite/2 函数:

潜在数据丢失警告
以下代码打开一个文件进行写入。如果给定路径上有现有文件,则将删除其内容。

可以使用 :append 选项而不是 :write 打开文件以保留其内容。您还可以传递 :utf8 选项,该选项告诉 File 模块将从文件读取的字节解释为 UTF-8 编码的字节。

除了用于打开、读取和写入文件的函数外,File 模块还有许多用于文件系统的函数。这些函数以它们的 UNIX 等效函数命名。例如,File.rm/1 可用于删除文件,File.mkdir/1 可用于创建目录,File.mkdir_p/1 可用于创建目录及其所有父链。甚至还有 File.cp_r/2 和 File.rm_rf/1 分别用于递归复制和删除文件和目录(即,也复制和删除目录的内容)。

您还会注意到 File 模块中的函数有两种变体:一种是“常规”变体,另一种是带有尾随感叹号 (!) 的变体。例如,当我们读取上面示例中的“hello”文件时,我们使用 File.read/1。或者,我们可以使用 File.read!/1:

请注意,带有 ! 的版本返回文件的内容而不是元组,如果出现任何问题,该函数会引发错误。

没有 ! 的版本当您想使用模式匹配处理不同的结果时,是首选:

但是,如果您希望文件在那里,则感叹号变体更有用,因为它会引发有意义的错误消息。避免写:

因为,如果发生错误,File.read/1 将返回 {:error,reason},并且模式匹配将失败。您仍将获得所需的结果(引发错误),但消息将与不匹配的模式有关(因此对于错误的具体含义却一无所知)。

因此,如果您不想处理错误结果,请优先使用以感叹号结尾的函数,例如 File.read!/1。

路径模块

文件模块中的大多数函数都要求将路径作为参数。最常见的是,这些路径将是常规二进制文件。路径模块提供了处理此类路径的功能:

最好使用路径模块中的函数,而不是直接操作字符串,因为路径模块可以透明地处理不同的操作系统。最后,请记住,在 Windows 上执行文件操作时,Elixir 会自动将斜杠 (/) 转换为反斜杠 (\)。

至此,我们介绍了 Elixir 提供的用于处理输入输出和与文件系统交互的主要模块。在下一节中,我们将深入了解一下,并了解输入输出系统如何在 VM 中实现。

进程

您可能已经注意到 File.open/2 返回一个类似 {:ok, pid} 的元组:

发生这种情况是因为输入输出模块实际上与进程一起工作(请参阅上一章)。假设文件是​​一个进程,当您写入已关闭的文件时,实际上是在向已终止的进程发送一条消息:

让我们更详细地了解当您请求 IO.write(pid, binary) 时会发生什么。输入输出模块向 pid 标识的进程发送一条消息,其中包含所需的操作。一个小的临时进程可以帮助我们看到它:

在 IO.write/2 之后,我们可以看到打印出来的输入输出模块发送的请求(一个四元素元组)。不久之后,我们看到它失败了,因为输入输出模块期望某种结果,而我们没有提供。

通过使用进程对输入输出设备进行建模,Erlang VM 甚至允许我们跨节点读取和写入文件。太棒了!

iodata 和 chardata

在上面的所有示例中,我们在写入文件时都使用了二进制文件。但是,Elixir 中的大多数 IO 函数也接受“iodata”或“chardata”。

使用“iodata”和“chardata”的主要原因之一是性能。例如,假设您需要在应用程序中向某人打招呼:

由于 Elixir 中的字符串是不可变的,与大多数数据结构一样,上面的示例会将字符串“Mary”复制到新的“Hello Mary!”字符串中。虽然这对于上面的短字符串来说不太可能,但对于大字符串来说,复制可能非常昂贵!因此,Elixir 中的 IO 函数允许您传递字符串列表:

在上面的示例中,没有复制。相反,我们创建一个包含原始名称的列表。我们将此类列表称为“iodata”或“chardata”,我们很快就会了解它们之间的确切区别。

这些列表非常有用,因为它实际上可以在几种情况下简化字符串的处理。例如,假设您有一个值列表,例如 [“apple”、“banana”、“lemon”],您希望用逗号分隔这些值写入磁盘。您如何实现这一点?

一种方式是使用 Enum.join/2 并将值转换为字符串:

以上通过将每个值复制到新字符串中来返回一个新字符串。但是,有了本节中的知识,我们知道我们可以将字符串列表传递给 IO/File 函数。因此我们可以这样做:

"iodata" 和 "chardata" 不仅包含字符串,还可能包含任意嵌套的字符串列表:

"iodata" 和 "chardata" 也可能包含整数。例如,我们可以使用 ? 作为分隔符来打印以逗号分隔的值列表,该分隔符表示逗号 (44):

"iodata" 和 "chardata" 之间的区别正是所述整数所代表的内容。对于 iodata,整数表示字节。对于 chardata,整数表示 Unicode 码位。对于 ASCII 字符,字节表示与码位表示相同,因此它适合这两种分类。但是,默认 IO 设备与 chardata 一起工作,这意味着我们可以这样做:

总体而言,列表中的整数可能表示一堆字节或一堆字符,使用哪一个取决于 IO 设备的编码。如果文件未经过编码打开,则文件应处于原始模式,并且必须使用 IO 模块中以 bin* 开头的函数。这些函数需要 iodata 作为参数,其中列表中的整数表示字节。

另一方面,默认 IO 设备 (:stdio) 和使用 :utf8 编码打开的文件与 IO 模块中的其余函数一起工作。这些函数需要 chardata 作为参数,其中整数表示码位。

虽然这是一个微妙的差异,但如果您打算将包含整数的列表传递给这些函数,则只需担心这些细节。如果您传递二进制文件或二进制文件列表,则不会出现歧义。

最后,还有最后一个构造称为 charlist,我们在前面的章节中讨论过。Charlist 是 chardata 的一个特例,其中所有值都是表示 Unicode 码位的整数。它们可以用 ~c 符号创建:

字符列表主要出现在与 Erlang 交互时,因为一些 Erlang API 使用字符列表作为字符串的表示。因此,任何包含可打印 ASCII 码位的列表都将打印为字符列表:

我们在这个小部分中塞进了很多内容,让我们来整理一下:

1.iodata 和 chardata 是二进制和整数的列表。这些二进制和整数可以任意嵌套在列表中。它们的目标是在使用 IO 设备和文件时提供灵活性和性能;

2.iodata 和 chardata 之间的选择取决于 IO 设备的编码。如果文件在没有编码的情况下打开,则文件需要 iodata,并且必须使用以 bin* 开头的 IO 模块中的函数。默认 IO 设备 (:stdio) 和使用 :utf8 编码打开的文件需要 chardata,并与 IO 模块中的其余函数配合使用;

3.charlists 是 chardata 的一个特例,它专门使用整数 Unicode 代码点列表。它们可以使用 ~c 符号创建。如果列表中的所有整数都代表可打印的 ASCII 代码点,则使用 ~c 符号自动打印整数列表。

这结束了我们对 IO 设备和 IO 相关功能的介绍。我们了解了三个 Elixir 模块 - IO、File 和 Path - 以及 VM 如何使用进程来实现底层 IO 机制以及如何使用 chardata 和 iodata 进行 IO 操作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1827984.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HTML表格的跨行与跨列:《红楼梦》人物与小学课表示例

在HTML中,表格不仅可以按常规行和列排列数据,还可以通过跨行(rowspan)和跨列(colspan)属性来合并单元格,以适应更复杂的数据展示需求。以下是跨行与跨列属性的介绍,以及两个示例&…

centos环境上:k8s 简单安装教程

本次演示安装3节点k8s环境,无需多言,直接上操作步骤: 1、环境准备 k8s部署前,首先需要准备好环境,除了1.4 步骤,其他步骤在所有(3个)节点上都要执行: 1.1 关闭防火墙 s…

移动硬盘数据恢复方法哪个好?六个硬盘恢复,新手也能用!

移动硬盘数据恢复方法哪个好?移动硬盘,作为我们存储重要数据的常用设备,一旦里面的视频、文档、音频等资料突然消失,确实会令人烦恼和担忧。然而,因为数据丢失的原因可能多种多样,因此恢复方法也会有所不同…

ABBYY Finereader 15软件下载及安装教程

ABBYY FineReader 是一款功能强大的 OCR(Optical Character Recognition)软件,可以将扫描的文档转换为可编辑的文本文件。它不仅可以识别文本,还可以识别表格、图像和布局,使得文档的转换更加准确和方便。 安 装 包 获…

【计算机毕业设计】基于Springboot的车辆管理系统【源码+lw+部署文档】

包含论文源码的压缩包较大,请私信或者加我的绿色小软件获取 免责声明:资料部分来源于合法的互联网渠道收集和整理,部分自己学习积累成果,供大家学习参考与交流。收取的费用仅用于收集和整理资料耗费时间的酬劳。 本人尊重原创作者…

基于51单片机的烟雾报警器设计-ADC0809

一.硬件方案 火灾报警器采用51单片机为核心控制器,利用气体传感器MQ-2、ADC0809模数转换器、DS18B20温度传感器等实现基本功能。通过这些传感器和芯片,当环境中可燃气体浓度或温度等发生变化时系统会发出相应的灯光报警信号和声音报警信号,以…

使用python绘制三维曲线图

使用python绘制三维曲线图 三维曲线图定义特点 效果代码 三维曲线图 三维曲线图(3D曲线图)是一种用于可视化三维数据的图表,它展示了数据在三个维度(X、Y、Z)上的变化。 定义 三维曲线图通过在三维坐标系中绘制曲线…

Arduino入门2——常用函数及用法

Arduino入门2——串口驱动函数及用法 IO串口 上期,我们简单的认识了一下Arduino,浅浅的入了个门,这一期我们介绍以下Arduino串口常用的函数及用法 IO 常用串口库函数如下: 函数名用法及解析pinMode()用于IO口初始化digitalWrite…

新政出台,房市热闹起来,卖房容易了,上海二手房东多卖360万

在517新政之后,上海的中介和房地产商售楼部都表示,如今咨询买房的人士大幅增长,而二手房东也迅速调涨价格,某二手房东表示当天调价,当天就成功卖出,卖出价格比之前增加了360万。 据悉该房东其实早已有意卖房…

数据结构01 栈及其相关问题讲解【C++实现】

栈是一种线性数据结构,栈的特征是数据的插入和删除只能通过一端来实现,这一端称为“栈顶”,相应的另一端称为“栈底”。 栈及其特点 用一个简单的例子来说,栈就像一个放乒乓球的圆筒,底部是封住的,如果你想…

python-基础篇-类与对象/面向对象程序设计-是什么

文章目录 定义一:面对对象是一种编程思想定义一:面向对象是一种抽象1、面向对象的两个基本概念2、面向对象的三大特性 定义一:你是土豪,全家都是土豪面向对象编程基础类和对象定义类创建和使用对象访问可见性问题面向对象的支柱 定…

java打印helloworld

源代码 public class Function1 {public static void main(String[] args) {System.out.println("hello world");}} 打印结果

PyQT5 键盘模拟/鼠标连点器的实现

近来在玩一个游戏,找不到合适的鼠标连点器,不是有广告就是功能太复杂,自己写了一个,分享出来,如果有需要的可以自行运行研究。 准备工作 Python版本:Python 3.12.3;运行前确保pyQT5已经安装: pip install PyQt5程序运行界面: 程序代码: 通过引入单独的常量和变…

C++ 53 之 继承中同名成员处理

#include <iostream> #include <string> using namespace std;class Base06{ public:int m_a;Base06(){this->m_a 10;}void fun(){cout << "父类的fun函数" << endl;}void fun(int a){cout << "父类的fun(int a)函数" &…

模仿qsort实现一个通用的冒泡排序

目录 前言 模仿 排序整型数组 排序结构体数组 排序字符数组 前言 qsort在前面我们讲到底层逻辑是快速排序的方式&#xff0c;是不是可以发现有了qsort来进行排序的话&#xff0c;就更加的方便快捷&#xff0c;我们在使用的时候 一方面&#xff0c;代码量会大大的减少 另一…

JVM 性能分析——jdk 自带命令分析工具(jps/jstat/jinfo/jmap/jhat/jstack)

文章目录 jps&#xff08;Java Process Status&#xff09;&#xff1a;查看正在运行的Java进程jstat&#xff08;JVM Statistics Monitoring Tool&#xff09;&#xff1a;查看 JVM 的统计信息jinfo&#xff08;Configuration Info for Java&#xff09;&#xff1a;实时查看和…

vs+qt5.0 使用poppler 操作库

Poppler 是一个用来生成 PDF 的C类库&#xff0c;从xpdf 继承而来。vs编译库如下&#xff1a; vs中只需要添加依赖库即可 头文件&#xff1a;

SAP HCM 员工供应商过账详解 财务角度理解员工供应商过账

导读 INTRODUCTION 员工供应商:在某些情况下,特别是在大型组织或集团公司中,员工可能同时扮演着供应商的角色,为组织内部的其他部门或子公司提供产品或服务。例如,一个技术部门的员工可能为销售部门提供技术支持或定制开发服务。,还有一种,就是员工在公司挂账的欠款,每…

zip加密txt文件后,暴力破解时会有多个解密密码可以打开的疑问??

最近在做一个关于zip压缩文件解密的测试&#xff0c;发现通过暴力解密时&#xff0c;会有多个解密密码可以打开&#xff0c;非常疑惑&#xff0c;这里做个问题&#xff0c;希望能有大佬解惑。 1、首先在本地创建一个113449.txt的文件&#xff0c;然后右键txt文件选择压缩&…

【计算机毕业设计】240基于微信小程序的校园综合服务平台

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…