湖北工学院图书馆计算机室
7 Y, E _6 c! |2 \% o1 x [! |/ R R张明武
---- 在Windows中实现文件的操作主要有两种方法。一种是直接利用CFile 类的
q, ]: _7 G% U0 o+ V3 ~- C: e9 f操作成员函数来实现,它要用到对于文件操作的底层操作方式,如READ、WRITE
、GETLENTH等,并且要直接操作文件的属性,如创建、读、写等;而且,其缓冲
区的设置对于文件的大小和不同的计算机是不同的,特别是对于长度很大的数据
. Q: g- @6 W K3 |$ ]. ?- K/ S( \库进行备份,很难达到最佳效果。
---- 另一种有效的方式是利用Win32外壳来实现这些对于文件的操作。它可以实
现包括文件的拷贝、更名、移动及删除等,并且可以支持通配符(如*和?),也
可以直接对一个目录或目录树进行操作。
---- 本文分析了Win32外壳API对于文件操作的原理,并利用Visual C++6.0实现
文件的拷贝操作。
一、 原理与结构
7 @7 {( }1 t& @' Z) F* P5 P4 a
---- Windows95/NT中提供了一个API函数SHFileOperation(),它只有一个指向
SHFILEOPSTRUCT结构的参数。SHFileOperation()函数的原形如下:
4 H$ c! {. l; i$ r" L0 f9 A9 a: N- `4 [" k$ ^ Z1 c1 [ A
---- WIN SHELL API int WINAPI SHFileOperation (LPSHFILEOPSTRUCT
lpFIleOp);
$ o$ p3 k/ z1 l( U/ d
---- LPSHFILEOPSTRUCT结构包含有进行文件操作的各种信息, 其具体的结构如
下:
Typedef struct _ShFILEOPSTRUCT {
O( Q- b+ J/ V
HWND hWnd; //消息窗口
9 T7 [/ u/ h- ^) }& U( ~7 P& l3 V$ _; t* X& W) t' L
UINT wFunc; //操作类型
: R3 k; C* d; C/ y1 J5 |0 T7 H
LPCSTR pFrom; //源文件及路径
# X% f$ c( b+ ?" B# `6 S6 c; T% n( O; Q/ D8 N
LPCSTR pTo; //目标文件及路径
FILEOP_FLAGS fFlags; //操作与确认标志
( R+ o/ M N6 i: a7 M( U/ k0 Y& ]* s8 H) Y$ Q! r; @8 k
BOOL fAnyOperationsAborted; //操作选择位
" `; H8 y0 l/ f6 V- i- w
LPVOID hNameMappings; //文件映射
; t" R }4 J% S4 t& \' n; r
LPCSTR lpszProgressTitle; //进度窗口标题
4 v* `- ]% ^9 e
} SHFILEOPSTRUCT, FAR* LPSHFILEOPSTRUCT;
% l b, u: q+ P) {9 ~( `
---- 在这个结构中,有几个成员很重要。hWnd是指向发送消息的窗口,pFrom
与pTo是进行文件操作的源文件名和目标文件名,它包含文件的路径,对于多个
$ Z! \. d* @6 |! ]8 @文件名之间用NULL作为间隔,并且可以支持通配符*和?。如源文件或目录有两
; L* u, F# A4 E E: ] r$ C/ D个,则应是:
8 G/ y0 V1 e1 o0 l9 k& g( V
char pFrom[]="c:\\windows\\command
' J$ h" D2 K/ H% s- }$ w' i6 y$ L+ v5 f# F4 k5 w$ U
\0c:\\dos\\himem.sys\0"
4 `: ~- ]2 ]* m6 j" G9 i! @# w* ^, C+ F0 a0 `# D$ f! M9 h6 k) ^* F, |
---- 它表示对c:\windows\command目录下的所有文件和c:\dos\himem.sys文件
进行操作。'\\'是C语言中的'\'的转义符,'\0'则是NULL。wFunc 是结构中的重
要成员,它指出将要进行的操作类型,是下面的操作类型之一:
---- FO_COPY: 拷贝文件pFrom到pTo 的指定位置。
3 w( B1 h. C- B8 m) W7 e$ i8 S5 I. R
---- FO_RENAME: 将pFrom的文件名更名为pTo的文件名。
" c7 _. E/ g1 f5 {) g; a# _5 M$ d
, v% c4 P/ G6 O; j* o1 X; y1 D% V6 k
---- FO_MOVE: 将pFrom的文件移动到pTo的地方。
---- FO_DELETE: 删除pFrom指定的文件。
0 N1 T3 X: K4 n/ p5 s9 I: z4 v6 c2 ], c6 l+ h
---- 在进行文件拷贝、移动或删除时,如果需要的时间很长,则会在进行的过
程中出现一个无模式的对话框,可以显示执行的进度和执行的时间,以及正拷贝
( Z3 [; E( Y' w9 D9 X; M' T移动或删除的文件名,成员lpszProgressTitle显示此对话框的标题。fFlags是
在进行文件操作时的过程和状态控制标识。它主要有如下一些标识,也可以是其
组合。
---- FOF_FILESONLY:不执行通配符,只执行文件.
9 X# D2 a; z4 S+ N# {# c) @
---- FOF_ALLOWUNDO:保存 UNDO信息,以便恢复.
---- FOF_NOCONFIRMATION: 在出现目标文件已存在的时
候,如
果不设置此项,则它会出现确认是否覆盖的对话框,设置
, D! ]: J! ]) E7 m1 U' W此项则
自动确认,进行覆盖,不出现对话框。
) k* @" f: @6 i
---- FOF_NOERRORUI: 设置此项后,当文件处理过程中出
' @% i. b- a& P, `% T0 I现错误
时,不出现错误提示,否则会进行错误提示。
6 S, |6 a0 x( u, r
---- FOF_RENAMEONCOLLISION: 当已存在文件名时,对其
进行更
# b- }8 ?! ^* ]! Z换文件名提示。
# [& `3 l3 i! }0 P
---- FOF_SILENT: 不显示进度对话框。
2 V1 m1 R1 X+ r( k- J7 Z9 s+ f! x& m8 Y/ j% r# W3 D' L% n& C
---- FOF_WANTMAPPINGHANDLE: 要求SHFileOperation()
7 s% g; }& G. l) n4 d函数返
回正处于操作状态的实际文件列表,文件列表名柄保存在
+ S" G) p9 R/ k- v% K' J0 T0 e
hNameMappings成员中。SHFILEOPSTRUCT将包含一个
) N9 ?$ Z ?; C& ^3 f* DSHNAMEMAPPING结构的数组,此数组保存由SHELL计算的每
# }2 u+ S# R$ E$ E: k5 w个处于
操作状态的文件的新旧路径。
二、 实例操作
8 d! T- r. ?0 D) W/ _. v4 b2 ?6 A, H5 u1 y
---- 本文就一个Visual C++程序来实现文件复制的实例。首先建立一个单文档
界面filecopy,然后在主框架中新增一个工具条变量m_wndMyToolBar,新建一个
工具条IDR_MYTOOLBAR,设置一个工具消息ID_FILECOPY,并在主框架MainFrm.
cpp的OnCreate()成员函数中加入工具栏。
if(!m_wndMyToolBar.Create(this)||
. m+ `6 ^ Q, w' d4 |. X
!m_wndMyToolBar.LoadToolBar(IDR_MYTOOLBAR))
{
M5 u/ ?4 w1 K9 l* w+ o3 {4 i: M3 ]+ G$ Y
TRACE("can not create the FileToolBar!\n");
9 m" E/ J. C' u/ ]# C+ F; E|+ K# E5 ]1 _7 r
/ V2 r$ e& T5 e* y/ W8 _
return -1;
! }* g, }5 f8 ^+ j& F
}
- j% L5 y" s q- L) X/ l- z
$ p4 v; q4 b Q% t4 ^( z
---- 通过中视类操作工具条IDR_MYTOOL,利用ClassWizard为其 消息
& e, Y/ D; l$ T( V+ d3 q+ UID_FILECOPY新增消息处理函数OnFilecopy。然后在处理函数中加入下面程序。
" H9 M5 h1 k- I
void OnFilecopy()
) J, \8 [3 ?) L, w: D+ w{
int nOk;
" E+ T- P; j) o2 N) a+ ^" D- `' H% {% schar strSrc[]="c:\\dos\0c:
) i1 |- P, Y3 `3 J' k( t3 q7 ~ h//可以改变源路径
char strDst[]="c:\\temp\0";
//设置目的路径
char strTitle[]="File copying";
( u* G, n1 {( j( l, v//进度题头
SHFILEOPSTRUCT FileOp;
FileOp.hwnd=m_hWnd;
& v. \4 G9 @6 ^
FileOp.wFunc=FO_COPY;
0 _& A; V+ L, I# e3 w/ J" H# l. e3 p8 n ~" W7 {
//执行文件拷贝
9 m7 }* P) i, u! K/ |# e/ o
FileOp.pFrom=strSrc;
! _& I" l W; s: c5 Z2 M) ]3 ~# o9 v8 c
FileOp.pTo=strDst;
& D/ G7 H% A |9 Q# ?* S6 S
FileOp.fFlags=FOF_ALLOWUNDO;
4 T6 N: H) |6 ]2 _. @2 v5 r
FileOp.hNameMappings=NULL;
c$ D0 v3 b1 t) R- h7 {) U9 {Y# p( e) u9 j. j, ^
FileOp.lpszProgressTitle=strTitle;
5 W/ K& @' Y$ n2 ^8 H
nOk=SHFileOperation(&FileOp);
1 Q! _( V9 i" _; {: W" r( k* B4 O, J" I! y2 B2 \# S
if(nOk)
' L- g+ l. j) i" f
TRACE("There is an error: %d\n",nOk);
3 t% x8 }, ?; y3 z/ v' O$ e& p* d( j; Q/ D! Y0 w! m( l
else
TRACE("SHFileOperation finished
9 p' J/ m' \0 \, D/ e6 ~# T. Tsuccessfully\n");
if(FileOp.fAnyOperationsAborted)
TRACE("Operation was aborted!\n");
* ~! ?6 {3 D$ {& Q4 p1 q}
8 D% j& X5 B+ j) R! M8 S+ ]
三、 结束语
7 b% G4 Q% C# c
---- 利用Windows API进行程序文件操作设计,它直接调用Windows操作系统中
5 _. u- U- w; B. S; u的外壳,它的处理过程与Windows95/98/NT中的处理过程是一致的有利于我们在
/ i4 [( g5 Q9 {% Y' ?0 p# {: q系统程序设计中保持与操作系统的一致性;同时,由于在文件处理中它是直接调
用WindowsAPI函数,因此不需要其它应用程序动态链接库DLL的支持。
" V8 [4 q: \3 k; s6 i+ U7 x
---- 在各种开发软件中,都提供了对于文件的各种操作方式,但是它必须利用
3 z$ {7 W6 ?; V2 X L到文件系统较为深入的知识,而且对于其操作的直观性方面也需要开发者进一步
地设计,因此利用操作系统SHELL进行程序设计,不失是一种好的设计方法。
| 欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) | Powered by Discuz! X2.5 |