文件流(fstream, ifstream, ofstream)的打開關閉、流狀態


一、文件流

ofstream,由ostream派生而來,用於寫文件
ifstream,由istream派生而來, 用於讀文件
fstream,由iostream派生而來,用於讀寫文件


二、打開文件

說明了流對象之后,可使用函數open()打開文件。文件的打開即是在流與文件之間建立一個連接
函數原型

void open(const char * filename, int mode = ios::out,int prot = _SH_DENYNO);

參數
filename:文件的名稱,可以包含(絕對和相對)路徑
mode:文件打開模式
prot:保護模式


(一)、文件打開模式

打開方式 描述

ios::in 打開一個供讀取的文件(ifstream流的默認值)

ios::out 打開一個供寫入的文件(ofstream流的默認值) ios::app 在寫之前找到文件尾 ios::ate 打開文件后立即將文件定位在文件尾 ios::trunc 廢棄當前文件內容 ios::nocreate(已不再支持) 如果要打開的文件並不存在,那么以此參數調用open()函數將無法進行 ios::noreplace (已不再支持) 如果要打開的文件已存在,試圖用open()函數打開時將返回一個錯誤。 ios::binary 以二進制的形式打開一個文件,默認為文本文件


(二)、保護模式

#define _SH_DENYRW      0x10    /* deny read/write mode */拒絕對文件進行讀寫
#define _SH_DENYWR      0x20    /* deny write mode */拒絕寫入文件
#define _SH_DENYRD      0x30    /* deny read mode */拒絕文件的讀取權限
#define _SH_DENYNO      0x40    /* deny none mode */讀取和寫入許可
#define _SH_SECURE      0x80    /* secure mode */共享讀取,獨占寫入

注意:假設A進程以_SH_DENYRW 打開,那么是B進程不能再對文件進行讀寫。


(三)、文件打開模式的有效組合


上述所有的打開模式組合還可以添加ate模式。對這些模式添加ate模只會改變文件打開時的初始定位,在第一次讀或
寫之前,將文件定位於文件末尾處。


(四)、文件打開的幾點說明

1、文件打開也可以通過構造函數打開,例如:

ofstream fout(“out.txt“,ios::out);

2、文件的打開方式可以為上述的一個枚舉常量,也可以為多個枚舉常量構成的按位或表達式。
3、使用open成員函數打開一個文件時,若由字符指針參數所指定的文件不存在,則建立該文件。(out)
4、當打開方式中不含有ios::ate或ios::app選項時,則文件指針被自動移到文件的開始位置,即字節地址為0的位置。

5、從效果上看ofstream指定out模式等同於指定了out和trunc模式
6、默認情況下,fstream對象以in和out模式同時打開。
7、當文件同時以in和out打開時不會清空
8、如果只使用out模式,而不指定in模式,則文件會清空現有數據。
9、如果同時指定了out與app,不會清空
10、如果打開文件時指定了trunc模式,則無論是否同時指定了in模式,文件同樣會被清空


三、流狀態


對應於這個標志字各狀態位,ios類還提供了以下成員函數來檢測或設置流的狀態:
bool rdstate();             //返回流的當前狀態標志字 bool eof();                 //返回非0值表示到達文件尾 bool fail();               //返回非0值表示操作失敗 bool bad();                 //返回非0值表示出現錯誤 bool good();               //返回非0值表示流操作正常 bool clear(int flag=0); //將流的狀態設置為flag
為提高程序的可靠性,應在程序中檢測I/O流的操作是否正常。當檢測到流操作出現錯誤時,可以通過異常處理來解決問題。


四、文件的關閉

每個文件流類中都提供有一個關閉文件的成員函數close()
功能:當打開的文件操作結束后,就需要關閉它,使文件流與對應的物理文件斷開聯系,並能夠保證最后輸出到文件緩沖區中的內容,無論是否已滿,都將立即寫入到對應的物理文件中

函數原型:void close();

文件流對應的文件被關閉后,還可以利用該文件流調用open成員函數打開其他的文件,最好先clear 一下。

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
 
#include <cassert>
#include <iostream>
#include <fstream>

using namespace std;

int main(void)
{
    /******************************************************/
    //若不存在文件,會創建文件
    //ofstream fout;
    //fout.open("test.txt");
    ofstream fout("test.txt", ios::out | ios::app);

    //判斷流狀態
    //if (fout.is_open())
    //{
    //  cout<<"succ"<<endl;
    //}
    //else
    //  cout<<"failed"<<endl;

    //if (fout.good())
    //{
    //  cout<<"succ"<<endl;
    //}
    //else
    //  cout<<"failed"<<endl;

    //if (fout)
    //{
    //  cout<<"succ"<<endl;
    //}
    //else
    //  cout<<"failed"<<endl;

    //if (!fout)
    //{
    //  cout<<"failed"<<endl;
    //}
    //else
    //  cout<<"succ"<<endl;

    assert(fout);
    fout.close();

    /************************************************************/
    // 若文件不存在,不會創建文件
    ifstream fin("test2.txt");

    //  assert(fin); //文件不存在,斷言失敗

    fin.close();
    /**********************************************************/
    //ofstream fout1("test3.txt", ios::in | ios::out | ios::ate);
    //ofstream fout2("test3.txt", ios::in | ios::out | ios::ate);

    //ofstream fout1("test3.txt", ios::in | ios::out | ios::app);
    //ofstream fout2("test3.txt", ios::in | ios::out | ios::app);

    // app 和 ate 可以共存,以app為准
    ofstream fout1("test3.txt", ios::in | ios::out | ios::app | ios::ate);
    ofstream fout2("test3.txt", ios::in | ios::out | ios::app | ios::ate);

    assert(fout1);
    assert(fout2);

    fout1 << "X";
    fout2 << "Y"; //Y 輸出在 X 的后面

    fout1.close();
    fout2.close();
    /****************************************************************/

    // app 與 trunc 不能共存,流狀態為fail
    ofstream fout3("test.txt", ios::out | ios::app | ios::trunc);
    if (fout3.good())
    {
        cout << "good" << endl;
    }
    if (fout3.bad())
    {
        cout << "bad" << endl;
    }
    if (fout3.fail())
    {
        cout << "fail" << endl;
    }
    if (fout3.eof())
    {
        cout << "eof" << endl;
    }

    fout3.clear();
    fout3.open("test.txt"); // clear之后能夠重新open
    if (fout3)
    {
        cout << "open succ" << endl;
    }
    else
        cout << "open failed" << endl;

    fout3.close();

    return 0;
}

 

參考:

C++ primer 第四版
Effective C++ 3rd
C++編程規范


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM