QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

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

6 H/ D& X: a6 i' S, Y* \2 w( S9 t

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

6 Y3 X" w0 n: Z- N$ R

张明武

# m m! O9 S- o! c

) n% z6 t* L" x, O

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

9 i* B) ~* H7 [0 {* ~3 x

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

; |. d8 J2 w/ n) j/ q+ X

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

" n' K% R4 y# [3 N+ f

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

, s# O% l: Q3 ^0 v: Q9 P2 S

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

1 m. S9 l- M& k1 e

. e% ^. j/ J/ K' f( s" @3 |

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

. @0 I1 c2 i! @2 V, C7 _; q

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

' ~/ k! E3 }- h

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

; Q o C3 x8 s/ |3 I6 c. j

. m' w1 F$ t& H# k

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

E7 ]- m ~7 d5 e

文件的拷贝操作。

[2 u7 s* c/ f

; B- O# r9 k( \8 l

一、 原理与结构

7 [" R* I/ d4 y

( r& E. B1 W$ P( A1 k% } t+ L

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

' T# z. d' r3 `/ d4 d: Q

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

( K# M! k, Y8 I6 d' W$ ]/ t

5 e5 T0 ~( O1 f) q

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

6 r$ t; {1 \% R5 x4 z/ D2 v

lpFIleOp);

! F# K$ S. p2 z5 c) C0 n3 Z

& k. M% {( h* e4 R e U

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

% F# o F1 t- S$ I

下:

; {. ]1 k3 k3 E. ?/ X. I( O% A2 g: M

% Q# o6 g' o& \/ X

Typedef struct _ShFILEOPSTRUCT {

% o: p' A0 @. [8 r

$ j- z, `3 _9 f0 C

HWND hWnd; //消息窗口

5 v; m: }9 M9 o- X

1 D1 n( b& h4 Z$ y- c4 n/ I0 h

UINT wFunc; //操作类型

4 x7 k- @& A n+ k

9 M$ c) n, L8 q7 _9 D3 j: [* s

LPCSTR pFrom; //源文件及路径

2 z, p( J c" g

, a @8 W% j! s% E

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

9 \ S( s, J6 G3 `" j+ l+ q" V

% g6 k( w; l. O0 |) O1 j- c

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

e7 r0 ~6 F9 \) a. A$ k, \6 d& J* ^

7 R0 b$ r9 C D! F4 f$ B

BOOL fAnyOperationsAborted; //操作选择位

: ~, v) L8 ?0 d6 v/ ^

. V+ F, z7 ~# M I

LPVOID hNameMappings; //文件映射

Y4 P/ ^9 v3 F6 X0 o

) u, b4 m: Q# [1 p' Y1 U

LPCSTR lpszProgressTitle; //进度窗口标题

9 R0 |+ v7 F5 ?- l& N! G. x

; A! u- A6 q8 M# }. n8 j$ \

a* O# \( ], h8 t t, L: C& n

} SHFILEOPSTRUCT, FAR* LPSHFILEOPSTRUCT;

: `( H4 i9 u! u9 s E5 }8 E/ r

+ o+ F- K8 |& E+ V, Q# m' F

* C- l. W- g9 `/ Y. C! i; X

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

, l% j; a" E; c; F

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

) U3 \; ~, Y, [2 z

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

$ k, e0 B$ o/ p# x# O# D

个,则应是:

" ~7 E7 h ^% T7 w6 L( \: w

, @- z1 E9 S6 ^9 B9 G

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

4 v' K$ j, F- f K H( d5 J2 g

5 b* \( p3 B! _6 ^6 t" `

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

, @4 t' @, m: D" a3 r

6 K# ], Y5 j8 p

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

- ]" F( }9 N* E7 ]9 A+ e, @

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

# T6 x+ Y6 D& m( W# _) ] Z; y

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

; R7 }0 M. J2 f; n" A+ i/ w! t

" c; w. ]3 [& T! d

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

' ]4 n2 m9 _7 i6 a( j4 p1 U: m# a

7 d9 `0 O9 x1 {" w

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

7 h9 C% h; B3 o8 Y$ o7 W8 S& P

0 @" Q3 p% c8 c' w- ^- P# t

# z" X9 a9 g8 u# A8 Z

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

, \3 e: o# F2 H

5 c/ U2 D3 q+ x3 M- v- B: `

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

M7 H, e5 U! a

' F# ~( s2 h7 q( ?, V2 A

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

4 Y( l$ @8 U3 I; S# b+ s0 O

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

O8 |6 }& u2 @! z1 Q

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

+ G! I: R( W9 f2 p

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

5 i; k3 L4 Y# T9 l) e& s

组合。

# c# W6 }2 c5 Q# \7 H2 Z. Q

( P* A( ?# d5 e& V

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

1 h2 _& O/ b3 Z, f$ j

4 c: {% |2 T" @0 `

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

% k9 V! l$ b8 W

2 Y6 p, p; W: ?* Z& o% \6 ?

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

4 @& j/ a _1 s6 J

候,如

0 z7 Q% w7 Q) O4 G, T6 ]

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

. H7 R9 o" z% V- q4 Z# D

此项则

; g1 w" Y- D8 H

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

6 P0 |% z4 G+ N7 b6 I$ |

3 r( f; d5 b$ E: T% h

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

1 V( r) `4 m7 s+ c" E

现错误

9 m0 o+ |6 L5 v3 ]

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

) g5 t% | {" _( J ~- \( P! Q

# G# h0 K) R0 O: O' b% p. d$ F

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

5 d$ q1 R0 u/ ?6 G

进行更

8 b/ v! ~ r; b9 }

换文件名提示。

% S+ \6 V, D, h/ i5 p1 D- Y& A

6 `! r! J) Y k9 d7 D1 m# E- ]" H/ c

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

8 R' L+ E0 U' k8 [

3 ?# u" z1 n: O0 U

---- FOF_WANTMAPPINGHANDLE: 要求SHFileOperation()

7 Q2 U6 q: \" I# I4 ?. z

函数返

! f- ?$ q7 D( \" N/ x

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

# q7 J! M* u# {$ P, l

; O3 X1 b8 _' t! d, {

hNameMappings成员中。SHFILEOPSTRUCT将包含一个

; T( y/ \0 p" a& j; k7 D, v# Q

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

" J! L2 _- O4 U9 ~" N) i) W$ k

个处于

3 b6 f0 i& T3 H

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

' S3 q# H8 t- n4 v- H) P

: K7 {2 L N' U- z3 Y# a

二、 实例操作

& J: i. u% `7 d' Z; }2 w

% D6 G+ `! h# m4 _- D# ?7 c

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

( y4 X9 [2 f; |. M& }5 d* i

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

: s3 A1 f9 n3 Y6 z

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

- r1 x2 m" M3 w9 L

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

3 l U3 h$ g; o' d6 R

7 A$ `& t/ U% k( [

if(!m_wndMyToolBar.Create(this)||

! E; M- j6 o$ D

4 l. O, D8 Q6 B5 d2 q0 @

!m_wndMyToolBar.LoadToolBar(IDR_MYTOOLBAR))

; ? x0 b( d9 M( w- [

; ^% c' Y k* h. m, ^7 g( \

{

2 E' T, \6 o7 h2 t0 I

' X, U; C. p! Q

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

% f- ^) v9 y0 F# @; G0 \9 o

0 y5 E3 B- g5 l0 D. E8 i B

% y7 D. f0 J2 O% Z t* Q; G

return -1;

5 ~) C0 u" W9 ?6 A- n

- o [" }; H6 _% C

}

( @7 H7 f2 i% ^# s1 C( R: n/ f" O

# q, K) [& P1 W0 t9 L

( B( ], r- Q0 D& E# J" p

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

" Z$ M3 M& @, I, r; q

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

1 i; g, S8 @# H( E2 y$ c4 S

# E" t# w0 j- ]( n

void OnFilecopy()

( m* o- ?. @" n1 J9 C, ]9 H

{

' b/ Y+ E6 o& Q5 t1 y3 |3 }! s

int nOk;

0 n; F/ t* J" H1 w0 M

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

% s6 Q5 K7 H9 s

\\pwin98\\command\0";

6 Q# @& T1 ~/ p- o: I

//可以改变源路径

9 d+ I! e4 l; P6 ` I

9 M' y5 o. \5 G* O, ^9 K/ n

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

8 C* r- {, u5 D

//设置目的路径

) i0 Y1 ]& |# Y. v) Q* A

8 ?* {3 b; y; y: E5 r9 v: z! Z! k; ~

char strTitle[]="File copying";

0 h1 O' p2 a% R

//进度题头

# |: `- b4 O% Q: O# g, {

! ?' k( ]5 c( b4 {# l) f

SHFILEOPSTRUCT FileOp;

8 n; U3 ]: M; U: X

2 ?9 c4 o2 ` u

FileOp.hwnd=m_hWnd;

$ C3 c# a" E, I- F( L! Y f

% C% H2 O; q8 o! ?0 {" w7 q

FileOp.wFunc=FO_COPY;

# E7 s) B" d7 V: Y5 ?

4 v8 I/ p2 A3 H5 @

//执行文件拷贝

; w( H4 x* L8 r; t( e

, }3 I0 w& \# d: Z, o: W

FileOp.pFrom=strSrc;

1 s& W& i/ y m) {/ M6 [$ I

$ F, `2 G" a; H9 ~

FileOp.pTo=strDst;

9 M; u( F2 O. T

z1 k8 t# S8 e, M0 L! c

FileOp.fFlags=FOF_ALLOWUNDO;

, o1 E/ C1 k1 S+ N3 b

8 @. o9 ?) V& T+ W7 b7 n

FileOp.hNameMappings=NULL;

& U" t* w+ ~) N; P( b/ s, y/ U

3 e! M2 n1 g2 L6 m3 [

FileOp.lpszProgressTitle=strTitle;

, w& n4 E8 Z9 F

3 x [/ x; i% V. A

nOk=SHFileOperation(&FileOp);

1 j3 H. C3 f7 U/ t

8 h* Q' H# k+ i3 y) r

if(nOk)

! H$ T6 \3 J5 ?7 n

% O8 C: i) c! L* @- N

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

: D5 ~/ y( W4 X5 S# ^5 q5 P

6 V, @0 Y" e0 r/ i* c! V

else

h3 I% X; y5 w8 b* K

% k! u9 I8 c. T7 e2 v) V

TRACE("SHFileOperation finished

1 M& I3 Y. s0 q7 }7 B, x0 }

successfully\n");

B5 L- f. L, E/ N3 G' x

& c9 `0 i6 A, x* r( L

if(FileOp.fAnyOperationsAborted)

, N5 y7 L# d' }3 c

0 a) ^7 g2 _% H. k

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

p9 Z$ W: H0 k, R( j2 ^

}

6 W& s4 H( I, I7 h

0 | W6 ^' b7 W

5 T; H; r# R+ w+ f+ d# o2 ~5 M

三、 结束语

# B, f0 K( P4 k) F$ G# L8 ?% E

$ f/ F" P; C4 s% H

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

" E+ t$ v6 U/ H$ S; ?

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

9 O- ^, |6 d1 m& g, O# A* o7 |" a

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

2 `8 x2 q/ H3 ?

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

$ ?* |4 a3 |8 v* g1 M( b

* [6 M. d! ?& i J/ \0 E/ f3 F

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

' \4 _0 z( G* e

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

. G) z+ M8 G+ z

地设计,因此利用操作系统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-6-14 04:35 , Processed in 0.427301 second(s), 51 queries .

回顶部