c++ 文件操作方式

51 篇文章 2 订阅
23 篇文章 2 订阅
本文详细介绍了文件操作的三种常见方法:使用C标准库中的fopen等函数,C++的fstream、ofstream、ifstream流,以及Win32API下的文件操作函数如CreateFile、WriteFile。内容涵盖文件的打开、读写、关闭,以及文件指针的管理。通过对不同方法的比较,帮助开发者理解和掌握各种文件操作技巧。
摘要由CSDN通过智能技术生成

1.使用标准C运行库函数,包括fopen、fclose、fseek、

fwrite、fread、fprintf等.

需要

FILE *fopen(const char *filename, const char *mode);
  • ilename -- 这是 C 字符串,包含了要打开的文件名称。
  • mode -- 这是 C 字符串,包含了文件访问模式
  • "r"打开一个用于读取的文件。该文件必须存在。
    "w"创建一个用于写入的空文件。如果文件名称与已存在的文件相同,则会删除已有文件的内容,文件被视为一个新的空文件。
    "a"追加到一个文件。写操作向文件末尾追加数据。如果文件不存在,则创建文件。
    "r+"打开一个用于更新的文件,可读取也可写入。该文件必须存在。
    "w+"创建一个用于读写的空文件。
    "a+"打开一个用于读取和追加的文件。

#include <stdio.h>

void fLog()
{
    FILE  *fp;
    fopen_s(&fp, "file.txt", "w+");
    fprintf(fp, "%s %s %s %d", "We", "are", "in", 2021);
    fclose(fp);
}

2.使用fstream、ofstream、ifstream流

要通过一个流对象打开一个文件,我们使用它的成员函数open():void open (const char * filename, openmode mode);

这里filename 是一个字符串,代表要打开的文件名,mode 是以下标志符的一个组合: ios::in 为输入(读)而打开文件
ios::out 为输出(写)而打开文件
ios::ate 初始位置:文件尾
ios::app 所有输出附加在文件末尾
ios::trunc 如果文件已存在则先删除该文件
ios::binary 二进制方式

#include <fstream>

ofstream file;
file.open ("example.bin", ios::out | ios::app | ios::binary);

当文件读写操作完成之后,我们必须将文件关闭以使文件重新变为可访问的。关闭文件需要调用成员函数close(),它负责将缓存中的数据排放出来并关闭文件。它的格式很简单:void close ();

tellg() 和 tellp()
这两个成员函数不用传入参数,返回pos_type 类型的值(根据ANSI-C++ 标准) ,就是一个整数,代表当前get 流指针的位置 (用tellg) 或 put 流指针的位置(用tellp).

seekg() 和seekp()
这对函数分别用来改变流指针get 和put的位置。两个函数都被重载为两种不同的原型:
seekg ( pos_type position );
seekp ( pos_type position );
使用这个原型,流指针被改变为指向从文件开始计算的一个绝对位置。要求传入的参数类型与函数 tellg 和tellp 的返回值类型相同。
seekg ( off_type offset, seekdir direction );
seekp ( off_type offset, seekdir direction );
使用这个原型可以指定由参数direction决定的一个具体的指针开始计算的一个位移(offset)。它可以是: ios::beg 从流开始位置计算的位移
ios::cur 从流指针当前位置开始计算的位移
ios::end 从流末尾处开始计算的位移

使用重载的插入操作符<< 或者 >> ,或者是cout <<  或 cin >> 

如:

#include <iostream>
#include <fstream>
#include <cstdlib>
using namespace std;
int main ()
{
    char buffer[256];
    ifstream examplefile("example.txt");
    if (! examplefile.is_open())
    {
        cout << "Error opening file"; exit (1);
    }
    while (!examplefile.eof())
    {
        examplefile.getline(buffer,100);
        cout<<buffer<< endl;
    }
    return 0;
}

在二进制文件中,使用<< 和>>,以及函数(如getline)来操作符输入和输出数据,没有什么实际意义。文 件流包括两个为顺序读写数据特殊设计的成员函数:write 和 read。

它们的原型是:
write ( char * buffer, streamsize size );
read ( char * buffer, streamsize size );

如:

#include <iostream>
#include <fstream>
using namespace std;
int main ()
{
    const char * filename = "example.txt";
    char * buffer;
    long size;
    ifstream file(filename, ios::in|ios::binary|ios::ate);
    size = file.tellg();
    file.seekg(0, ios::beg);
    buffer = new char [size];
    file.read(buffer, size);
    file.close();
    cout <<"the complete file is in a buffer";
    delete[] buffer;
    return 0;
}

3.使用Win32下的文件和目录操作函数,如CreateFile,CloseHandle,SetFilePointer,ReadFile、WriteFile、CopyFile,DeleteFile,FindNextFile

Win32 下,打开和创建文件都由CreateFile完成,成功的话,得到一个Win32下的句柄,这不同于“C”的fopen返回的句柄。关闭文件使用Win32的CloseHandle。

HANDLE CreateFile(
                  LPCTSTR,lpFileName,                        //指向文件名的指针
                  DWORD dwDesiredAccess,                     //访问模式(读/写)
                  DWORD dwShareMode,                         //共享模式
                  LPSECURITY_ATTRIBUTES lpSecurityAttributes,//指向安全属性的指针
                  DWORD dwCreationDisposition,               //如何让创建
                  DWORD dwFlagAndAttributes,                 //文件属性
                  HANDLE hTemplateFile                       //用于复制文件句柄
                 );

lpFileName:要打开的文件名;

dwDesiredAccess:如果是GENERIC_READ表示允许对设备进行读访问;如果是GENERIC_WRITE表示允许对设备进行写访问(可以组合使用);如果是0,表示只允许获取与一个设备有关的信息;

dwShareMode:定义共享模式。如果是0表示不共享;是FILE_SHARE_READ和/或FILE_SHARE_WRITE表示允许对文件进行共享;

lpSecurityAttributes:指向一个SECURITY_ATTRIBUTES结构的指针,定义了文件的安全特性;

dwCreationDisposition:指定当文件存在或不存在时的操作。常见的操作有5种:

CREATE_NEW:创建文件,如果文件存在会出错;
CREATE_ALWAYS:创建文件,会修改前一个文件;
OPEN_EXISTING:文件已经存在;
OPEN_ALWAYS:如果不存在就创建;
TRUNCATE_EXISTING:将现有的文件缩短为零长度;
dwFlagAndAttributes:表示新创建文件的属性。文件的常见属性有5种:

FILE_ATTRIBUTE_ARCHIVE:标记为归档属性;
FILE_ATTRIBUTE_NORMAL:默认属性;
FILE_ATTRIBUTE_HIDDEN:隐藏文件或目录;
FILE_ATTRIBUTE_READONLY:文件为只读;
FILE_ATTRIBUTE_SYSTEM:文件为系统文件;
hTemplateFile:指向用于存储的文件句柄;如果不为0,则指定一个文件句柄,新的文件将从这个文件中复制扩展属性;
如:以只写的方式打开已存在的文件

HANDLE hFILE=CreateFile("1.txt",GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);

在成功调用CreateFile函数之后,返回所打开的或创建的文件句柄,可调用ReadFile或WriteFile函数来读写文件

BOOL WriteFile(
               HANDLE fFile,                  //文件句柄
               LPCVOID lpBuffer,              //数据缓存区指针
               DWORD nNumberOfBytesToWrite,   //所要写的字节数
               LPDWORD lpNumberOfBytesWritten,//用于保存实际写入字节数的存储区的指针
               LPOVERLAPPED lpOverlapped      //OVERLAPPED结构体指针
              )

BOOL ReadFile(
               HANDLE fFile,                  //文件句柄
               LPCVOID lpBuffer,              //数据缓存区指针
               DWORD nNumberOfBytesToRead,    //所要写的字节数
               LPDWORD lpNumberOfBytesRead,   //用于保存实际写入字节数的存储区的指针
               LPOVERLAPPED lpOverlapped      //OVERLAPPED结构体指针
              )

DWORD
WINAPI
SetFilePointer(
    _In_ HANDLE hFile,
    _In_ LONG lDistanceToMove,
    _Inout_opt_ PLONG lpDistanceToMoveHigh,
    _In_ DWORD dwMoveMethod
    );

例子:

#include <stdio.h>
#include <windows.h>
int main()
{
    HANDLE hFILE=CreateFile("1.txt",GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
    if(hFILE==INVALID_HANDLE_VALUE)
    {
        printf("CreateFile error\n");
        return 0;
    }
    if(SetFilePointer(hFILE,0,NULL,FILE_END)==-1)
    {
        printf("SetFilePointer error\n");
        return 0;
    }
    char buff[256]="hello";
    DWORD dwWrite;
    if(!WriteFile(hFILE,&buff,strlen(buff),&dwWrite,NULL))
    {
        printf("WriteFile error\n");
        return 0;
    }
    printf("write %d.\n",dwWrite);
    printf("done.\n");
    CloseHandle(hFILE);
    return 0;
}

4.如果是mfc,MFC用一些类来封装文件访问的Win32 API。以CFile为基础,从CFile派生出几个类,如CStdioFile,CMemFile,MFC内部使用的CMiororFile,等等.

构造一个CFile对象。

调用CFile::Open()函数创建、打开指定的文件。Open调用Win32函数::CreateFile打开文件,并把文件句柄保存到成员变量m_hFile中。

调用CFile::Read()和CFile::Write ()进行文件操作。

调用CFile::Close()关闭文件句柄。

文件指针的位置设置可以使用:

Seek( LONG lOff, UINT nFrom )   把文件指针移动到指定位置

lOff :是指针偏移字节数,若向后偏移则为正数,若向前偏移,则为负数。

nFrom :MSDN上有三种取值:

CFile::begin  从文件开头开始算起,lOff为正数;

CFile::current  当前位置开始算起;

CFile::end     从文件结尾开始算起,lOff为负数;

SeekToBegin( )      把文件指针移到文件开头

SeekToEnd( )          把文件指针移到文件末尾

GetPosition( )        返回当前文件指针的位置

file.open( LPCTSTR lpszFileName, UINT nOpenFlags, CFileException* pError = NULL );

//pszFileName是文件名,可包含文件路径,若只有文件名,则默认路径为工程路径,nOpenFlags是文件打开模式,pError是打开失败时用来接收失败信息,一般设置为NULL。

nOpenFlags的常用模式有

标志

含义

CFile::modeCreate

创建新文件,如果文件已存在,则将其长度变成0

CFile::modeNoTruncate

与modeCreate组合使用,如果文件已存在,则不会将其长度变成0

CFile::modeRead

以只读方式打开文件

CFile::modeReadWrite

以读写方式打开文件

CFile::modeWrite

以只写方式打开文件

CFile::modeNoInherit

组织该文件被子项继承

CFile::shareDenyNone

以共享模式打开文件,不会禁止其他进程对文件的读写

CFile::shareDenyRead

禁止其他进程对文件的读操作

CFile::shareDenyWrite

禁止其他进程对文件的写操作

CFile::shareExclusive

以独占模式打开文件,禁止其他进程对文件的读写

CFile::typeText

以文本方式打开文件

CFile::typeBinary

以二进制方式打开文件

写入文件:

CFile file;

file.Open("E:\\VC\\1.txt",CFile::modeCreate|CFile::modeWrite|CFile::modeNoTruncate,NULL);

file.Write("HelloWorld",strlen("HelloWorld"));  

file.close( );

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值