QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

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

9 e7 y6 C" g% W& h4 {$ e3 z

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

+ @9 D' a" w0 p) M+ @

张明武

7 S, n, D% N- z" N* q! b1 |8 P

6 `4 ]! m- |, D. ]+ C3 D

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

/ o3 F- X, T$ A5 ?3 X2 p% Q/ d" B

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

* M2 e; r9 L6 W2 W) E S6 C

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

# r a2 G: c+ v

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

! H2 V# T; T) L' L

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

+ u' P% a- x) O

' S3 G9 o0 x3 W5 R! N

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

+ c. ?1 k' A$ A0 v2 O* o$ C

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

8 B7 Z! w9 X6 J3 X# i

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

3 x# B) z0 u' \" b5 ] O. o

" C, V* q# h/ Y

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

* l& q( o: p" O1 ]% y

文件的拷贝操作。

6 [" A5 s' }; R: G

7 z8 S% W6 Y- |* V8 C

一、 原理与结构

7 N& y$ S% G0 c

. i$ L0 D* g6 m+ F! N

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

0 O$ w: y& y6 c" b

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

# L; x0 R. W$ V' C, k/ k7 z6 X

7 W g; |3 D9 |5 M8 I

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

4 x/ Z; N# j" O1 I. V

lpFIleOp);

# E- n4 h+ G% H

& K3 B# T8 d6 u0 C- r: n; r4 ~

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

% q* Y- j7 U S( _: `" y, n! {

下:

$ u! C/ C/ |, x

# n3 _+ r0 U! Q2 O5 w$ C. I

Typedef struct _ShFILEOPSTRUCT {

1 F5 o, Z7 g/ M% q1 @( J/ A6 r

* K6 X: ]$ D* h& E% X$ o2 }" Z) S6 g* N

HWND hWnd; //消息窗口

; B+ f. Y8 j$ V: w- f

) @7 [* ]) h( x/ Z) y) z1 ~+ X. B

UINT wFunc; //操作类型

1 s4 X5 E6 [8 Y. d

1 G) _! o4 E" S- F8 X7 ]9 ?* _

LPCSTR pFrom; //源文件及路径

# P; L: ?# o( T0 p# @5 k7 a9 y

/ X5 V! A j% n3 [# s4 N- ^8 i( ]

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

D& ~; J* m: y* @# s

% E9 G) g! T/ g0 f: A7 Q

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

7 p e3 G. [. A9 l

6 I# Q9 J, g) K1 y3 y. @4 t

BOOL fAnyOperationsAborted; //操作选择位

9 l: _ J0 H; x5 q& Z8 i0 e4 `4 n0 Y: e

, q' z6 ~% D/ a# g

LPVOID hNameMappings; //文件映射

. Z! N3 A! t8 z: W0 o

# P9 f% Z* c& O9 Y$ t" _$ U2 e

LPCSTR lpszProgressTitle; //进度窗口标题

. T" r4 N1 j }& ^+ i1 Y

1 J& W/ d. f- T: p

3 W# O% v: W% [: T5 B3 H& A

} SHFILEOPSTRUCT, FAR* LPSHFILEOPSTRUCT;

* `: [ y, s: \; Z9 v7 r1 C2 \

, m1 \* F+ C! w' W' F6 C2 [

3 |- G* U( `( D! N! t

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

3 n8 h& Q2 @! s+ C- V

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

2 A4 D6 ~1 b( M& t; |

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

# Q* U# ^0 t7 W

个,则应是:

# V# _; d* v8 z

$ L9 j- t( [& } ? p

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

9 T! l4 `8 w- _3 H8 b

, g% z" u: [8 ~

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

: o* I0 ^/ C3 S% N1 T9 D4 T! Z

4 J6 U2 P, e; H3 M: T1 y, A( `( f+ Y9 B( f

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

; t( F5 u6 {- i

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

( c( L0 z" v7 n! A3 X, B

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

( \7 a' \, F4 Y ]

{% Q' U( L: Q& W4 y; ^% k& s4 I

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

/ Q) g/ Q9 V, q; y

. o+ J m7 a8 S! R

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

6 P. _% P# X+ [* s7 B; V

* k2 U/ V; j3 v! E( N1 X

* r J# A g3 G1 J

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

+ Z6 g8 q) U$ i) H9 P

' y% u3 a2 r( n! S% b9 z

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

, i% Y7 ]. v9 X9 c0 J9 v

) G ]) h- {; O+ b. z q+ j4 o

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

3 f, b; V$ Y% L3 t& X

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

% u% H# f6 H8 }+ U/ P) D+ U% o" n; g

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

* A. z9 v) w. w' F' j

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

/ V) G1 N4 r5 r

组合。

7 a* l- U* N# U- o6 i

8 B' f% r# l8 ^6 n4 Y: h& F8 w

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

9 R: t" i% w/ a6 o# z* e# b

, p E" J' I& v5 t

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

" ?7 t" Z6 Z6 v E* B5 Z

E- i. ], _2 y- `/ D

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

# n5 c v# B8 g$ Q

候,如

! n% l( w% v2 x% [; y

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

# p" @$ J L, ~( K$ D& s2 W

此项则

) j( o7 T0 w# e

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

$ n: A& u: E4 j0 K( J5 G; [9 ?7 ~

/ K3 q Z4 ]3 U5 c5 S+ t' H [

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

/ C4 Y- ^7 H" m7 f& A( K" U

现错误

" r6 q5 | z& Z4 t9 \

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

6 ~0 i, J. V4 w1 k1 C! {, w

& M9 w* R, B5 w1 [" F

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

8 t2 `5 ^4 I* \0 z

进行更

, \3 k" N/ |8 D3 z* ~

换文件名提示。

- f& _, r9 w1 W$ l

1 G% G+ Z( h0 Z. E

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

9 j$ `# v( m8 Y4 V

% d8 t: o$ Q4 X$ R) Q

---- FOF_WANTMAPPINGHANDLE: 要求SHFileOperation()

8 S0 d! \, r; Q: `& T C

函数返

; F0 s. ` ?. Y6 h o/ P

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

% I P2 N: r6 t5 n( W- Z

, S, U" p; v ~6 a

hNameMappings成员中。SHFILEOPSTRUCT将包含一个

/ m; L) c4 c7 t) M: k( e

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

( u7 E, t- J6 y( q- G; t

个处于

' ^& m+ a5 `; r4 T5 m

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

i1 p# Y5 W; q" N/ h1 M0 f

7 a0 S' a" R3 [) s

二、 实例操作

. a: O, |4 r5 C+ k- K. k3 ^) v

% Y. n# R O5 Y( b, ?

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

& {5 }7 E* T7 I0 D. m0 R# d7 s

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

* w2 t; O: d7 E& [

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

* s! J( R5 ` V" h) c# ]0 a

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

/ l" z1 i) n- _! y$ J9 r

. B) n- p4 d# D/ b5 W9 s2 R9 w

if(!m_wndMyToolBar.Create(this)||

- E4 ~+ ~8 a# v6 R0 ~

2 Z! O3 u, o l- H v

!m_wndMyToolBar.LoadToolBar(IDR_MYTOOLBAR))

( l8 r, ]" q3 A( d: ~2 n( @6 w6 ?

5 Z2 A( x# i/ a) H

{

/ r4 @3 E& { w+ T

$ R$ S' m6 m+ b1 S$ ?/ x/ ^ X

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

# ^) V4 E* Y) E# q7 k

6 C: V) I: D' G: _, U2 z

7 q7 C5 T ], }% c

return -1;

. |' V# s, c8 G4 O* _: }* z, _

& V- [/ p; B/ \2 j* ~. a

}

# S* y* K. D/ E( y5 g4 e) f

7 Z [8 E5 B5 }( P& X

# S) K8 W8 x' S8 p) o0 u" b

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

8 m) s' `6 G5 T

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

( K4 C- V5 X) ~+ e4 O

4 T& @. g! S" U' g

void OnFilecopy()

4 ~, N0 C8 C) q8 j7 b* R, d% q

{

3 L; b: @( ]/ O. ?9 D" e$ x

int nOk;

# q- a- f/ |" I- L* |. h$ {6 s

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

# X6 r1 p7 t, b+ O4 O6 k! f

\\pwin98\\command\0";

8 b; Z _) V: A: i: i

//可以改变源路径

; F/ z! u- H7 H2 I

$ N% o# P# Y/ y* v5 o

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

9 }8 L5 q* x9 @, O

//设置目的路径

# P: z2 H3 E% ]% q# `' ^: n

" I5 r2 ^3 `0 s6 h& o0 k& Z

char strTitle[]="File copying";

7 L7 M, ^7 F0 q2 D. H5 x d

//进度题头

( G& _6 L, p; L0 U; i3 T' D

6 i8 G# Y6 m7 s8 Q4 `! H) D+ W* T

SHFILEOPSTRUCT FileOp;

2 _; R; U3 A% j$ t

7 f% j* M q. K0 Q |5 u

FileOp.hwnd=m_hWnd;

7 d* T2 s/ e/ [

0 ~( D- P- \4 T* v

FileOp.wFunc=FO_COPY;

- O% ^& c$ ?, Q$ r t) m

3 N3 ?4 M) x+ v0 Z7 A3 ^

//执行文件拷贝

7 l3 R. ~0 }8 ]3 L; l

) m# h9 p, w0 Y7 u6 X

FileOp.pFrom=strSrc;

3 k( ~1 N9 k0 c9 z0 B" D; n4 n

6 P' q" ^1 \1 l

FileOp.pTo=strDst;

, d. V5 f- x$ O% c9 Q; }" s* l& v/ z! Z

9 [- i7 T: ~. M) g& t+ k

FileOp.fFlags=FOF_ALLOWUNDO;

* ~3 A) k1 \. u

. ]4 }- n5 P' H0 u

FileOp.hNameMappings=NULL;

* O' v7 ^+ c- E( q

5 |. w& E9 r3 d! V+ `: L, v( n

FileOp.lpszProgressTitle=strTitle;

K! h; j& C0 C) K s& R

# b: i8 \2 Z, ?& a& Z; c; ~

nOk=SHFileOperation(&FileOp);

* z) Y7 I6 I9 u* T! @

( ^, [- M8 E B& B: z

if(nOk)

$ O$ s' y# a* R9 T9 E/ n" R# Y

9 F) P. ^0 `$ @+ @4 L' x l- r

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

) E8 Q# ~1 I! G3 ^/ ~

& G& v1 C! D3 n6 ]6 Z! w

else

, C3 r* N/ [$ I1 x( k' s

9 I* A7 ~- s* q9 f; {' R# l& K

TRACE("SHFileOperation finished

* k5 V$ \6 `* k* x) p" F3 N

successfully\n");

; e) X3 e' Q5 J

: E: ~, G6 @, i' u

if(FileOp.fAnyOperationsAborted)

% R& T5 o, k; y, w+ y8 t) v" t

( d* U, f9 Q/ |4 R d" A1 \

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

3 N( G* _$ ~2 i4 p5 [5 ?

}

) d. t" j. b" O: _

" @0 Z" N a6 w+ E6 x; ]- i8 u

) r$ e0 S# o: ^

三、 结束语

- ?2 ~. p: n- P3 w0 i

) f+ \; ~0 H. E6 O H7 [" O: [; R; w x

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

* v# P1 E$ T3 Q p

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

6 W4 r/ s6 J# m* w

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

! \8 V( x+ w! @5 u

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

( ?- T. ?, [3 k! \- h C! d

" {" P' ^ N% A/ I; X* B2 k

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

: O$ G) C1 W' d- r$ t, H

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

1 v2 [8 a% t* {1 @$ X

地设计,因此利用操作系统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-4-19 05:54 , Processed in 0.338313 second(s), 52 queries .

回顶部