QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

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

d% A$ m# E# `6 G

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

" M" x' Q, V, I! x4 f& c5 @3 ?9 } O( e

张明武

' _: B2 C0 z( \' j

+ x) `9 @* ~7 `( V( j; s/ y7 S* j, D

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

) Y Y( E# q3 u! r& ^3 O# ]

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

9 k- k3 @* m/ Y# X8 R# o2 H

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

9 ~ S9 q# p' |) F! e" L9 i* [! I

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

7 ~! y5 Y5 q$ I& H

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

6 @+ i7 i- Y: H

+ g" ~) `- v7 w }1 a8 p

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

9 N" m p7 j) s9 Z9 v4 N

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

% }! _+ e* W% X

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

& |. P; h4 i/ p* G

7 V: ?' W' J+ p. c) Z1 _3 {

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

$ ~* X$ ?3 T8 { C1 ]

文件的拷贝操作。

8 A9 R ^9 w- Y# X! _4 Q$ h

" G1 {9 v) R% r2 {. `, V4 p

一、 原理与结构

5 T' m1 [; g4 T, \. O, V- m' k. i

. b* j# ~2 Y/ X' p2 L. A/ N# D

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

2 ]) I9 q) D+ S; G; Y( y! Q

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

' j3 q9 R: ^1 R8 k, @$ w

2 d1 V+ y: H- n4 r' z2 x

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

5 K. i3 v) z M

lpFIleOp);

6 c! ]4 d4 }( g+ g" ]

. v1 W$ e- M! X: h" n+ ]; U. P

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

9 T5 _4 V; F0 f* A

下:

! `3 B( L. q: o- C! {! E" {8 K

0 V8 J* z" `% @* l. s) e

Typedef struct _ShFILEOPSTRUCT {

8 _! V1 m( A h3 D

2 i1 u: L$ l+ K5 r% C3 |- Y

HWND hWnd; //消息窗口

' }' G/ _& k5 }+ r1 ^( k& y

( o; T, j% S4 X

UINT wFunc; //操作类型

5 U" l2 U5 M* e0 e

7 p- g7 ~5 g, x" N: I

LPCSTR pFrom; //源文件及路径

( N. U. {# f! |# C, R

+ _+ q$ s7 v" u* X

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

; R1 l0 e1 i9 }3 [- F- \

7 V" v% h9 J" I6 t( O/ f. L/ v

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

d$ t" L& }5 L5 B3 m

0 T1 B4 @, a# u& R

BOOL fAnyOperationsAborted; //操作选择位

9 ^3 ?- K$ E0 k$ w' v6 H" N0 j

9 j x2 B5 o9 J \9 p: Q7 B# @

LPVOID hNameMappings; //文件映射

7 p* I! S9 d$ @6 ]5 M3 C- Q) k p u

/ {5 r6 x/ s; _. [: g3 R

LPCSTR lpszProgressTitle; //进度窗口标题

7 l, m( q/ U2 R

$ a0 G( e9 b. ^; Y

; o/ h8 k+ H2 {

} SHFILEOPSTRUCT, FAR* LPSHFILEOPSTRUCT;

$ N" P/ ]. \' V" Q' @

: P# E; Z5 W0 i

: T, |- U' i7 L0 j

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

9 Z" G. [7 ]2 s& [! l9 _5 j5 N

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

9 [6 Y5 H$ @& Q# h0 q& G! |# I

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

7 Q1 Y1 X, d& w0 T2 C% e3 D. C

个,则应是:

6 y* f+ q+ J* A9 \

0 f" q& B# a. |6 @6 w$ |1 R b! g

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

% K2 z+ ~) Q) A1 t7 P8 [

a- n; D r4 q$ o; b

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

8 Y- f: ~ \: c* {4 d, X" c

% ^& n0 c) v5 q8 h% @5 f/ k

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

8 m+ W$ G/ d* y

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

& W% O) v4 |; L. x0 Q3 I' J8 x8 Z

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

+ _' [1 R6 o7 w3 ^

6 o$ {/ B: f6 k$ R* F2 y" b: d

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

6 j. ?. E/ j {1 a* J8 k' c

9 G3 [$ A9 N! I, w0 V

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

$ v. s' k( C3 X7 Z# M# B

! H) q6 O* a3 z0 U+ I' P) [

2 O. C" F) \# y% c# t" }

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

1 H- [' c d$ K9 L& ]* e7 N0 F

- j: j e- | E

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

/ X6 c6 M8 R! m5 }3 y, c4 C/ Z5 p" T

! G, m+ L% `6 M- Y; o8 Q! x9 t

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

8 c# n% [) f5 J* l

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

' d N0 o+ R9 W: I- h, F

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

9 B$ B3 m& s% c7 h) _" Q: q0 h C

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

' y. a1 V+ N k: c2 k2 G

组合。

& Q8 n% @# t! k% I2 [4 g

7 V/ p; c! h; N0 I5 D8 r

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

; Q8 |1 [' o' @: q* C1 w

) w$ t* K0 ^2 k' ~* A1 ^ v6 Z8 \1 ~

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

3 x3 }$ z4 l& X: y, y7 A1 _* h2 J

1 Y7 {/ w6 {4 _7 h

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

S j" U4 u! K6 w9 o

候,如

$ i* u3 g* L/ {8 l! L8 U7 f6 d

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

" f2 f* u5 \: p2 T- O% d" H D

此项则

6 V% w$ ]. P* n" ^7 c: q

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

; c, W1 G: y2 c) I9 L* y

$ A* i! P6 \; g3 A. V8 Y/ o

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

* E$ ~7 V+ k+ o# ]. n$ `

现错误

/ d% H! g+ c) H5 }7 ]; W

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

/ i3 D, [4 X( W

) ]( s5 e+ z, E5 C8 w

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

* @ y5 N; p. v, U# Z3 m g

进行更

0 [- g+ t9 R/ {: K' |* S6 \

换文件名提示。

* E3 ~5 W: w$ O) O) u& ~/ A Z) i- B

0 c7 k" M1 o5 D& }% @

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

) B: c* l; y2 u6 K# |, m& _

! S: _/ R( r6 g+ A: I7 F0 e

---- FOF_WANTMAPPINGHANDLE: 要求SHFileOperation()

. \- a( v3 |7 A, T1 m

函数返

G% S0 s. D% b

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

* [. G# u* Z) k5 M7 U' _

- j8 u0 Z# w. z' t* }/ F

hNameMappings成员中。SHFILEOPSTRUCT将包含一个

% e3 E3 `1 @8 `: T9 `5 ^6 [5 H

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

9 @0 G+ y* o) c

个处于

m0 d m& u5 N2 |7 a+ R4 Q. N

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

; j D8 M4 z; @3 }

6 Z- u& |, z1 I: t: @9 V0 N

二、 实例操作

4 ] P3 g" t9 I! K* D

4 y3 O; `( F8 M8 I- _: a6 Y

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

; e- Y$ w1 s9 _) ~4 s

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

3 B$ L2 [- u$ b `2 h% Y

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

- N$ r4 w' M( `

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

X9 U; K3 o# H" f% Y( V

1 f5 c4 f! d( y5 M( V7 l9 |

if(!m_wndMyToolBar.Create(this)||

' G: f9 j0 \+ A; D

% `* E6 ]* \! k v8 o3 K

!m_wndMyToolBar.LoadToolBar(IDR_MYTOOLBAR))

9 ^8 I" L: W2 w3 a# `& a

3 X: |( o# M a7 P8 U

{

- [5 u. k" s9 K

, c8 ?+ F3 p3 P. l" `2 }# U

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

% E- | m4 C1 Q4 u g2 |

; Z, K8 y% K/ S

' e& _! V( C7 ]2 z, f$ s

return -1;

9 A4 K3 p2 t- D2 w( R* F

' T+ T# V2 j1 Z v4 B

}

, h. a$ l: L7 W9 ]/ t7 ?' t6 l

0 W9 W$ z- Y# r5 j; ]$ w

) h5 ]5 S5 ^! }6 H0 |8 ~

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

6 E* R$ n5 z. |3 m7 M

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

: l e0 a! ~8 l) C S' l& }& v

# f: H; e/ s; u# g: R7 \3 q: C

void OnFilecopy()

( B u/ Y- s. ~8 i- X2 |

{

2 }# W+ V4 O. b5 {5 V% T

int nOk;

- _: V* p5 H6 s5 E: I9 [# j

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

# m8 h* a( [* C& L1 g+ y

\\pwin98\\command\0";

. n0 u" V: h" B$ K' E$ u( e

//可以改变源路径

5 E+ d! m5 M3 R! H& m# Z1 X

6 h/ B& X4 n i# s1 P$ F

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

& \! R* ^5 U& p5 P0 E' r. S( R% T( |

//设置目的路径

& _' t3 V% C* s& |4 F$ A

, E1 m4 [4 W% X' C; K

char strTitle[]="File copying";

/ D1 g" ?& G* k2 K# }! [3 p0 n5 M

//进度题头

, ?9 O( j; o5 ]# B

! G5 v+ ], y# s! v, B8 W

SHFILEOPSTRUCT FileOp;

1 K2 [/ P* ^, K1 q S5 U3 P; G

; R: p! e8 l4 x' S1 Q

FileOp.hwnd=m_hWnd;

/ W8 C: c7 k4 r: d

! J3 W" Z6 ~9 ?; U/ c- k! L1 o

FileOp.wFunc=FO_COPY;

}1 l- b% E5 k$ b& ^6 R m; F7 X% Q

" ~( Y5 p+ Y) S# K8 e

//执行文件拷贝

. E% Y& P( w- T+ \* S. z

z( V% M( f6 q9 L

FileOp.pFrom=strSrc;

" x2 Z9 a7 V% V1 M0 _

% ?. ~; U0 i& `

FileOp.pTo=strDst;

) c U6 l/ m3 G' ]( Q0 ]1 E8 O v+ X

0 H3 R$ O5 t2 u% `

FileOp.fFlags=FOF_ALLOWUNDO;

+ Z( u1 V" p! K2 Q o

" l7 V$ S6 N# l I

FileOp.hNameMappings=NULL;

, [- N: ~3 g' O+ x- T, {9 A

1 Y3 G! q; A) T! k3 M

FileOp.lpszProgressTitle=strTitle;

K, E2 r7 [0 g

0 a$ y9 o! |) }9 F7 M

nOk=SHFileOperation(&FileOp);

) y, R# J. j% `% V& g

4 o3 s8 H1 x, j. x( e

if(nOk)

3 t7 \+ G- ^- q& Y2 I: V4 C" O

2 e" M/ |9 ]6 H, x$ [, v% P1 n

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

' G7 F C4 D; B

& A( G! Z' t8 Q& x9 L

else

' y$ o. Y1 y3 ~9 [( k9 h( F+ k

8 F& F" w! d$ [1 H5 e5 l

TRACE("SHFileOperation finished

0 t1 o* N$ u# n( o" m

successfully\n");

: C% H4 i; B* w

6 m" V& F3 J V) @; E

if(FileOp.fAnyOperationsAborted)

2 b$ v' ?% g8 Y6 C- d% w5 F

d7 n7 \. P- e( w, i6 z

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

" c; N; ^5 x. s

}

d+ L: Z5 R, {( ]' Q

& u5 M* S7 X# P# _

, ]0 b. C$ ?) Z0 ~2 ~# {$ f1 n8 V

三、 结束语

6 ~. a7 e) y. e C# }

4 a2 F( ]3 u. ~/ w

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

! p; d2 D% P2 U3 x x% d

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

1 g$ i5 L, o( D8 z0 c1 b" }& X7 t

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

: a5 u0 p, w! ?( t4 f @; c. k0 J

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

1 L8 e3 E" d; [. {% D

$ e- O- J& ]5 C1 N# h; H5 E

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

! [: D6 H; y* ~" u3 b4 X& k6 U

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

- Z5 C; f6 k, q5 d% G+ c8 @

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

回顶部