C\C++\MFC\QT文件操作
应该打开一个文件以使映射成功,换句话说就是映射必须打开一个文件,但在映射内存之后,该文件不需要保持打开状态。当缓存被排放出来(flush)时,它里面的所有数据或者被写入物理媒质中(如果是一个输出流的话),或者简单的被抹掉(如果是一个输入流的话)。纯文本文件(“.txt”):能够在 Windows 的“记事本”程序中打开,并且能看出是一段有意义的文字的文件。ios::app方式打开文件,即使修改文件
文章目录
文件
文件可分为文本文件、视频文件、音频文件、图像文件、可执行文件等多种类别(格式)。
纯文本文件(“.txt”):能够在 Windows 的“记事本”程序中打开,并且能看出是一段有意义的文字的文件。文件中的每个字节都是一个可见字符的 ASCII 码。
图像、视频、可执行文件等:一般被称作“二进制文件”。二进制文件如果用“记事本”程序打开,看到的是一片乱码。
打开方式:文本 vs 二进制
std::ifstream in("file.txt", std::ios::binary);
无论是否指定二进制方式打开文件,读写的最小单位都是字节。
UNIX/Linux 平台:用文本方式或二进制方式打开文件没有任何区别。以\n(ASCII 码为 0x0a)作为换行符号。
Windows平台:默认换行符为两个字符\r\n(\r的 ASCII 码是 0x0d)。
- Windows + 文本普通方式读取文件:系统会将文件中所有的
\r\n转换成一个字符\n=》系统丢弃前面的 0x0d 字节,只读入 0x0a)。而linux下会读入0D 0A两个字符。 - Windows + 文本普通方式写入文件:系统会将写入的
\n转换成\r\n存储(如果要写入的内容中有字节为 0x0a,则在写入该字节前,系统会自动先写入一个 0x0d)。
=》因此,如果用文本方式打开二进制文件进行读写,读写的内容就可能和文件的内容有出入。因此,用二进制方式打开文件总是最保险的(更贴近原样)。
- Windows + ios::binary方式写入:换行符存储为单字符。和Linux表现一致。
- Windows + ios::binary读取:如果文件中本来存在0D 0A两个字符,windows 和 linux下均会读入0D 0A两个字符。
C文件操作
FILE *fopen(const char *filename, const char *mode)
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
C++文件操作
fstream
3 个文件流类:
- ofstream:写文件
- ifstream:读文件
- fstream:读写文件

FILE *_fsopen(
const char *filename,
const char *mode,
int shflag
);
FILE *_wfsopen(
const wchar_t *filename,
const wchar_t *mode,
int shflag
);
文件打开模式:mode
ofstream
| 模式 | 备注 |
|---|---|
| ios::app | 如果没有文件,那么生成空文件;如果有文件,那么在文件尾追加。 |
| ios::app | ios::in | 不管有没有文件,都返回失败。 |
| ios::ate | 如果没有文件,那么生成空文件;如果有文件,那么清空该文件。 |
| ios::ate | ios::in | 如果没有文件,那么打开失败;如果有文件,那么定位到文件尾,并可以写文件,但是不能读文件。 |
ios::app方式打开文件,即使修改文件指针,也只能输出到文件尾,和文件指针无关。
ios::ate可以配合指针修改文件中的部分内容。
ifstream
| 模式 | 备注 |
|---|---|
| ios::app (ios::app | ios::in) | 不管有没有文件,打开都是失败。 |
| ios::ate | 如果没有文件,打开失败。如果有文件,打开成功,将清空原文件? |
| ios::ate | ios::in | 如果没有文件,打开失败。如果有文件,打开成功,并定位到文件尾,但是不能写文件。 |
fstream
默认是ios::in
| 模式 | 备注 |
|---|---|
| ios::app | 如果没有文件,返回失败。 |
| ios::ate | 如果没有文件,返回失败。 |
| ios::app | ios::out | 如果没有文件则创建文件,如果有文件,则在文件尾追加。 |
| ios::ate | ios::out | 如果没有文件则创建文件,如果有,则清空文件。 |
| ios::ate | ios::out | ios::in | 如果没有文件,则打开失败,有文件则定位到文件尾。 |

ofstream之ios::ate,ios::app,ios::in,ios::out
共享类型\保护模式:shflag
#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进程不能再对文件进行读写。
ofstream ofs;
ofs.open("./out.bin",ios::out| ios::app | ios::binary, _SH_DENYNO); //允许第三方应用同时打开?
文件读写:文本模式
流运算符
>>:输入流运算符。以行为单位写入文件。
<<:输出流运算符。以空格、Tab、回车结束。
ifstream srcFile("in.txt", ios::in); //以文本模式打开in.txt备读
ofstream destFile("out.txt", ios::out); //以文本模式打开out.txt备写
if (!srcFile || !destFile) { //打开失败
return;
}
while (srcFile >> x) { // 像用cin那样用ifstream对象
destFile << x << " "; // 像cout那样使用 ofstream 对象
}
destFile.close();
srcFile.close();
getline()
以行为单位读入内存,能一次读入一行。碰到换行标志、EOF结束。
OpenFile.getline(str,20);
get( ) & put()
一次读写一个字符。遇空白字符不停止读取。
char ch='1';
ofstream OpenFile("file.txt");
OpenFile.put(ch);
OpenFile.close();
char ch;
ifstream OpenFile("file.txt");
OpenFile.get(ch);
cout<<ch;
OpenFile.close();
文件读写:二进制模式
ofstream::write() & ifstream::read()
打开文件:
const char *chText ="xxxxxx";
fstream fs("test.txt", ios::out | ios::binary);
fstream fs; //创建一个 fstream 类对象
fs.open("test.txt", ios::out); //将 test.txt 文件和 fs 文件流关联
文件是否打开成功:
if (!fs.is_open())
{
fs.close();
}
写入:
fs.write(chText, 30); //向test.txt文件中写入 url 字符串
关闭:
fs.close();
写入文件内容到结构体
Student st;
fstream fs;
fs("test.txt",ios::out | ios::binary);//binary二进制输出
if(fs)
{
fs.write(reinterpret_cast<char*>(&st), sizeof(st));
//fs.write((char*)(&st),sizeof(st));
fs.close();
}
Writing binary with ofstream.
利用fstream写入结构体(二进制写入)
C++ fstream读取结构体出错问题解决
文件是否打开成功:is_open()
if (!fs.is_open())
{
fs.close();
}
缓存和同步
当缓存被排放出来(flush)时,它里面的所有数据或者被写入物理媒质中(如果是一个输出流的话),或者简单的被抹掉(如果是一个输入流的话)。这个过程称为同步(synchronization),它会在以下任一情况下发生:
- 当文件被关闭时。
- 当缓存buffer满时:缓存Buffers 有一定的空间限制。当缓存满时,它会被自动同步。
- 控制符明确指明:当遇到流中某些特定的控制符时,同步会发生。这些控制符包括:
flush()和endl。 - 明确调用函数
sync():调用成员函数sync() (无参数)可以引发立即同步。这个函数返回一个int 值,等于-1 表示流没有联系的缓存或操作失败。
获取文件大小
ifstream:seekg + tellg
ifstream fsRead;
fsRead.open(srcFilePath.c_str(), ios::in|ios::binary);
if (!fsRead) {
return;
}
fsRead.seekg(0, fsRead.end); // 搜索到文件末尾
size_t srcSize = fsRead.tellg(); // 文件大小
if (!srcSize) {
fsRead.close();
}
fsRead.seekg(0, 0); // 还原到文件开头
ofstream:seekp + tellp
ofstream fsWrite;
fsWrite.open(destFilePath.c_str(), ios::out|ios::binary);
if (!fsWrite) {
fsRead.close();
return;
}
fsWrite.seekp(0, fsWrite.end); // 搜索到文件末尾
size_t dstFileSize = fsWrite.tellp(); // 文件大小
seekg 和 seekp 的参数通常是一个长整型。第二个参数可以用于指定查找方向:ios::beg:默认,从流的开头开始定位。ios::cur:从流的当前位置开始定位。ios::end:从流的末尾开始定位。
fileObject.seekg( n ); // 定位到 fileObject 的第 n 个字节(默认ios::beg)
fileObject.seekg( n, ios::cur ); // 把文件的读指针从 fileObject 当前位置向后移 n 个字节
fileObject.seekg( n, ios::end ); // 把文件的读指针从 fileObject 末尾往回移 n 个字节
fileObject.seekg( 0, ios::end ); // 定位到 fileObject 的末尾
fstream 获取文件大小_c++获取文件大小
使用C++文件流(fstream),如何确定文件的大小?
获取读取的字节数
ifstream ifs("a.txt");
char buf[1024];
ifs.read(buf, 1024);
size_t extracted = ifs.gcount();
std::ifstream::readsome和std::ifstream::read的区别
std::locale::global() 支持中文路径
当传递NULL作为参数时,会调用local对象的一个显示默认构造函数。
新构造出的对象包含当前系统的默认locale。
随后会比较当前本应用程序正在使用的locale是否和这个local对象所代表的locale一致,不一致的话则将这个local对象所携带的locale设置为新的locale(系统默认locale),并返回之前正在使用的locale。
ofstream ofs; //打开文件用于写,若文件不存在就创建它
locale loc = locale::global(locale("")); //要打开的文件路径含中文,设置全局locale为本地环境
ofs.open("./out.bin",ios::out| ios::app | ios::binary, _SH_DENYNO); //输出到文件,追加、二进制
locale::global(loc); //恢复全局locale
//写入文件
if (!ofs.is_open())
return;
char* buffer = "fdsfdsfdsfdsfdsfds\n";
ofs.write(buffer, sizeof(char)*17);
ofs.flush();
Sleep(1000);
ofs.close();
文件操作std::locale::global(std::locale(“”))的作用
状态标志符
bad()
如果在读写过程中出错,返回 true 。例如:当我们要对一个不是打开为写状态的文件进行写入时,或者我们要写入的设备没有剩余空间的时候。
fail()
除了与bad() 同样的情况下会返回 true 以外,加上格式错误时也返回true ,例如当想要读入一个整数,而获得了一个字母的时候。
ofstream OpenFile("file.txt");
if (OpenFile.fail())
{
cout<<"打开文件错误!"<<endl;
exit(0);
}
eof()
如果读文件到达文件末尾,返回true。
while (!OpenFile.eof())
{
//文件结束时的代码
}
good()
这是最通用的:如果调用以上任何一个函数返回true 的话,此函数返回 false 。
C++文件操作
ofstream文件输出流把二进制数据写入文件
C/C++读写文件的几种方法fstream fopen、fwrite()、fread()操作
删除文件
int remove(const char * filename);
_finddata_t存储文件信息
头文件#include <io.h>
struct _finddata_t
{
unsigned attrib;
time_t time_create;
time_t time_access;
time_t time_write;
_fsize_t size;
char name[_MAX_FNAME];
};
QT文件操作
基本读写操作
QFile file(fileName); // fileName文件的路径
if(file.open(QIODevice::ReadOnly | QIODevice::Text)) // 以读写的方式打开文件
return ;
while (!file.atEnd()) {
QByteArray line = file.readLine();
}
流操作QTextStream\QDataStream
QFile file("in.txt");
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
return;
QTextStream in(&file);
while (!in.atEnd()) {
QString line = in.readLine();
}
文件内存映射
uchar *QFileDevice::map(qint64 offset, qint64 size, QFileDevice::MemoryMapFlags flags = NoOptions)
从偏移量开始将文件的大小字节映射到内存(虚拟内存)中。应该打开一个文件以使映射成功,换句话说就是映射必须打开一个文件,但在映射内存之后,该文件不需要保持打开状态。当QFile被销毁或用这个对象打开一个新文件时,任何未被映射的映射都将被自动取消映射。
在处理数据量较大的文件时,往往需要使用文件映射技术,即虚拟内存。 通过文件映射之后,就可以像操作内存一样去直接操作文件。而不需要再调用文件读写方法了。
给磁盘上的文件分配地址,类似内存的地址一样,对虚拟出来的内存的操作就是对文件的操作了。
文件对话框QFileDialog
QString strFileName = QFileDialog::getOpenFileName(this, tr("Open Image"), "/home/", tr("Image Files (*.png *.jpg *.bmp)"));
更多推荐



所有评论(0)