QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2736|回复: 0
打印 上一主题 下一主题

在WIN95中实现文件拷贝的编程方法

[复制链接]
字体大小: 正常 放大
韩冰        

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

跳转到指定楼层
1#
发表于 2005-1-26 01:29 |只看该作者 |倒序浏览
|招呼Ta 关注Ta

# m( `' ]) q& R6 _" l

湖北工学院图书馆计算机室

2 L! ]7 m; k! T3 Q+ L

张明武

! `' ]2 W+ r( f/ m, u

' M) u. E% F2 ]' z8 A2 ]; H. n

---- 在Windows中实现文件的操作主要有两种方法。一种是直接利用CFile 类的

* @% z( R) c) x

操作成员函数来实现,它要用到对于文件操作的底层操作方式,如READ、WRITE

% ]: A+ ~8 K& k( k! A+ w1 i# f

、GETLENTH等,并且要直接操作文件的属性,如创建、读、写等;而且,其缓冲

1 G6 ?; [. x9 \" w9 ?) I1 Q

区的设置对于文件的大小和不同的计算机是不同的,特别是对于长度很大的数据

" Z- ~" R- O, g) c6 d3 s& R* B2 b

库进行备份,很难达到最佳效果。

- A) Y n( n& m* Z

* a) B* \7 r% }/ L7 M( U, }5 c- f4 X3 ]

---- 另一种有效的方式是利用Win32外壳来实现这些对于文件的操作。它可以实

! R5 x/ t- V5 A7 V

现包括文件的拷贝、更名、移动及删除等,并且可以支持通配符(如*和?),也

- A% u6 x {% u, l. ]

可以直接对一个目录或目录树进行操作。

1 c8 d" e; e- g

# }& V4 y/ B4 w" X: h

---- 本文分析了Win32外壳API对于文件操作的原理,并利用Visual C++6.0实现

/ O9 d* x9 p" t0 p! M

文件的拷贝操作。

: G& O, m$ D% C4 R0 \

& n; V; H- l/ t+ A, t

一、 原理与结构

0 w6 x- t6 ?% B5 l) j+ Q

) M* c K' M" u* [

---- Windows95/NT中提供了一个API函数SHFileOperation(),它只有一个指向

) X5 J# f" f# v( W& A$ j

SHFILEOPSTRUCT结构的参数。SHFileOperation()函数的原形如下:

" A1 B7 \* N; x% n

3 U% ]1 b: b1 F, p1 s& w( Q4 P8 U

---- WIN SHELL API int WINAPI SHFileOperation (LPSHFILEOPSTRUCT

" R5 H' B* C% W; g9 F

lpFIleOp);

8 j- P f+ w5 c* r4 ~0 A

3 u$ d% x& \( c/ L9 T# Y' F

---- LPSHFILEOPSTRUCT结构包含有进行文件操作的各种信息, 其具体的结构如

) M z8 d( F: J8 w, e

下:

; U0 v5 I! u3 t% ^0 c$ c

4 z$ I, g3 U$ n! b0 l; l

Typedef struct _ShFILEOPSTRUCT {

3 ^! f, L5 [7 ~

! J3 L- K2 ~; y5 f# O/ F

HWND hWnd; //消息窗口

+ l& i9 \* c' o7 h! |

' ]. s2 R1 g' b9 h+ g* J6 y8 ^

UINT wFunc; //操作类型

0 b9 a( e+ |0 _. I7 S$ [; B

- f- ~: O9 ]3 l% A+ B

LPCSTR pFrom; //源文件及路径

7 o0 R! Y+ I1 O8 Z

- F4 l0 h& g. {$ o

LPCSTR pTo; //目标文件及路径

# j1 o- u; [* F5 q6 _; R

: ]# p! z7 v% h( P- `% U+ H/ F- d, g3 `

FILEOP_FLAGS fFlags; //操作与确认标志

, }5 x2 W1 ]( `

* Q! _3 ^! N. C' t$ o& } u

BOOL fAnyOperationsAborted; //操作选择位

- c3 d0 S. T [: Y

- C7 {: p% k9 n/ v

LPVOID hNameMappings; //文件映射

2 y9 k5 _! I% X5 P7 D7 Q

) S" v7 v+ }6 O6 E$ i& r# E

LPCSTR lpszProgressTitle; //进度窗口标题

: }4 Q. `" o, W, L

% E$ Q2 o' g: |" A) l A, T

! f: o: U# A( D9 i

} SHFILEOPSTRUCT, FAR* LPSHFILEOPSTRUCT;

9 a3 C8 L) Q. ]1 X2 `% n7 E

W+ i' p# Q5 `$ I* z& T

( C- A& }$ M2 ^

---- 在这个结构中,有几个成员很重要。hWnd是指向发送消息的窗口,pFrom

7 _. j. }1 T& ~

与pTo是进行文件操作的源文件名和目标文件名,它包含文件的路径,对于多个

( e7 w3 V, K/ j/ ~$ C, x t2 `: X; q6 N: j

文件名之间用NULL作为间隔,并且可以支持通配符*和?。如源文件或目录有两

+ D0 r6 C/ Q P4 B1 A7 x) x

个,则应是:

! F1 D! R D |2 n$ u

`. c; ~! V. y/ U1 n0 Z

char pFrom[]="c:\\windows\\command

! z5 e7 r7 z4 v& @. |

, n! O7 w1 Z) N

\0c:\\dos\\himem.sys\0"

% L. u) G4 J% \- s! n. M

$ o( `$ M8 ~- N

---- 它表示对c:\windows\command目录下的所有文件和c:\dos\himem.sys文件

: a0 x' W" b& z' N7 Z8 s

进行操作。'\\'是C语言中的'\'的转义符,'\0'则是NULL。wFunc 是结构中的重

" H0 b" @0 b# f5 M/ @3 A

要成员,它指出将要进行的操作类型,是下面的操作类型之一:

0 B U7 r0 f( T2 M6 X

9 C/ i5 C( K% Y

---- FO_COPY: 拷贝文件pFrom到pTo 的指定位置。

( i; ~( T$ c9 o

: ?1 g4 G, Q5 N e$ Z

---- FO_RENAME: 将pFrom的文件名更名为pTo的文件名。

4 R. S% H; T0 N- P3 o' b

6 Y3 y3 J; x1 J8 |& O0 U7 y

: Q) [6 X+ N2 v2 v8 f

---- FO_MOVE: 将pFrom的文件移动到pTo的地方。

. a7 r0 b# G1 r1 a" l

k i5 z+ F7 b1 s. w& J% A$ Q

---- FO_DELETE: 删除pFrom指定的文件。

' K2 s8 R% }" m5 C4 u, I* p% A* t

* y4 F% A( m3 D; r9 [* M7 t

---- 在进行文件拷贝、移动或删除时,如果需要的时间很长,则会在进行的过

% `/ M$ u U# H

程中出现一个无模式的对话框,可以显示执行的进度和执行的时间,以及正拷贝

, F4 D8 O; R- S. A! R

移动或删除的文件名,成员lpszProgressTitle显示此对话框的标题。fFlags是

& @8 _* A! c0 ?; s9 P( |2 B3 v3 G/ D

在进行文件操作时的过程和状态控制标识。它主要有如下一些标识,也可以是其

" O7 ]- t0 K# ?" ^7 u. w* f( g- t4 {0 A

组合。

* u w0 j* r7 b2 K6 q" z

% m1 v7 D) G$ @8 p0 S

---- FOF_FILESONLY:不执行通配符,只执行文件.

4 S7 `% V; d/ ^% d- C+ }! \& Z

3 K& l7 N- j, a: g4 C5 D

---- FOF_ALLOWUNDO:保存 UNDO信息,以便恢复.

# A# V# g5 f! ^% W; V& ~" V

2 O4 j" w) [7 E) q$ T! l( i3 M

---- FOF_NOCONFIRMATION: 在出现目标文件已存在的时

+ F8 U* V1 B6 ?$ n5 A4 E, r

候,如

4 J, n# ]3 D, g: t0 ?6 I4 u

果不设置此项,则它会出现确认是否覆盖的对话框,设置

. S" j% n! n7 h2 u' V) V

此项则

- I' }, x) T O' n& {5 n1 ?; C6 v4 E8 T

自动确认,进行覆盖,不出现对话框。

3 _) x& u, Y% {. s0 ~5 \2 t

6 v9 }: X: Z/ Z( \

---- FOF_NOERRORUI: 设置此项后,当文件处理过程中出

! J4 N# A o0 w5 n' B/ n' n

现错误

6 t% y7 R3 |0 f& f; f

时,不出现错误提示,否则会进行错误提示。

& F. b8 S- V0 I v: i; T

+ y* Q+ F7 c) t" J2 G3 C) |3 K

---- FOF_RENAMEONCOLLISION: 当已存在文件名时,对其

' |! q O9 X. f1 [8 h

进行更

* L! S* a$ h! l/ H

换文件名提示。

: i9 U' K. ]! K

5 [+ v2 \4 U3 }- {3 g+ N1 @5 r

---- FOF_SILENT: 不显示进度对话框。

0 Y m$ D( G" w( Z/ Z) ]3 r, ^

6 X; l3 C8 ]6 p2 q

---- FOF_WANTMAPPINGHANDLE: 要求SHFileOperation()

! P4 Q# ~- u4 i/ ^) i) t, \

函数返

8 `5 ]% K1 L+ }9 |; [9 |

回正处于操作状态的实际文件列表,文件列表名柄保存在

* _* X' v0 C/ ~5 l

5 a" i7 w2 A2 w

hNameMappings成员中。SHFILEOPSTRUCT将包含一个

: Y5 ]: ~) |; n. D

SHNAMEMAPPING结构的数组,此数组保存由SHELL计算的每

6 y; i( _2 V, p+ t9 K

个处于

5 C, [ ^- L- [, Q

操作状态的文件的新旧路径。

2 h! y S, i9 b1 d: |% i* w

! J" T5 Q @( B: H

二、 实例操作

" p, l' i( X& |: C, v

% Y* o [+ U: P+ _' q! h. g

---- 本文就一个Visual C++程序来实现文件复制的实例。首先建立一个单文档

/ i2 r# r) u' F! v0 `

界面filecopy,然后在主框架中新增一个工具条变量m_wndMyToolBar,新建一个

$ A- S5 M5 f# H; V9 G; T

工具条IDR_MYTOOLBAR,设置一个工具消息ID_FILECOPY,并在主框架MainFrm.

9 ]" S2 l4 F( h9 C* g

cpp的OnCreate()成员函数中加入工具栏。

) i3 _2 B8 f# H, r* k9 E; |

: Z5 w! c. s% L: w

if(!m_wndMyToolBar.Create(this)||

6 j H0 U7 e6 u) ~& E) [

+ t3 B6 D& i! V$ n* ^$ L

!m_wndMyToolBar.LoadToolBar(IDR_MYTOOLBAR))

. W2 u& L- ~% t, Y7 x

0 p/ x! [% @1 _) g

{

. o7 w2 X/ t" A1 a9 ~3 }

9 Q& L! T: L' Q/ g$ l3 Y

TRACE("can not create the FileToolBar!\n");

1 c: K% m1 w- C0 _- Y' h R3 X

6 i1 D& u8 z2 T+ L

$ A3 s0 h3 m8 j% r. I: V4 O

return -1;

9 `, Q% |7 f" a& g1 X

: T q" y* V7 a

}

. z3 U; t# E5 v

/ a- j y" ~' H1 S& e

7 r: _8 j# y3 |7 h8 N. o

---- 通过中视类操作工具条IDR_MYTOOL,利用ClassWizard为其 消息

" g. m. K/ U9 G

ID_FILECOPY新增消息处理函数OnFilecopy。然后在处理函数中加入下面程序。

$ p6 g# a4 U0 {5 M# o* U

/ ]% f6 N; p2 K/ A+ e) t

void OnFilecopy()

% a+ e" c: E& U

{

0 b6 U) \1 d* O3 ^ Z0 Y' ?

int nOk;

) d3 v: i/ Y+ T

char strSrc[]="c:\\dos\0c:

* k4 M$ V3 U1 P! s& i

\\pwin98\\command\0";

2 W7 w3 o1 U, t9 p

//可以改变源路径

: o. l7 T( X. `; v3 C

# M3 w* K' R+ y a7 z

char strDst[]="c:\\temp\0";

; c4 A9 r' L8 J! S" V5 o

//设置目的路径

8 v7 I: i/ N$ V9 K. _

2 Q) r: p2 `/ @2 b

char strTitle[]="File copying";

8 h7 I5 u2 J2 w; N+ ~/ m5 ` s# D' X

//进度题头

1 P% I" x1 B0 s! M1 T f& I/ }

2 U& | Z# Y+ a- F( L: @

SHFILEOPSTRUCT FileOp;

/ D6 b/ ~' }: I6 G% x* X- _

8 K/ y( X; W# M& H

FileOp.hwnd=m_hWnd;

3 `7 o- p- f0 _2 k# t; N1 H

1 C/ `1 T& h5 c ]) D1 `

FileOp.wFunc=FO_COPY;

1 h- l5 d* o" j

S p3 B8 P/ T7 a3 |! X2 ]# p# _

//执行文件拷贝

j! }3 i# [+ f$ P- B

! ^' i* E# n2 f/ R

FileOp.pFrom=strSrc;

$ ^, L* i1 ]# s1 g

3 J) _+ b, o$ ^, R; d8 J

FileOp.pTo=strDst;

3 c+ i- R$ M% s5 E, M. b

' P/ H5 _! D5 [( Y* W

FileOp.fFlags=FOF_ALLOWUNDO;

1 r3 i, c: P# ?' `" W% q& D* I

7 F' r* ^$ ]0 Q9 D

FileOp.hNameMappings=NULL;

' ^& ?; d! f' I' f9 f' h6 M

4 J# P% x( [1 X3 b* B

FileOp.lpszProgressTitle=strTitle;

. Y. k/ D! D5 s

6 Y, M. |5 V( `6 E' p& [5 I3 y

nOk=SHFileOperation(&FileOp);

, F1 {! z0 M+ t& h4 ~+ q0 P

; q* z4 g5 I; }% W

if(nOk)

{7 o3 l4 c+ m

, S$ H# M% U& R: d" ~# f$ x

TRACE("There is an error: %d\n",nOk);

# c$ p/ c- R. X, w2 s2 @

$ c/ ]- U7 P) B1 r0 _# E+ F8 F

else

4 o0 a e% r2 z4 G q

6 Y, D% \$ ]; f8 L

TRACE("SHFileOperation finished

3 S3 V' w. f# G; F

successfully\n");

2 h6 r$ a' M w p# \

9 e+ |: U2 o3 }7 H

if(FileOp.fAnyOperationsAborted)

$ `, F) E; J! ~) @1 N; m

5 `2 J8 ] Y: I7 _. S; j/ m

TRACE("Operation was aborted!\n");

: _8 u2 _ J2 U' u5 j- K. }) B

}

0 \ l. v- \. m' _$ W2 v

0 `' {0 @1 o9 S3 s f& Y

4 J2 ?- }3 S* f9 t) | Z4 y3 L. D

三、 结束语

. c& Y# F Q, S6 g8 z

1 i$ X0 [- [" P0 N: r% q) U

---- 利用Windows API进行程序文件操作设计,它直接调用Windows操作系统中

8 q. z5 K" n2 A2 o6 e

的外壳,它的处理过程与Windows95/98/NT中的处理过程是一致的有利于我们在

6 Y7 a3 S% B; G( T5 K! f7 y

系统程序设计中保持与操作系统的一致性;同时,由于在文件处理中它是直接调

5 }+ _/ w: r/ y6 ~( c5 T3 _

用WindowsAPI函数,因此不需要其它应用程序动态链接库DLL的支持。

) v! W( x9 b2 [" x' r

6 W* h( y2 R! p* Z8 K, P9 ?

---- 在各种开发软件中,都提供了对于文件的各种操作方式,但是它必须利用

! ]# s- Q2 h9 j4 U; z0 M: k m- @

到文件系统较为深入的知识,而且对于其操作的直观性方面也需要开发者进一步

( i0 c6 L8 R3 @

地设计,因此利用操作系统SHELL进行程序设计,不失是一种好的设计方法。

zan
转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
您需要登录后才可以回帖 登录 | 注册地址

qq
收缩
  • 电话咨询

  • 04714969085
fastpost

关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

手机版|Archiver| |繁體中文 手机客户端  

蒙公网安备 15010502000194号

Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

GMT+8, 2026-8-11 10:56 , Processed in 0.578175 second(s), 51 queries .

回顶部