QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

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

' V% z) Z. ^0 W! C9 g3 Z7 f

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

$ J' ?& G2 i, z% G9 E

张明武

) C0 R# g% R' }9 s

. F3 u7 m" X% w; t! [+ A" g0 C% ?

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

5 k0 G3 r7 Z% v

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

e- G9 f. }8 e& \* \9 {

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

6 B% |( }5 M4 ^& s$ b8 `

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

5 O, o n2 Y: U/ B! r) I) M

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

* W, D0 V1 t8 U* U' Y! t/ [+ l

7 ~6 ]8 K0 C5 i

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

- G" [9 O9 A6 g$ |( p* ^; R2 I( G

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

! M! ?4 l& x( |* X. p) r2 L

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

9 A! v& Y1 t1 V9 M& m

) r# N: U. N/ p6 u0 |

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

: w6 }/ x. ` L, j- t

文件的拷贝操作。

$ a1 L' Z |6 ~- |) G- `

; a- S! \/ V) j* G6 }; e/ h

一、 原理与结构

6 l( z2 Q, s" u* H

Y3 T2 a& K- Y9 S1 Z. Q

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

* C6 k- S2 y5 g+ s0 I7 H

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

0 i1 H9 ]" ?# @/ t2 `4 o7 ^

- C: L: K' K" R7 P

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

7 l# P4 F# A2 G

lpFIleOp);

& R/ [* A8 w, x$ _* {

# @9 j a+ a2 r2 D

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

9 G: h4 j8 X v. o

下:

; V X) Y& G& Y* P) t

# s! h3 s* N# [- z* \; p f

Typedef struct _ShFILEOPSTRUCT {

8 {# ^! F/ Y( E0 v0 o1 P( P

p! I! Y8 l+ ^6 t

HWND hWnd; //消息窗口

% A: Z$ o5 h' k

4 S! t; z6 O0 b! m2 e

UINT wFunc; //操作类型

8 `3 n" [# z, x2 W

) h t& n! ^" E& Z. \6 F

LPCSTR pFrom; //源文件及路径

& ^7 P7 V2 H5 |, J

" ^2 Q' W! W2 K5 t) m* s( b

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

% B2 n0 }1 J6 Y/ k/ \2 V1 |) c

) o% ^; _5 A- h6 T0 w; ] P& ]; F/ Y

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

5 } I& | D" |6 h

0 S* {2 L3 Q7 o% V, a% j$ [. E

BOOL fAnyOperationsAborted; //操作选择位

3 r2 I, I* p/ \+ e" g* Z, f

& w+ h3 O( d* @3 [, |( k' X) |4 ^

LPVOID hNameMappings; //文件映射

- v0 _3 R/ I4 X% L6 T

$ P4 S3 ~1 g% G

LPCSTR lpszProgressTitle; //进度窗口标题

8 W; O/ ~4 d$ [- O

$ l( m' w+ b5 y$ ?1 z/ h4 u

: D/ W$ E( d. J& |/ v' o% }0 ?6 A, r

} SHFILEOPSTRUCT, FAR* LPSHFILEOPSTRUCT;

9 T& \% K9 |- E- z" R0 K7 t _

$ {8 o; `1 e. U: E0 n* y2 n

* Q7 R$ Y( h- k# h+ `1 w4 k

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

6 R* N; L @; @# J

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

' R, Q c7 q1 }! R+ s+ C

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

+ Z* f$ R* e/ _9 q2 h. F0 x7 [

个,则应是:

! n f* V5 U5 f* B5 E A

( e2 g( c7 f) }$ D( o7 {1 P

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

?) [& S% T \& x& Z& J$ c% W# P

" N. v6 Q# j j

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

/ P, @8 Q, `, _$ T5 n

, D3 q" Q) l7 t2 h1 J5 U3 e

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

+ z3 G/ K+ E( t1 Z0 {" r

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

. G( ]4 [. v1 c) B) s% J( v1 i

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

/ r% R9 J( |0 T, \9 r

3 g0 _$ o) A* m0 [

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

* T6 ~& h) P: `

: Q. B* ~* G% Q3 n

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

8 ~2 b* P5 \+ A: P0 o. R, o

- T" H: y9 p3 [( T

' \" S( X: \7 G, K+ c+ J, ]

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

7 }6 Z9 j: l5 B2 d

6 c- }5 j; b- Z9 V3 S7 E

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

. {0 ?& S' j, y

2 A4 J7 \! S7 m9 r

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

0 E# q8 |/ }8 k2 o

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

% w- ]" b/ E3 }) @6 ]8 \9 l' K

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

, I: S' U0 h2 b" G- S

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

# [! [; L) o" C- v' C

组合。

1 b1 H$ S2 N( b

6 [7 D- `, e' M( _1 f, Y/ o4 ^

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

5 _3 I- V1 h U% p: t% ]

d& x/ l2 N6 ]7 e- r

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

0 j/ d. c2 u% L6 _5 M; Z2 E

2 N4 h2 E# F. o _

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

3 z$ E. O3 s2 f- b1 @

候,如

$ L& _& h/ [+ l

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

# N7 U3 s+ b8 W4 k% ~1 j/ T

此项则

4 C: W8 ]+ n( [6 Z6 e3 Z

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

: {8 j1 y( M/ G2 a9 t; e- g

; W7 u9 f$ m2 m f9 m ~* I9 ?

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

' ^, F( A# T( N# H# O

现错误

3 M% J7 p% e, ^& E( |0 ^

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

) @9 g* X5 v0 ~: `, V- z3 W/ l

; L$ R# g/ \# }6 g

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

2 f2 j _4 J9 i# _+ {4 _7 b! G

进行更

9 _2 F4 }5 l: {: }; `2 v

换文件名提示。

& ?3 ?5 i( C! C1 e

7 W8 P0 O3 x% M; R( s# r

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

! y* P5 l( [2 S

" C9 V6 ^* [$ }6 s: y; s! O4 `

---- FOF_WANTMAPPINGHANDLE: 要求SHFileOperation()

9 r- H! r$ \1 o* k( u3 ]0 a( ^

函数返

! ^7 T1 K: e$ z5 K' [

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

1 k7 ~0 L9 Q1 ^5 q* s" _

2 X, o2 H4 K4 v2 F3 E, m

hNameMappings成员中。SHFILEOPSTRUCT将包含一个

; g, X( f- e$ T2 w3 E3 M' [( C+ f

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

7 u0 M; {& @, h/ O; t

个处于

t8 S e. e/ f+ \% s- v

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

! y9 e; {8 Z- W7 X1 I5 A, |3 @' X

+ h" C" E. L9 ]* n/ x

二、 实例操作

; y% v# g$ v! ^

% m* L: E2 T ~; o/ B9 f

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

x/ w* |" R- y5 F

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

" l. r# G" _9 A

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

. z M9 e0 ]1 ~% B: Q( P

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

0 W# C1 ^, K& i

# G4 d' {1 V& K

if(!m_wndMyToolBar.Create(this)||

9 j8 o P1 f' Z" k

: {& G5 p) ]1 O' Z3 K

!m_wndMyToolBar.LoadToolBar(IDR_MYTOOLBAR))

( l, s/ E! S6 m! h+ \! K$ c8 @; V. F

5 I6 M9 Q/ P) q8 o& I( ]

{

1 H. b' w5 B; a, ]/ u6 L/ i

) i* @8 ]! e) X: `/ q( T9 r

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

$ g& s9 l( S, O! n; f" H* m) r3 [

8 G* a. l \* q7 Q

% \" S; h& Q+ F: z7 w

return -1;

- k, R/ s1 M+ M# b8 e

" z& s2 M7 }6 U4 U" ~* g% E: }

}

! e$ h0 V6 w |3 r. }/ q

, _: @4 `9 h3 u* e, v) P

. \3 A0 m7 z) y- o

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

3 E0 U7 a: O( N* s( ^' c

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

; z1 @! T. x2 ~1 {# I

4 r- K1 v6 T/ P9 X

void OnFilecopy()

* W' E" \ d, v \

{

; d9 \7 Q8 |9 T. [; l5 F

int nOk;

& c7 L1 u& {! e/ m5 f. e

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

; U. ~( V6 @: H4 E1 Y) ?) k% U

\\pwin98\\command\0";

) [" f: X3 G) |; A s& {

//可以改变源路径

8 s7 S {" y6 i; @* }

$ q+ P: h' J5 N {, v& T2 q

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

8 [$ u$ y5 h+ }

//设置目的路径

, W* c; y; x/ [) V2 S3 U% K

3 r6 B: s. D; Z4 I5 |1 x; B

char strTitle[]="File copying";

( E7 |. d# R0 D8 e

//进度题头

4 f/ u0 X1 I* {5 w- m# f+ P

' x# V0 i1 c. V' Z- W

SHFILEOPSTRUCT FileOp;

1 v$ g4 C* Q! h+ Q& h/ Q3 w" Y

* W" J4 r5 ^' J! h3 x( l- N

FileOp.hwnd=m_hWnd;

7 r; @. x1 l' [4 D# ~2 Y3 j5 l

; e. I) W5 l* c6 O

FileOp.wFunc=FO_COPY;

1 n9 Y* y' @ e8 U6 x# L

4 b3 i7 w; m1 X, _+ }

//执行文件拷贝

3 ~6 e( B! w) C k

. V& l4 X# p: Z; j

FileOp.pFrom=strSrc;

& ?, t5 V0 H8 k3 h

7 o8 t e9 t. M. l

FileOp.pTo=strDst;

( `$ c5 O3 R1 I0 {. J4 T

}% `/ r+ b9 H7 G. y+ \" ]3 i

FileOp.fFlags=FOF_ALLOWUNDO;

* f, O0 l; M6 x# `3 s: Q7 l

7 v8 K7 A5 ?( B; E, v& d: U+ q

FileOp.hNameMappings=NULL;

' c& e) H" E4 O8 H8 a

Y9 W3 }4 O; W1 @9 g5 z+ Y- U9 B" r

FileOp.lpszProgressTitle=strTitle;

" q) G: G' V6 J' m* O- G

8 V: t1 D4 G/ Z8 p. e- J. w9 s

nOk=SHFileOperation(&FileOp);

, [( M/ q: U# K

5 k8 Q3 h4 p. ^. i' S6 L9 z' {& z

if(nOk)

- K( F1 y: h9 o8 b* f |1 ?: t1 ^+ F- ^9 c

( n" o5 R8 M& W5 R9 v2 m

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

# B5 U: U/ P2 j7 a( [% F: ~

3 `, A- F, M; F: V, z8 {

else

7 C* c: }1 |4 x" k% c! t X

$ t7 B6 R; H( i' ?

TRACE("SHFileOperation finished

5 n% c* v$ e0 l* D

successfully\n");

: s* J* x7 p1 ]0 `! V! J! G v

5 e% P4 p; h: b0 `

if(FileOp.fAnyOperationsAborted)

- J( `0 z" q5 R- ]8 i* ?

6 Q- H* J1 O/ B X! C1 M& b

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

! H5 ~6 F: c) l; q

}

1 b7 m" O8 w9 u( E/ N9 p8 r& ~, @: J

. p U9 F% t ? E& G6 N5 n' h

. [1 f1 y# z k l3 @

三、 结束语

$ j9 {+ l8 @5 J4 o* b% ~

, a. H- U5 o2 h# d

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

! z$ D5 L+ A1 {: `/ [

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

/ _% h* `/ X& b9 D/ l: R4 \

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

; W% t n* b5 V& X. R

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

1 b9 j) x7 d5 G9 S& O+ Y, t/ d

5 [8 B8 }; m5 i% O+ b+ x% k& l# \! ^: N

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

6 j. y1 Q( @5 Z0 {4 M

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

2 m& b: p5 H- M M( s

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

回顶部