7 N; H' T, v1 ?; e+ M" |
湖北工学院图书馆计算机室
张明武
- u. T6 @% e" K0 T7 {8 h- Y! N7 c9 i2 H/ x
---- 在Windows中实现文件的操作主要有两种方法。一种是直接利用CFile 类的
) V) K. }2 w. L操作成员函数来实现,它要用到对于文件操作的底层操作方式,如READ、WRITE
、GETLENTH等,并且要直接操作文件的属性,如创建、读、写等;而且,其缓冲
+ B' \. q: g, ] V区的设置对于文件的大小和不同的计算机是不同的,特别是对于长度很大的数据
库进行备份,很难达到最佳效果。
- F+ z8 f' L, }3 s, F* J! }3 \! {% f3 Y7 D4 [. o& ]: {
---- 另一种有效的方式是利用Win32外壳来实现这些对于文件的操作。它可以实
现包括文件的拷贝、更名、移动及删除等,并且可以支持通配符(如*和?),也
4 k& r7 \( R, ]: ~) q可以直接对一个目录或目录树进行操作。
5 G( W" i Q2 \. r, C- s) P
---- 本文分析了Win32外壳API对于文件操作的原理,并利用Visual C++6.0实现
/ ~5 c+ J. m1 a8 }. j* L. U" D文件的拷贝操作。
& v) e3 h# L( N4 o, O/ B; y
一、 原理与结构
---- Windows95/NT中提供了一个API函数SHFileOperation(),它只有一个指向
SHFILEOPSTRUCT结构的参数。SHFileOperation()函数的原形如下:
. q' k! V, `( q0 S$ E) c q, g) P0 K5 B
---- WIN SHELL API int WINAPI SHFileOperation (LPSHFILEOPSTRUCT
# v5 }3 ?( q/ H( z6 Z% I! L2 AlpFIleOp);
0 F u, l Z- t( [3 x; r" G
---- LPSHFILEOPSTRUCT结构包含有进行文件操作的各种信息, 其具体的结构如
% ]! v. |, i& l下:
Typedef struct _ShFILEOPSTRUCT {
, Q7 _* B: x7 W u& ^
HWND hWnd; //消息窗口
$ i7 R/ g$ R3 ~ P; Z8 O: a9 Y V8 b
UINT wFunc; //操作类型
LPCSTR pFrom; //源文件及路径
6 C7 S v; Q* y, i& r
LPCSTR pTo; //目标文件及路径
# Z& Y0 [6 ~+ s
FILEOP_FLAGS fFlags; //操作与确认标志
+ K3 P2 n- x: V
BOOL fAnyOperationsAborted; //操作选择位
H- K1 o: Q$ o9 k" T7 ?7 W0 X+ ?+ T
LPVOID hNameMappings; //文件映射
" r# K3 X! u+ W) p, z3 r/ k
LPCSTR lpszProgressTitle; //进度窗口标题
} SHFILEOPSTRUCT, FAR* LPSHFILEOPSTRUCT;
8 W2 n3 @+ t' ~+ p* J: n- h6 J6 N* r- q; h
---- 在这个结构中,有几个成员很重要。hWnd是指向发送消息的窗口,pFrom
$ D$ n- |2 K! H& P+ g, k与pTo是进行文件操作的源文件名和目标文件名,它包含文件的路径,对于多个
+ U0 o6 } B+ O6 h9 S8 y文件名之间用NULL作为间隔,并且可以支持通配符*和?。如源文件或目录有两
# l: F4 W k, ^- k5 r3 S' d, ~个,则应是:
! o" Q1 c! R! @" [6 c4 t: e* Z9 y2 I" {
char pFrom[]="c:\\windows\\command
/ b0 l& x2 ^3 X5 _) i4 {7 P8 K3 Q, F! }" ?6 J( x& g) p# O W
\0c:\\dos\\himem.sys\0"
! t0 H8 d I. g1 l3 o6 c \) {( e
---- 它表示对c:\windows\command目录下的所有文件和c:\dos\himem.sys文件
进行操作。'\\'是C语言中的'\'的转义符,'\0'则是NULL。wFunc 是结构中的重
) M3 A3 P6 `" [4 v/ X& x! x要成员,它指出将要进行的操作类型,是下面的操作类型之一:
7 O: o3 |# ?! q; r$ s2 g
---- FO_COPY: 拷贝文件pFrom到pTo 的指定位置。
; d3 b) ?/ X- @9 In& N* ?+ W/ a& b2 R t( z$ B
---- FO_RENAME: 将pFrom的文件名更名为pTo的文件名。
2 N4 i1 l+ l7 R- l' J! o3 h( q
---- FO_MOVE: 将pFrom的文件移动到pTo的地方。
" M2 h& g2 N- X1 T
---- FO_DELETE: 删除pFrom指定的文件。
---- 在进行文件拷贝、移动或删除时,如果需要的时间很长,则会在进行的过
/ U! x% r( n1 d* k" Y7 z& g程中出现一个无模式的对话框,可以显示执行的进度和执行的时间,以及正拷贝
7 e A8 x4 M- ]' q. g( t' N移动或删除的文件名,成员lpszProgressTitle显示此对话框的标题。fFlags是
在进行文件操作时的过程和状态控制标识。它主要有如下一些标识,也可以是其
% s# n9 @6 F! M% h( \) c组合。
---- FOF_FILESONLY:不执行通配符,只执行文件.
2 b2 r; @: g0 {& a' A% u
---- FOF_ALLOWUNDO:保存 UNDO信息,以便恢复.
---- FOF_NOCONFIRMATION: 在出现目标文件已存在的时
' n9 O- Q! E. m, w1 I" [候,如
7 _/ c1 F. b# P" Q4 s$ a, Z果不设置此项,则它会出现确认是否覆盖的对话框,设置
此项则
( V- J3 s: h+ \3 I9 F; B6 p自动确认,进行覆盖,不出现对话框。
; T5 _. K/ l0 Z5 `9 u8 w4 f# Z
---- FOF_NOERRORUI: 设置此项后,当文件处理过程中出
现错误
1 |9 E' H3 X# U" N. m时,不出现错误提示,否则会进行错误提示。
---- FOF_RENAMEONCOLLISION: 当已存在文件名时,对其
+ O; _2 ~5 t" [进行更
8 @' d) G1 A' z换文件名提示。
---- FOF_SILENT: 不显示进度对话框。
( p& l9 I7 k5 f7 K2 U0 C0 U6 T5 g
---- FOF_WANTMAPPINGHANDLE: 要求SHFileOperation()
' G$ y# x8 [0 L/ W6 \% Z函数返
回正处于操作状态的实际文件列表,文件列表名柄保存在
hNameMappings成员中。SHFILEOPSTRUCT将包含一个
# W B: f; {' A8 J/ k' WSHNAMEMAPPING结构的数组,此数组保存由SHELL计算的每
: T9 t% j- u6 z1 \个处于
+ Q! M9 F' s( S, o) y) u操作状态的文件的新旧路径。
4 e$ O2 T4 G! w P4 Z6 b9 K8 k1 f ?- L: y9 `2 @$ ], w% J
二、 实例操作
+ M$ e, O+ L8 W' M! `$ ^4 W' L& ]1 F" q
---- 本文就一个Visual C++程序来实现文件复制的实例。首先建立一个单文档
" c* y v1 N$ S% g+ ?2 _9 r: q* f界面filecopy,然后在主框架中新增一个工具条变量m_wndMyToolBar,新建一个
; p* k$ d/ L3 p% U& P) q" ?8 R. j工具条IDR_MYTOOLBAR,设置一个工具消息ID_FILECOPY,并在主框架MainFrm.
cpp的OnCreate()成员函数中加入工具栏。
% p0 p4 ~$ a8 n) T( \% w5 ~2 h+ a5 g
if(!m_wndMyToolBar.Create(this)||
9 [( a e+ a) H$ r" M7 e/ [/ ? j! t! N, W+ _
!m_wndMyToolBar.LoadToolBar(IDR_MYTOOLBAR))
{
TRACE("can not create the FileToolBar!\n");
( {1 O$ ^5 N: U' E$ ^2 n' M @9 ^% ]4 D
7 I: F5 g- |. u5 p$ G9 s( n
return -1;
; l5 b' f. _7 f. H/ Y1 l3 h
}
' d5 h) H8 n$ ]3 H1 \
1 e( Y$ R0 L9 ^9 u0 O: A8 T& B
---- 通过中视类操作工具条IDR_MYTOOL,利用ClassWizard为其 消息
1 g& L' _" c: l6 jID_FILECOPY新增消息处理函数OnFilecopy。然后在处理函数中加入下面程序。
% @" U6 T% F" R2 u. F' N
void OnFilecopy()
* a" x) d7 R. c7 y% @+ ]{
) K% O" C0 _5 M" c8 z6 mint nOk;
char strSrc[]="c:\\dos\0c:
+ }- e) I3 B( _7 {6 F//可以改变源路径
! N, w, X$ M% I, G8 ?8 j7 e0 h" v3 G) c _
char strDst[]="c:\\temp\0";
8 _8 u8 v" ]* K//设置目的路径
& Z9 Q8 ?1 K* l
char strTitle[]="File copying";
//进度题头
; I# e. g2 I: J+ |) H- b% f& q
SHFILEOPSTRUCT FileOp;
0 W; `8 T3 i& y( F1 g* g% m
FileOp.hwnd=m_hWnd;
FileOp.wFunc=FO_COPY;
! U4 k+ x; H- R9 K( g; N# n0 r
//执行文件拷贝
FileOp.pFrom=strSrc;
- ?! g5 }) z! m; ~1 Z
FileOp.pTo=strDst;
4 K) b% q$ G4 T1 l# q2 z) j& o3 T0 [' [) R
FileOp.fFlags=FOF_ALLOWUNDO;
FileOp.hNameMappings=NULL;
FileOp.lpszProgressTitle=strTitle;
8 `1 r' g* Y# ~. n* U1 k
nOk=SHFileOperation(&FileOp);
. `1 L* W q3 I& w5 J M! g% q. V
if(nOk)
6 G7 F; P8 _. z; f+ a, R( [
TRACE("There is an error: %d\n",nOk);
else
1 N/ L+ ?- W. N/ C$ o5 p2 U) H( v$ v$ X
TRACE("SHFileOperation finished
3 _4 x/ [9 ^0 xsuccessfully\n");
if(FileOp.fAnyOperationsAborted)
% b2 v u; m3 M& |7 e. R; Z( d+ }1 z; ~! m+ g3 ]
TRACE("Operation was aborted!\n");
}
# X2 T0 W" d1 Q ^. R4 ^' P& U
三、 结束语
---- 利用Windows API进行程序文件操作设计,它直接调用Windows操作系统中
的外壳,它的处理过程与Windows95/98/NT中的处理过程是一致的有利于我们在
系统程序设计中保持与操作系统的一致性;同时,由于在文件处理中它是直接调
用WindowsAPI函数,因此不需要其它应用程序动态链接库DLL的支持。
6 R' d+ p7 N$ m1 N4 b
---- 在各种开发软件中,都提供了对于文件的各种操作方式,但是它必须利用
到文件系统较为深入的知识,而且对于其操作的直观性方面也需要开发者进一步
; m K8 g1 w% w地设计,因此利用操作系统SHELL进行程序设计,不失是一种好的设计方法。
| 欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) | Powered by Discuz! X2.5 |