湖北工学院图书馆计算机室
: k; b# }( N% Y" W+ Q张明武
0 _! ~4 @7 C: q! t! N
---- 在Windows中实现文件的操作主要有两种方法。一种是直接利用CFile 类的
操作成员函数来实现,它要用到对于文件操作的底层操作方式,如READ、WRITE
、GETLENTH等,并且要直接操作文件的属性,如创建、读、写等;而且,其缓冲
区的设置对于文件的大小和不同的计算机是不同的,特别是对于长度很大的数据
" R( I( a# l1 d# `& n% F" s库进行备份,很难达到最佳效果。
" l* N* b: a2 v& O* w2 {8 G2 G U9 W$ P& C0 U+ R
---- 另一种有效的方式是利用Win32外壳来实现这些对于文件的操作。它可以实
; w& J4 T0 s# X* N现包括文件的拷贝、更名、移动及删除等,并且可以支持通配符(如*和?),也
, f6 b+ f' c" O可以直接对一个目录或目录树进行操作。
7 Y* v6 C; n, |+ ^! D
---- 本文分析了Win32外壳API对于文件操作的原理,并利用Visual C++6.0实现
文件的拷贝操作。
一、 原理与结构
8 k1 X7 e8 ^. H! F C$ f4 b8 p1 R/ `6 s
---- Windows95/NT中提供了一个API函数SHFileOperation(),它只有一个指向
7 n: U$ J& U; C8 o6 t- M! ~SHFILEOPSTRUCT结构的参数。SHFileOperation()函数的原形如下:
; J* e/ k' U0 N5 `
---- WIN SHELL API int WINAPI SHFileOperation (LPSHFILEOPSTRUCT
( C# Y1 }2 ~1 P1 Z! E, }. ClpFIleOp);
$ o! N2 |' Y9 T0 O6 j
---- LPSHFILEOPSTRUCT结构包含有进行文件操作的各种信息, 其具体的结构如
下:
) s/ L, E" G8 ~& F7 }1 ^0 k, [# ]$ x Z
Typedef struct _ShFILEOPSTRUCT {
& l/ R+ N* H; ~( A7 H/ X2 ?& @: x- m( a( g0 ]9 E% R+ i$ E( k
HWND hWnd; //消息窗口
0 u6 t1 R7 T4 L; z% X* d. }% X5 ?. h0 ]
UINT wFunc; //操作类型
t' D9 A8 A0 M8 u' J. r/ W$ S( F
LPCSTR pFrom; //源文件及路径
9 a4 y& v0 \: d9 e5 Y
LPCSTR pTo; //目标文件及路径
FILEOP_FLAGS fFlags; //操作与确认标志
! g6 |$ U+ a/ Q+ D$ D
BOOL fAnyOperationsAborted; //操作选择位
LPVOID hNameMappings; //文件映射
; Z+ Y! j {0 I; v6 P
LPCSTR lpszProgressTitle; //进度窗口标题
8 H0 h! Q) }3 b I8 h3 \5 R
} SHFILEOPSTRUCT, FAR* LPSHFILEOPSTRUCT;
$ x, }1 E) j3 ]+ W* B3 R) x {
---- 在这个结构中,有几个成员很重要。hWnd是指向发送消息的窗口,pFrom
2 B7 E' U: M7 |+ j8 Y; O7 R与pTo是进行文件操作的源文件名和目标文件名,它包含文件的路径,对于多个
文件名之间用NULL作为间隔,并且可以支持通配符*和?。如源文件或目录有两
5 e$ o+ y1 ~2 I个,则应是:
# u" |$ Q9 c+ N& [" ?2 p: I* U$ D0 w8 n: |, M6 C1 J
char pFrom[]="c:\\windows\\command
/ c5 D& W9 h! R
\0c:\\dos\\himem.sys\0"
---- 它表示对c:\windows\command目录下的所有文件和c:\dos\himem.sys文件
' K; U' S2 U6 a9 Z- V& f/ Z进行操作。'\\'是C语言中的'\'的转义符,'\0'则是NULL。wFunc 是结构中的重
要成员,它指出将要进行的操作类型,是下面的操作类型之一:
) V# y' N% [0 W
---- FO_COPY: 拷贝文件pFrom到pTo 的指定位置。
" C. ~1 [; G7 z! ~! ^1 v( G) G
---- FO_RENAME: 将pFrom的文件名更名为pTo的文件名。
---- FO_MOVE: 将pFrom的文件移动到pTo的地方。
" g4 N# C7 i3 z: H0 h- z# U
---- FO_DELETE: 删除pFrom指定的文件。
3 k: @- c) F3 B8 s# D1 n+ N0 M, T6 a" \+ ~
---- 在进行文件拷贝、移动或删除时,如果需要的时间很长,则会在进行的过
2 T! |- Y, [- x8 i0 n( ]程中出现一个无模式的对话框,可以显示执行的进度和执行的时间,以及正拷贝
5 h* Y! J3 {) r' `# [6 R* S移动或删除的文件名,成员lpszProgressTitle显示此对话框的标题。fFlags是
2 q7 F4 \/ L+ b7 |8 |; S在进行文件操作时的过程和状态控制标识。它主要有如下一些标识,也可以是其
$ V% }3 s* b$ U9 [" ? O# m组合。
# @9 b, g. p d T
---- FOF_FILESONLY:不执行通配符,只执行文件.
6 r6 z. ^: u! i, h" d$ {
---- FOF_ALLOWUNDO:保存 UNDO信息,以便恢复.
% c: m( a( \0 i5 j# X2 `# F
---- FOF_NOCONFIRMATION: 在出现目标文件已存在的时
候,如
果不设置此项,则它会出现确认是否覆盖的对话框,设置
- x5 V* n7 j( \- m$ {此项则
$ c/ k9 i1 l+ C- ?自动确认,进行覆盖,不出现对话框。
---- FOF_NOERRORUI: 设置此项后,当文件处理过程中出
现错误
时,不出现错误提示,否则会进行错误提示。
/ v+ n; H1 L1 ~& b# j- h% Z. t8 f- |9 L% H9 _
---- FOF_RENAMEONCOLLISION: 当已存在文件名时,对其
( I. v1 q* N# O6 |- M8 P# q进行更
: l$ `/ F7 S8 r: I5 {- C1 K& A换文件名提示。
& T. U, j9 u# e/ I3 M* ]0 C% z. j. Z, P
---- FOF_SILENT: 不显示进度对话框。
8 r! B( z/ k3 t* E. T1 l- d2 V5 G( z. g3 P1 t$ O2 h
---- FOF_WANTMAPPINGHANDLE: 要求SHFileOperation()
函数返
+ z$ d! g1 [0 g0 A* V$ G回正处于操作状态的实际文件列表,文件列表名柄保存在
; `; K( N$ L ^7 s: g3 F. ^: @
hNameMappings成员中。SHFILEOPSTRUCT将包含一个
3 V+ }0 y$ i! `SHNAMEMAPPING结构的数组,此数组保存由SHELL计算的每
个处于
3 d& [2 {% i. j4 z操作状态的文件的新旧路径。
二、 实例操作
+ b- |5 \$ k4 j0 x9 y9 R& E
---- 本文就一个Visual C++程序来实现文件复制的实例。首先建立一个单文档
4 J1 A0 B1 N8 @! e- p, w界面filecopy,然后在主框架中新增一个工具条变量m_wndMyToolBar,新建一个
工具条IDR_MYTOOLBAR,设置一个工具消息ID_FILECOPY,并在主框架MainFrm.
: U2 R9 } ^& G k& V, f# _. C4 ~cpp的OnCreate()成员函数中加入工具栏。
3 o8 k( D( n+ E& s1 y% b
if(!m_wndMyToolBar.Create(this)||
! L# Y$ A) |5 m! P1 u; u) J+ r* O% Q0 l" E' R0 T& B! S
!m_wndMyToolBar.LoadToolBar(IDR_MYTOOLBAR))
& M7 }+ Z( A8 z/ b, z
{
# }3 a$ Z3 ?! i2 t" O7 m9 N/ F: j
TRACE("can not create the FileToolBar!\n");
7 S& F: ?- M- E. d4 Y( o" d+ M0 T6 f
return -1;
( E7 I& S4 v& c: ~6 i2 }0 t! }' K+ ?$ C1 [/ @
}
3 y# j/ x6 V6 t; E) i. o z" C4 @! G; B' n2 R% b# ?' V7 o: j
% Q8 V8 f4 u8 ?' u0 o
---- 通过中视类操作工具条IDR_MYTOOL,利用ClassWizard为其 消息
' ~1 r- ]" E: z6 QID_FILECOPY新增消息处理函数OnFilecopy。然后在处理函数中加入下面程序。
`! s6 v' R; }9 C
void OnFilecopy()
{
int nOk;
char strSrc[]="c:\\dos\0c:
! t/ i7 J/ {; j' S, F; X% E8 B 5 ]1 W1 ?: p3 q$ C1 d//可以改变源路径
3 H2 `, A' v0 x- @6 B# q8 ]; _( g7 ?1 I% C$ n5 v: M
char strDst[]="c:\\temp\0";
8 R; F2 `; z8 I4 P0 C//设置目的路径
char strTitle[]="File copying";
3 J [3 ~ I% z/ T# \& m5 ^//进度题头
SHFILEOPSTRUCT FileOp;
% R3 V( F8 p0 |) P* F" k
FileOp.hwnd=m_hWnd;
; p1 k! b7 I- w6 f2 u8 \4 k
FileOp.wFunc=FO_COPY;
//执行文件拷贝
4 T( ]- ^3 e% t
FileOp.pFrom=strSrc;
' T2 L ~0 J& Q1 H. U3 I3 _
FileOp.pTo=strDst;
FileOp.fFlags=FOF_ALLOWUNDO;
( |/ W# T0 M% a$ g" z
FileOp.hNameMappings=NULL;
+ x \! L# q4 ?2 k4 D5 @; Z7 [& }6 D" e% I3 u9 E8 X
FileOp.lpszProgressTitle=strTitle;
nOk=SHFileOperation(&FileOp);
if(nOk)
# x9 I5 a1 V# M, h& l8 u6 g/ F+ z. j# h
TRACE("There is an error: %d\n",nOk);
( A5 J8 s) b: r: w$ T
else
TRACE("SHFileOperation finished
successfully\n");
if(FileOp.fAnyOperationsAborted)
TRACE("Operation was aborted!\n");
}
: E: Z3 v% Q8 N8 ^) `0 p- H2 m, N3 h- }1 |2 n! }8 o# o& R
三、 结束语
, F `; u) V9 j- G- }" N
---- 利用Windows API进行程序文件操作设计,它直接调用Windows操作系统中
9 L9 f( V" P( i( N3 H的外壳,它的处理过程与Windows95/98/NT中的处理过程是一致的有利于我们在
系统程序设计中保持与操作系统的一致性;同时,由于在文件处理中它是直接调
" D# q' T5 ]+ k. X用WindowsAPI函数,因此不需要其它应用程序动态链接库DLL的支持。
8 T) ~' _. x; m( D: [8 w1 k- k) _2 \/ `; `3 z
---- 在各种开发软件中,都提供了对于文件的各种操作方式,但是它必须利用
到文件系统较为深入的知识,而且对于其操作的直观性方面也需要开发者进一步
- o7 B3 t4 y; `地设计,因此利用操作系统SHELL进行程序设计,不失是一种好的设计方法。
| 欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) | Powered by Discuz! X2.5 |