【问题标题】:Understanding `read, write` system calls in Unix理解 Unix 中的“读、写”系统调用
【发布时间】:2011-02-21 20:19:31
【问题描述】:

我的系统编程项目让我们实现了一个压缩/解压缩程序,通过删除零顶部位并将输出写入单独的文件来处理 ASCII 文本文件,具体取决于压缩或解压缩例程是否正常工作。为此,教授要求我们使用二进制文件和Unix系统调用,包括open, close, read, write等。

根据我对读写的理解,它通过定义的字节块读取二进制数据。但是,由于这个数据是二进制的,我不知道如何解析它。

这是我的代码的精简版,减去错误检查:

void compress(char readFile[]){

  char buffer[BUFFER] //buffer size set to 4096, but tunable to system preference
  int openReadFile;
  openReadFile= open(readFile, O_RDONLY);
}

如果我使用read将数据读入buffer,缓冲区中的数据是二进制还是字符格式?我没有遇到任何关于这个细节的东西,它与我如何解析内容非常相关。

【问题讨论】:

  • char 是一个字节。 “二进制或字符格式”是什么意思?
  • 他大概是在“混合”fopen的“文本模式”和“二进制模式”。 open,作为一个原始人,没有“文本模式”(如果我没记错的话),所以它总是处于“二进制模式”
  • @xanatos: ...这对我使用的任何 *nix 都没有任何影响
  • @matti 我在 fopen 的随机手册上看到:“在许多环境中,例如大多数基于 UNIX 的系统,将文件作为文本文件或二进制文件打开没有区别;两者以完全相同的方式处理,但建议进行区分以获得更好的便携性。”。尽管如此,许多并不是全部,他的问题是一个明智的问题(如果这是一个问题)
  • C 中的byte 没有单独的类型。将您读取的每个字符视为一个字节。

标签: c unix system-calls


【解决方案1】:

read() 将在没有任何解释的情况下读取字节(因此是“二进制”模式)。

作为二进制文件,你想访问单个字节,你应该使用 unsigned char 的缓冲区 unsigned char buffer[BUFFER]。您可以将 char/unsigned char 视为字节,它们在 linux 上为 8 位。

现在,由于您处理的是 8 位 ascii 压缩到 7 位,因此您必须再次将这 7 位转换为 8 位,这样您才能理解数据。

为了解释所做的事情 - 考虑文本 Hey 。这是 3 个字节。每个字节有 8 位,在 ascii 中就是位模式:

01001000 01100101 01111001

现在,从中删除最高有效位,将剩余位向左移动一位。

X1001000 X1100101 X1111001

在上面,X 是要删除的位。删除这些,然后移动其他的,你最终会得到这种模式的字节:

10010001 10010111 11001000

最右边的 3 位只是用 0 填充。到目前为止,虽然没有节省空间。还有3个字节。 对于一个 8 字节的字符串,我们节省了 1 个字节,因为它会压缩到 7 个字节。

现在你必须对你读回的字节做相反的事情

【讨论】:

    【解决方案2】:

    我将引用http://www.kernel.org/doc/man-pages/online/pages/man3/fopen.3.html 中的fopen 函数的手册(即基于open 函数/原语)

    模式字符串还可以包括 字母“b”作为最后一个字符 或作为之间的字符 任何两个字符中的字符 上述字符串。这是 严格与 C89 兼容 并且没有效果; 'b' 被忽略 在所有符合 POSIX 的系统上, 包括Linux

    所以即使是高级函数也会忽略模式:-)

    【讨论】:

      【解决方案3】:

      它将读取文件的二进制内容并将其加载到内存缓冲区指向的位置。当然,一个字节是 8 位,这就是为什么 char 是 8 位,所以,如果文件是一个普通的纯文本文档,你最终会得到一个可打印的字符串(注意它的结尾,read 返回数字字节数(ascii 编码的纯文本文件中的字符)读取)。

      编辑:如果您正在读取的文件不是文本文件,而是二进制表示的集合,您可以将缓冲区的类型设为文件的类型,即使它是结构。

      【讨论】:

        猜你喜欢
        • 2021-07-06
        • 1970-01-01
        • 2018-07-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-09-24
        • 1970-01-01
        相关资源
        最近更新 更多