蚊章汇 - 读写
type: channel
link: https://linuxcn.bwsl.wang/tag/%E8%AF%BB%E5%86%99/
items: 使用 Python 读写文件
items: 不同的编程语言是如何读写数据的
items: 用 Lua 操作文件中的数据
items: 用 Bash 读写文件
items: 学习如何用 C 语言来进行文件输入输出操作

使用 Python 读写文件
type: item
date: 2021-08-05T17:47:25+08:00
description: 每种编程语言处理文件数据的方式不尽相同，Python 是这么干的。有些数据是临时的，它们在应用程序运行时存储在内存中，然后丢弃。但是有些数据是持久的。它们存储在硬盘驱动器上供以后使用，而且它们通常是用户最关心的东西。对于程序员来说，编写代码读写文件是很常见的，但每种语言处理该任务的方式都不同。本文演示了如何使用 Python 处理文件数据。安装 Python在 Linux 上，你可能已经安装了 Python。如果没有，你可以通过发行版软件仓库安装它。例如，在 CentOS 或 RHEL 上：$ sudo dnf install python3 在 macOS 上，你可以使用 MacPorts 或 Homebrew 安装。在 Windows 上，你可以使用 Chocolatey 安装。一旦安装了 Python，打开你最喜欢的文本编辑器，准备好写代码吧。使用 Python 向文件中写入数据如果你需要向一个文件中写入数据，记住有三个步骤：打开写入关闭这与你在计算机上编码、编辑照片或执行其他操作时使用的步骤完全相同。首先，打开要编辑的文档，然后进行编辑，最后关闭文档。在 Python 中，过程是这样的：f = open('example.txt', 'w') f.write('hello world') f.close() 这个例子中，第一行以写模式打开了一个文件，然后用变量 f 表示，我使用了 f 是因为它在 Python 代码中很常见，使用其他任意有效变量名也能正常工作。在打开文件时，有不同的模式：w 代表写入r+ 代表可读可写a 表示追加第二行表示向文件中写入数据，本例写入的是纯文本，但你可以写入任意类型的数据。最后一行关闭了文件。使用 with 语法写入数据对于快速的文件交互，常用有一种简短的方法可以写入数据。它不会使文件保持打开状态，所以你不必记得调用 close() 函数。相反，它使用 with 语法：with open('example.txt', 'a') as f: f.write('hello open source') 使用 Python 读取数据如果你或你的用户需要通过应用程序需要向文件中写入一些数据，然后你需要使用它们，那么你就需要读取文件了。与写入类似，逻辑一样：打开读取关闭同样的，这个逻辑反映了你一开始使用计算机就已知的内容。阅读文档，你可以打开、阅读，然后关闭。在计算机术语中，“打开”文件意味着将其加载到内存中。实际上，一个文本文件内容肯定不止一行。例如，你需要读取一个配置文件、游戏存档或乐队下一首歌曲的歌词，正如你打开一本实体书时，你不可能立刻读完整本书，代码也只能解析已经加载到内存中的文件。因此，你可能需要遍历文件的内容。f = open('example.tmp', 'r') for line in f: print(line) f.close() 示例的第一行指明使用 读 模式打开一个文件，然后文件交由变量 f 表示，但就像你写数据一样，变量名是任意的。f 并没有什么特殊的，它只是单词 “file” 的最简表示，所以 Python 程序员会经常使用它。在第二行，我们使用了 line，另一个任意变量名，用来表示 f 的每一行。这告诉 Python 逐行迭代文件的内容，并将每一行的内容打印到输出中（在本例中为终端或 IDLE）。使用 with 语法读取数据就像写入一样，使用 with 语法是一种更简短的方法读取数据。即不需要调用 close() 方法，方便地快速交互。with open('example.txt', 'r') as f: for line in f: print(line) 文件和 Python使用 Python 有很多方法向文件写入数据，包括用 JSON、YAML、TOML 等不同的格式写入。还有一个非常好的内置方法用于创建和维护 SQLite 数据库，以及许多库来处理不同的文件格式，包括 图像、音频和视频等。via: https://opensource.com/article/21/7/read-write-files-python作者：Seth Kenlon 选题：lujun9972 译者：MjSeven 校对：turbokernel本文由 LCTT 原创编译，Linux中国 荣誉推出

不同的编程语言是如何读写数据的
type: item
date: 2021-07-20T14:54:11+08:00
description: 每种编程语言都有其独特的完成任务的方式，这也说明了为什么有这么多语言可供选择。在 Jim Hall 的《不同的编程语言如何完成相同的事情》文章中，他演示了 13 种不同的语言如何使用不同的语法来完成同一个任务。经验是，编程语言往往有很多相似之处。一旦你了解了一种编程语言，你就可以通过理解它的语法和结构来学习另一种。本着同样的精神，Jim 的文章比较了不同编程语言如何读写数据。无论数据来自配置文件还是用户创建的文件，在存储设备上处理数据都是程序员的常见任务。以这种方式涵盖所有编程语言是不切实际的，但最近的 Opensource.com 系列文章提供了对这些编程语言采用的不同方法的深入了解：CC++JavaGroovyLuaBashPython读写数据用计算机读写数据的过程和你在现实生活中读写数据的过程类似。要访问书中的数据，你首先要打开它，然后阅读单词或将生词写入书中，然后合上书。当程序需要从文件中读取数据时，你向程序传入一个文件位置，然后计算机将该数据读入内存中并解析它。同样，当程序需要将数据写入文件时，计算机会将新数据放入系统的内存写入缓冲区，然后将其同步到存储设备上的文件中。下面是这些操作的一些伪代码：在内存中加载文件。读取文件内容，或将数据写入文件。关闭文件。从文件中读取数据从 Opensource.com 系列文章的语言中，你可以看到读取文件的三种趋势。C在 C 语言中，打开文件可能涉及检索单个字符（直到 EOF 指示符，表示文件结束）或一个数据块，具体取决于你的需求和方法。根据你的目标，它可能感觉像一个主要是手工的过程，但这正是其他语言所模仿的。FILE *infile; int ch; infile = fopen(argv[1], "r"); do { ch = fgetc(infile); if (ch != EOF) { printf("%c", ch); } } while (ch != EOF); fclose(infile); 你还可以选择将文件的某些部分加载到系统缓冲区中，然后在缓冲区外工作。FILE *infile; char buffer[300]; infile = fopen(argv[1], "r"); while (!feof(infile)) { size_t buffer_length; buffer_length = fread(buffer, sizeof(char), 300, infile); } printf("%s", buffer); fclose(infile); C++C++ 简化了一些步骤，允许你将数据解析为字符串。std::string sFilename = "example.txt"; std::ifstream fileSource(sFilename); std::string buffer; while (fileSource >> buffer) { std::cout << buffer << std::endl; } JavaJava 和 Groovy 类似于 C++。它们使用名为 Scanner 的类来设置数据流或对象，这样就会包含你选择的文件内容。你可以通过标记（字节、行、整数等）扫描文件。File myFile = new File("example.txt"); Scanner myScanner = new Scanner(myFile); while (myScanner.hasNextLine()) { String line = myScanner.nextLine(); System.out.println(line); } myScanner.close(); Groovydef myFile = new File('example.txt') def myScanner = new Scanner(myFile) while (myScanner.hasNextLine()) { def line = myScanner.nextLine() println(line) } myScanner.close() LuaLua 和 Python 进一步抽象了整个过程。你不必有意识地创建数据流，你只需给一个变量赋值为 open 函数的返回值，然后解析该变量的内容。这种方式快速，最简且容易。myFile = io.open('example.txt', 'r') lines = myFile:read("*all") print(lines) myFile:close() Pythonf = open('example.tmp', 'r') for line in f: print(line) f.close() 向文件中写入数据就写…

用 Lua 操作文件中的数据
type: item
date: 2021-04-05T18:25:03+08:00
description: 了解 Lua 如何处理数据的读写。有些数据是临时的，存储在 RAM 中，只有在应用运行时才有意义。但有些数据是要持久的，存储在硬盘上供以后使用。当你编程时，无论是简单的脚本还是复杂的工具套件，通常都需要读取和写入文件。有时文件可能包含配置选项，而另一些时候这个文件是你的用户用你的应用创建的数据。每种语言都会以不同的方式处理这项任务，本文将演示如何使用 Lua 处理文件数据。安装 Lua如果你使用的是 Linux，你可以从你的发行版软件库中安装 Lua。在 macOS 上，你可以从 MacPorts 或 Homebrew 安装 Lua。在 Windows 上，你可以从 Chocolatey 安装 Lua。安装 Lua 后，打开你最喜欢的文本编辑器并准备开始。用 Lua 读取文件Lua 使用 io 库进行数据输入和输出。下面的例子创建了一个名为 ingest 的函数来从文件中读取数据，然后用 :read 函数进行解析。在 Lua 中打开一个文件时，有几种模式可以启用。因为我只需要从这个文件中读取数据，所以我使用 r（代表“读”）模式：function ingest(file) local f = io.open(file, "r") local lines = f:read("*all") f:close() return(lines) end myfile=ingest("example.txt") print(myfile) 在这段代码中，注意到变量 myfile 是为了触发 ingest 函数而创建的，因此，它接收该函数返回的任何内容。ingest 函数返回文件的行数（从一个称为 lines 的变量中0。当最后一步打印 myfile 变量的内容时，文件的行数就会出现在终端中。如果文件 example.txt 中包含了配置选项，那么我会写一些额外的代码来解析这些数据，可能会使用另一个 Lua 库，这取决于配置是以 INI 文件还是 YAML 文件或其他格式存储。如果数据是 SVG 图形，我会写额外的代码来解析 XML，可能会使用 Lua 的 SVG 库。换句话说，你的代码读取的数据一旦加载到内存中，就可以进行操作，但是它们都需要加载 io 库。用 Lua 将数据写入文件无论你是要存储用户用你的应用创建的数据，还是仅仅是关于用户在应用中做了什么的元数据（例如，游戏保存或最近播放的歌曲），都有很多很好的理由来存储数据供以后使用。在 Lua 中，这是通过 io 库实现的，打开一个文件，将数据写入其中，然后关闭文件：function exgest(file) local f = io.open(file, "a") io.output(f) io.write("hello world\n") io.close(f) end exgest("example.txt") 为了从文件中读取数据，我以 r 模式打开文件，但这次我使用 a （用于”追加“）将数据写到文件的末尾。因为我是将纯文本写入文件，所以我添加了自己的换行符（/n）。通常情况下，你并不是将原始文本写入文件，你可能会使用一个额外的库来代替写入一个特定的格式。例如，你可能会使用 INI 或 YAML 库来帮助编写配置文件，使用 XML 库来编写 XML，等等。文件模式在 Lua 中打开文件时，有一些保护措施和参数来定义如何处理文件。默认值是 r，允许你只读数据：r 只读w 如果文件不存在，覆盖或创建一个新文件。r+ 读取和覆盖。a 追加数据到文件中，或在文件不存在的情况下创建一个新文件。a+ 读取数据，将数据追加到文件中，或文件不存在的话，创建一个新文件。还有一些其他的(例如，b 代表二进制格式)，但这些是最常见的。关于完整的文档，请参考 Lua.org/manual 上的优秀 Lua 文档。Lua 和文件和其他编程语言一样，Lua 有大量的库支持来访问文件系统来读写数据。因为 Lua 有一个一致且简单语法，所以很容易对任何格式的文件数据进行复杂的处理。试着在你的下一个软件项目中使用 Lua，或者作为 C 或 C++ 项目的 API。via: https://opensource.com/article/21/3/lua-files作者：Seth Kenlon 选题：lujun9972 译者：geekpi 校对：wxy本文由 LCTT 原创编译，Linux中国 荣誉推出

用 Bash 读写文件
type: item
date: 2021-04-02T06:37:26+08:00
description: 学习 Bash 读取和写入数据的不同方式，以及何时使用每种方法。当你使用 Bash 编写脚本时，有时你需要从一个文件中读取数据或向一个文件写入数据。有时文件可能包含配置选项，而另一些时候这个文件是你的用户用你的应用创建的数据。每种语言处理这个任务的方式都有些不同，本文将演示如何使用 Bash 和其他 POSIX shell 处理数据文件。安装 Bash如果你在使用 Linux，你可能已经有了 Bash。如果没有，你可以在你的软件仓库里找到它。在 macOS 上，你可以使用默认终端，Bash 或 Zsh，这取决于你运行的 macOS 版本。在 Windows 上，有几种方法可以体验 Bash，包括微软官方支持的 Windows Subsystem for Linux（WSL）。安装 Bash 后，打开你最喜欢的文本编辑器并准备开始。使用 Bash 读取文件除了是 shell 之外，Bash 还是一种脚本语言。有几种方法可以从 Bash 中读取数据。你可以创建一种数据流并解析输出, 或者你可以将数据加载到内存中。这两种方法都是有效的获取信息的方法，但每种方法都有相当具体的用例。在 Bash 中援引文件当你在 Bash 中 “ 援引 source ” 一个文件时，你会让 Bash 读取文件的内容，期望它包含有效的数据，Bash 可以将这些数据放入它建立的数据模型中。你不会想要从旧文件中援引数据，但你可以使用这种方法来读取配置文件和函数。（LCTT 译注：在 Bash 中，可以通过 source 或 . 命令来将一个文件读入，这个行为称为 “sourcing”，英文原意为“一次性（试）采购”、“寻找供应商”、“获得”等，考虑到 Bash 的语境和发音，我建议可以翻译为“援引”，或有不当，供大家讨论参考 —— wxy）例如，创建一个名为 example.sh 的文件，并输入以下内容：#!/bin/sh greet opensource.com echo "The meaning of life is $var" 运行这段代码，看见失败了：$ bash ./example.sh ./example.sh: line 3: greet: command not found The meaning of life is Bash 没有一个叫 greet 的命令，所以无法执行那一行，也没有一个叫 var 的变量记录，所以文件没有意义。为了解决这个问题，建立一个名为 include.sh 的文件：greet() { echo "Hello ${1}" } var=42 修改你的 example.sh 脚本，加入一个 source 命令：#!/bin/sh source include.sh greet opensource.com echo "The meaning of life is $var" 运行脚本，可以看到工作了：$ bash ./example.sh Hello opensource.com The meaning of life is 42 greet 命令被带入你的 shell 环境，因为它被定义在 include.sh 文件中，它甚至可以识别参数（本例中的 opensource.com）。变量 var 也被设置和导入。在 Bash 中解析文件另一种让数据“进入” Bash 的方法是将其解析为数据流。有很多方法可以做到这一点. 你可以使用 grep 或 cat 或任何可以获取数据并管道输出到标准输出的命令。另外，你可以使用 Bash 内置的东西：重定向。重定向本身并不是很有用，所以在这个例子中，我也使用内置的 echo 命令来打印重定向的结果：#!/bin/sh echo $( < include.sh ) 将其保存为 stream.sh 并运行它来查看结果：$ bash ./stream.sh greet() { echo "Hello ${1}" } var=42 $ 对于 include.sh 文件中的每一行，Bash 都会将该行打印（或 echo）到你的终端。先用管道把它传送到一个合适的解析器是用 Bash 读取数据的常用方法。例如, 假设 include.sh 是一个配置文件, 它的键和值对用一个等号（=）分开. 你可以用 awk 甚至 cut 来获取值：#!/bin/sh myVar=`grep var include.sh | cut -d'=' -f2` echo $myVar 试着运行这个脚本：$ bash ./stream.sh 42 用 Bash 将数据写入文件无论你是要存储用户用你的应用创建的数据，还是仅仅是关于用户在应用中做了什么的元数据（例如，游戏保存或最近播放的歌曲），都有很多很好的理由来存储数据供…

学习如何用 C 语言来进行文件输入输出操作
type: item
date: 2021-03-31T06:28:47+08:00
description: 理解 I/O 有助于提升你的效率。如果你打算学习 C 语言的输入、输出，可以从 stdio.h 包含文件开始。正如你从其名字中猜到的，该文件定义了所有的标准（“std”）的输入和输出（“io”）函数。大多数人学习的第一个 stdio.h 的函数是打印格式化输出的 printf 函数。或者是用来打印一个字符串的 puts 函数。这些函数非常有用，可以将信息打印给用户，但是如果你想做更多的事情，则需要了解其他函数。你可以通过编写一个常见 Linux 命令的副本来了解其中一些功能和方法。cp 命令主要用于复制文件。如果你查看 cp 的帮助手册，可以看到 cp 命令支持非常多的参数和选项。但最简单的功能，就是复制文件：cp infile outfile 你只需使用一些读写文件的基本函数，就可以用 C 语言来自己实现 cp 命令。一次读写一个字符你可以使用 fgetc 和 fputc 函数轻松地进行输入输出。这些函数一次只读写一个字符。该用法被定义在 stdio.h，并且这也很浅显易懂：fgetc 是从文件中读取一个字符，fputc 是将一个字符保存到文件中。int fgetc(FILE *stream); int fputc(int c, FILE *stream); 编写 cp 命令需要访问文件。在 C 语言中，你使用 fopen 函数打开一个文件，该函数需要两个参数：文件名和打开文件的模式。模式通常是从文件读取（r）或向文件写入（w）。打开文件的方式也有其他选项，但是对于本教程而言，仅关注于读写操作。因此，将一个文件复制到另一个文件就变成了打开源文件和目标文件，接着，不断从第一个文件读取字符，然后将该字符写入第二个文件。fgetc 函数返回从输入文件中读取的单个字符，或者当文件完成后返回文件结束标记（EOF）。一旦读取到 EOF，你就完成了复制操作，就可以关闭两个文件。该代码如下所示： do { ch = fgetc(infile); if (ch != EOF) { fputc(ch, outfile); } } while (ch != EOF); 你可以使用此循环编写自己的 cp 程序，以使用 fgetc 和 fputc 函数一次读写一个字符。cp.c 源代码如下所示：#include <stdio.h> int main(int argc, char **argv) { FILE *infile; FILE *outfile; int ch; /* parse the command line */ /* usage: cp infile outfile */ if (argc != 3) { fprintf(stderr, "Incorrect usage\n"); fprintf(stderr, "Usage: cp infile outfile\n"); return 1; } /* open the input file */ infile = fopen(argv[1], "r"); if (infile == NULL) { fprintf(stderr, "Cannot open file for reading: %s\n", argv[1]); return 2; } /* open the output file */ outfile = fopen(argv[2], "w"); if (outfile == NULL) { fprintf(stderr, "Cannot open file for writing: %s\n", argv[2]); fclose(infile); return 3; } /* copy one file to the other */ /* use fgetc and fputc */ do { ch = fgetc(infile); if (ch != EOF) { fputc(ch, outfile); } } while (ch != EOF); /* done */ fclose(infile); fclose(outfile); return 0; } 你可以使用 gcc 来将 cp.c 文件编译成一个可执行文件：$ gcc -Wall -o cp cp.c -o cp 选项告诉编译器将编译后的程序保存到 cp 文件中。-Wall 选项告诉编译器提示所有可能的警告，如果你没有看到任何警告，则表示一切正常。读写数据块通过每次读写一个字符来实现自己的 cp 命令可以完成这项工作，但这并不是很快。在复制“日常”文件（例如文档和文本文件）时，你可能不会注意到，但是在复制大型文件或通过网络复制文件时，你才会注意到差异。每次处理一个字符需要大量的开销。实现此 cp 命令…