C++ 实现文件随机IO

| 分类 c/c++之文件操作  java之文件操作  | 标签 C  C++  文件IO  文件流  RandomAccessFile  Java 

对比一下在Java 与C++ 中的实现细节

Java 中使用RandomAccessFile 实现文件随机IO

package com.xum.e003.JavaFile;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;

import com.google.common.io.Files;

public class FileExample 
{
    private static final String FILE_NAME = "test.bin";
    
    public static void main(String[] args) throws IOException
    {
        File file = new File("./" + FILE_NAME);
        // 如果文件不存在,则创建文件
        if (!file.exists()) {
            Files.touch(file);
        }
        
        RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw");
        
        // 设置文件大小
        randomAccessFile.setLength(8);
        
        // 写入内容
        randomAccessFile.writeInt(10);
        System.out.println("写入整数:10");
        randomAccessFile.writeInt(20);
        System.out.println("再写入整数:20");
        
        // seek() 方法将文件指针偏移量,从这个文件开始测量,进行下一个读或写操作
        // 偏移量可以被设置为超出文件的末尾。设置偏移超出了文件的末尾不会改变文件长度
        // 文件长度,也只是由偏移已被设置为超出文件的末尾之后写入更改
        
        // 定位到第4个字节(从0开始)
        randomAccessFile.seek(4);
        
        // 读取内容,因为最开始分别写入10(0-3字节)、20(4-7字节),上面seek(4),再readInt,所以预期会读到20
        Integer i = randomAccessFile.readInt();
        System.out.println("读取到整数:" + i);
        
        // 关闭文件
        randomAccessFile.close();
    }
}

运行效果如下

在test.bin 中可以看到二进制内容如下,刚好是10(十六进制A)和20(十六进制14)

C++ 中使用fstream 实现文件随机IO

随机访问文件,即可以任意地向前或向后移动文件指针,具体使用的函数是seekp() 和seekg()。seekp() 即seek put,用于输出流;seekg() 即seek get,用于输入流

可以使用tellp() 和tellg() 函数返回文件指针的当前位置

比如一些典型的用法

  • seekg(100, ios::beg) 将文件指针移动到从文件开始第100 个字节处
  • seekg(-100, ios::end) 将文件指针移动到从文件末尾向后第100 个字节处
  • seekp(42, ios::cur) 将文件指针从当前位置向前移动42 个字节
  • seekp(-42, ios::cur) 将文件指针从当前位置向后移动42 个字节
  • seekp(100) 将文件指针移动到文件第100 个字节处

看一个具体的例子

#include <iostream>
#include <fstream>

using namespace std;

class Person 
{
    public:
        Person() {}
        Person(int age, char sex)
        {
            this->age = age;
            this->sex = sex;
        }

        int getAge() const
        {
            return this->age;
        }

        char getSex() const 
        {
            return this->sex;
        }

    private:
        int age;
        char sex;
};

int main()
{
    fstream fs;

    // 写方式打开文件
    fs.open("data.dat", ios::out | ios::binary);

    Person p1(10, 'm');
    Person p2(11, 'f');
    Person p3(12, 'm');

    fs.write(reinterpret_cast<char*>(&p1), sizeof(Person));
    fs.write(reinterpret_cast<char*>(&p2), sizeof(Person));
    fs.write(reinterpret_cast<char*>(&p3), sizeof(Person));

    fs.close();

    // 读方式打开文件
    fs.open("data.dat", ios::in | ios::binary);
    Person newP;

    // 文件随机寻址
    fs.seekg(2 * sizeof(Person));

    cout << "当前文件指针的位置是: " << fs.tellg() << endl;

    fs.read(reinterpret_cast<char*>(&newP), sizeof(Person));

    cout << "当前人的年龄是: " << newP.getAge() << "; 性别是: " << newP.getSex() << endl;

    cout << "当前文件指针的位置是: " << fs.tellg() << endl;

    fs.close();

    return 0;
}

编译运行效果如下




如果本篇文章对您有所帮助,您可以通过微信(左)或支付宝(右)对作者进行打赏!


上一篇     下一篇