C++ 中的文件输入 / 输出 (5)

原作: Ilia Yordanov,  loobian@cpp-home.com

 

二进制文件的处理

 

虽然有规则格式( formatted )的文本(到目前为止我所讨论的所有文件形式)非常有用,但有时候你需要用到无格式( unformatted )的文件——二进制文件。它们和你的可执行程序看起来一样,而与使用 << >> 操作符创建的文件则大不相同。 get() 函数与 put() 函数则赋予你读 / 写无规则格式文件的能力:要读取一个字节,你可以使用 get() 函数;要写入一个字节,则使用 put() 函数。你应当回想起 get() ——我曾经使用过它。你可能会疑惑为什么当时我们使用它时,输出到屏幕的文件内容看起来是文本格式的?嗯,我猜这是因为我此前使用了 << >> 操作符。

 

译注:作者的所谓“规则格式文本( formatted text )”即我们平时所说的文本格式,而与之相对的“无格式文件( unformatted files )”即以存储各类数据或可执行代码的非文本格式文件。通常后者需要读入内存,在二进制层次进行解析,而前者则可以直接由预定好的 << >> 操作符进行读入 / 写出(当然,对后者也可以通过恰当地重载 << >> 操作符实现同样的功能,但这已经不是本系列的讨论范围了)。

 

get() 函数与都各带一个参数:一个 char 型变量 (译注:指 get() 函数) 或一个字符 (译注:指 put() 函数,当然此字符也可以以 char 型变量提供)

假如你要读 / 写一整块的数据,那么你可以使用 read() write() 函数。它们的原型如下:

 

istream &read(char *buf, streamsize num);

ostream &write(const char *buf, streamsize num);

 

对于 read() 函数, buf 应当是一个字符数组,由文件读出的数据将被保存在这儿。对于 write() 函数, buf 是一个字符数组,它用以存放你要写入文件的数据。对于这两个函数, num 是一个数字,它指定你要从文件中读取 / 写入的字节数。

假如在读取数据时,在你读取“ num ”个字节之前就已经到达了文件的末尾,那么你可以通过调用 gcount() 函数来了解实际所读出的字节数。此函数会返回最后一次进行的对无格式文件的读入操作所实际读取的字节数。

在给出示例代码之前,我要补充的是,如果你要以二进制方式对文件进行读 / 写,那么你应当将 ios::binary 作为打开模式加入到文件打开的参数表中。

现在就让我向你展示示例代码,你会看到它是如何运作的。

 

示例 1 :使用 get( ) put( )

 

#include <fstream.h>

 

void main()

{

    fstream File("test_file.txt",ios::out | ios::in | ios::binary);

 

    char ch;

    ch='o';

 

    File.put(ch); // ch 的内容写入文件

 

    File.seekg(ios::beg); // 定位至文件首部

 

    File.get(ch); // 读出一个字符

 

    cout << ch << endl; // 将其显示在屏幕上

 

    File.close();

}

 

示例 2 :使用 read( ) write( )

 

#include <fstream.h>

#include <string.h>

 

void main()

{

    fstream File("test_file.txt",ios::out | ios::in | ios::binary);

 

    char arr[13];

    strcpy(arr,"Hello World!"); // Hello World! 存入数组

 

    File.write(arr,5); // 将前 5 个字符—— "Hello" 写入文件

 

    File.seekg(ios::beg); // 定位至文件首部

 

    static char read_array[10]; // 在此我将打算读出些数据

 

    File.read(read_array,3); // 读出前三个字符—— "Hel"

 

    cout << read_array << endl; // 将它们输出   

 

    File.close();

}