在Windows平台对文件进行存取操作可选的方案有很多,如果采用纯C,则需要用到File*等,当然也可以直接调用Windows API来做;如果采用C++,首先想到的就是文件流fstream。虽然在COM层面上,我们还可以使用IStream来实现文件的读写,其效率也非常高。不过本文仅对C++流操作做简单的探讨,相比于Windows API或IStream,C++的流操作通用性更好一些,因为你能轻松将代码移植到其它平台上。

fstream有两个派生类,即ifstream和ofstream,分别对应输入文件流、输出文件流。在使用它们之前,必须将它们的头文件包含到你的cpp文件中。

创建一个文件流的方法很简单:

ifstream fin;
fin.open("C:\filename.txt");

这样就创建了一个输入文件流fin,它对应的文件是C盘根目录下的filename.txt。实际上,open方法还包含一个参数mode,用以指定其打开方式。

ios::in 以读取方式打开文件
ios::out 以写入方式打开文件
ios::ate 存取指针在文件末尾
ios::app 写入时采用追加方式
ios::trunc 写入时抹去旧数据
ios::binary 以二进制方式存取

上面的代码并未指定任何打开方式,则采用默认参数:输入文件流即ios::in,输出文件流即ios::out。一般在需要组合特殊的mode才显式指定,比如:

ios::in | ios::binary; //以二进制方式读取文件

除此之外,还可以在构造时指定相应的文件路径和名称,让创建过程一步到位。上述代码可改写为:

ifstream fin("C:\filename.txt");

与open方法相反的是close方法,它的作用与open正好相反。open是将文件流对象与外设中的文件关联起来,close则是解除二者的关联。但是需要注意的是,close还起到清空缓存的作用。最好让open方法与close方法成对出现。

创建并打开一个文件流后,就能像操作标准I/O那样使用流插入操作符(<<)与流提取操作符(>>)。对于输入文件流来说,可以调用getline函数从文件流中读取一整行数据,这样就可以读入含有空格的字符串。

下面是一个例子,该例的作用是读取一个STLA格式的文件。STL是一种常用快速成像文件格式,其格式非常简单,特别是ASCII版本(即STLA)。代码如下所示:

stdafx.h

// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
// #pragma once #include "targetver.h" #include <stdio.h>
#include <tchar.h>
//added
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <vector>
using namespace std; // TODO: reference additional headers your program requires here

readstla.cpp

// readstla.cpp : Defines the entry point for the console application.
// #include "stdafx.h" struct facet {
float normal[3];
float vertex[3][3];
}; int _tmain(int argc, _TCHAR* argv[])
{
if (argc < 2) {
printf("specify an input file!\n");
return 1;
}
ifstream in(argv[1]);
if (!in.is_open()) {
printf("fail to open file!\n");
return 1;
}
//var
vector<facet> solid;
string line;
string word;
//check format
getline(in, line);
if (line.find("solid") != 0) {
printf("wrong file format!\n");
in.close();
return 1;
}
while (getline(in, line)) {
if (line.find("facet normal") != string::npos) {
facet f;
//read normal
stringstream ns(line);
ns >> word; //eat "facet"
ns >> word; //eat "normal"
ns >> f.normal[0] >> f.normal[1] >> f.normal[2];
//read vertices
getline(in, line); //"outer loop"
for (int i = 0; i < 3; i++) {
getline(in, line);
stringstream vs(line);
vs >> word; //eat "vertex"
vs >> f.vertex[i][0] >> f.vertex[i][1] >> f.vertex[i][2];
}
getline(in, line); //"endloop"
getline(in, line); //"endfacet"
solid.push_back(f);
}
}
in.close();
//output
int cnt = solid.size();
printf("read %d facet\n", cnt);
for (int i = 0; i < cnt; i++) {
facet& f = solid[i];
printf("\nfacet %d:\nnormal = (%f, %f, %f)\n", \
i+1, f.normal[0], f.normal[1], f.normal[2]);
for (int j = 0; j < 3; j++) {
printf("vertex[%d] = (%f, %f, %f)\n", \
j+1, f.vertex[j][0], f.vertex[j][1], f.vertex[j][2]);
}
}
return 0;
}

测试文件为:

cube_corner.stl

solid cube_corner
facet normal 0.0 -1.0 0.0
outer loop
vertex 0.0 0.0 0.0
vertex 1.0 0.0 0.0
vertex 0.0 0.0 1.0
endloop
endfacet
facet normal 0.0 0.0 -1.0
outer loop
vertex 0.0 0.0 0.0
vertex 0.0 1.0 0.0
vertex 1.0 0.0 0.0
endloop
endfacet
facet normal 0.0 0.0 -1.0
outer loop
vertex 0.0 0.0 0.0
vertex 0.0 0.0 1.0
vertex 0.0 1.0 0.0
endloop
endfacet
facet normal 0.577 0.577 0.577
outer loop
vertex 1.0 0.0 0.0
vertex 0.0 1.0 0.0
vertex 0.0 0.0 1.0
endloop
endfacet
endsolid

输入结果为:

read 4 facet

facet 1:
normal = (0.000000, -1.000000, 0.000000)
vertex[1] = (0.000000, 0.000000, 0.000000)
vertex[2] = (1.000000, 0.000000, 0.000000)
vertex[3] = (0.000000, 0.000000, 1.000000) facet 2:
normal = (0.000000, 0.000000, -1.000000)
vertex[1] = (0.000000, 0.000000, 0.000000)
vertex[2] = (0.000000, 1.000000, 0.000000)
vertex[3] = (1.000000, 0.000000, 0.000000) facet 3:
normal = (0.000000, 0.000000, -1.000000)
vertex[1] = (0.000000, 0.000000, 0.000000)
vertex[2] = (0.000000, 0.000000, 1.000000)
vertex[3] = (0.000000, 1.000000, 0.000000) facet 4:
normal = (0.577000, 0.577000, 0.577000)
vertex[1] = (1.000000, 0.000000, 0.000000)
vertex[2] = (0.000000, 1.000000, 0.000000)
vertex[3] = (0.000000, 0.000000, 1.000000)
Press any key to continue . . .


C++流操作之fstream的更多相关文章

  1. ndk学习之c++语言基础复习----C++容器、类型转换、异常与文件流操作

    继续来复习C++,比较枯燥,但是这是扎实掌握NDK开发的必经之路,不容小觑. 容器: 容器,就是用来存放东西的盒子. 常用的数据结构包括:数组array, 链表list, 树tree, 栈stack, ...

  2. Node学习笔记(一):stream流操作

    NodeJs中谈及较多的可能就是Stream模块了,先写一个简单的ajax回调 $.post("index.php",{data:'aaa',order:'ccc'},functi ...

  3. [WCF编程]10.操作:流操作

    一.流操作概述 在默认情况下,当客户端调用服务时,服务只有在接收到完整的消息后才会被调用,同样,客户端只有在包含了调用结果的返回消息被完整接受时,才会解除对它的阻塞. 对于数据量小的消息,这种交换模式 ...

  4. io流操作大全

    JAVA 中的IO流 一.流的概念        流(stream)的概念源于UNIX中管道(pipe)的概念.在UNIX中,管道是一条不间断的字节流,用来实现程序或进程间的通信,或读写外围设备.外部 ...

  5. Stream 流操作

     Stream 类 先看下面的图 Stream 是所有流的抽象基类(不能被实例化,需要使用他的派生类FileStream/MemoryStream/BufferedStream).流是字节序列的抽象概 ...

  6. delphi 基础之三 文件流操作

    文件流操作 Delphi操作流文件:什么是流?流,简单来说就是建立在面向对象基础上的一种抽象的处理数据的工具.在流中,定义了一些处理数据的基本操作,如读取数据,写入数据等,程序员是对流进行所有操作的, ...

  7. IOS文件操作的两种方式:NSFileManager操作和流操作

    1.常见的NSFileManager文件方法 -(NSData *)contentsAtPath:path //从一个文件读取数据 -(BOOL)createFileAtPath: path cont ...

  8. Java基础---IO(一)---IO流概述、字符流、字节流、流操作规律

    第一讲     IO概述 概述 1.IO流:即InputOutput的缩写. 2.特点: 1)IO流用来处理设备间的数据传输. 2)Java对数据的操作是通过流的方式. 3)Java用于操作流的对象都 ...

  9. JAVA之旅(二十七)——字节流的缓冲区,拷贝mp3,自定义字节流缓冲区,读取键盘录入,转换流InputStreamReader,写入转换流,流操作的规律

    JAVA之旅(二十七)--字节流的缓冲区,拷贝mp3,自定义字节流缓冲区,读取键盘录入,转换流InputStreamReader,写入转换流,流操作的规律 我们继续来聊聊I/O 一.字节流的缓冲区 这 ...

随机推荐

  1. Vue.js 学习示例

    本篇和大家分享的是学习Vuejs的总结和调用webapi的一个小示例:快到年底了争取和大家多分享点东西,希望能对各位有所帮助:本章内容希望大家喜欢,也希望各位多多扫码支持和推荐谢谢: » Vuejs ...

  2. ListView的小知识

    1.设置项目分割功能 android:divider="@android:color/blue" android:dividerHeight="10dp" &l ...

  3. python之列表、字典的使用

    一.概述:以后你在Linux里面写Python脚本的时候会经常用到Python列表.字典,因为你在以后写脚本的时候,大多数情况下都是对文件进行操作处理,使用字典和列表可以很好的操作文件,得出你想要的结 ...

  4. SQL Server 控制锁升级

    背景知识: 锁升级的路线图.行--> 页 --> 区(extent)-->区(表分区)--> 表: alter table 控制锁的升级行为: 1.table SQL Serv ...

  5. Nginx 配置指令的执行顺序(十)

    运行在 post-rewrite 阶段之后的是所谓的 preaccess 阶段.该阶段在 access 阶段之前执行,故名preaccess. 标准模块 ngx_limit_req 和 ngx_lim ...

  6. webview的一些问题

    一些小问题. Webview 里面的网页,如果有 input ,需要输入,但是点上去却没反应,输入法不出来.这种情况是因为 webview 没有获取焦点.需要在 java 里面给 webview 设置 ...

  7. Android-PullToRefresh下拉刷新库基本用法

    How:(使用) 转自:http://blog.csdn.net/hantangsongming/article/details/42490277 PullToRefresh是一套实现非常好的下拉刷新 ...

  8. GPS功能:百度路书自定义【轨迹回放】

    如题所述:百度的编辑界面很直观,修改后就可以运行,地址:http://developer.baidu.com/map/jsdemo.htm#c2_8: 因为同事研究了一下午结果都没搞出来,他copy百 ...

  9. 【hihocoder 1258 Osu! Master】

    2015北京区域赛现场赛签到题. 题面:http://media.hihocoder.com/contests/icpcbeijing2015/problems.pdf OJ链接:http://hih ...

  10. sql的基本查询语句

    --------------------------------------------基本常用查询-------------------------------------- 自己简单练习做了个表. ...