QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

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

/ M- v, u1 D6 g2 J7 X3 K# R9 d5 ^: ?

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

; w: A! s* J4 [" S- V" f! u

张明武

R, ?' G1 _1 ?, a4 f! P6 K

T5 s% s8 n7 X; K

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

9 p7 @6 z9 e; _

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

7 L1 q b0 a8 }

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

% W) F" y# \5 j# q) q

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

+ z0 W& s3 X1 C l: p* [

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

' b4 A+ a5 P# D8 `: m: C; g! ?

* J# ?8 Q# Y# j

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

% k$ u! M9 e# @* M0 r! D

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

7 G, g! G9 ~' ^) O

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

/ ]; ]" k/ U5 n$ x7 @

7 \; t9 p3 q- @

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

. R! ^$ \8 e% v8 S

文件的拷贝操作。

4 L1 H. e, s- I3 V

/ ~5 [/ U- u6 I) F9 w

一、 原理与结构

4 ^2 u: O* ]: ^4 _5 p' @

% j/ V* z& i3 j, I" T' s

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

% a' A2 Y1 e C0 ]6 b

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

, o. c5 j3 ]1 n" \

. }4 _6 f0 S1 r8 f1 m5 |( i

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

7 r0 w% ]7 h! O7 [9 v' t8 C, |

lpFIleOp);

8 E4 P: g& ?; v' I1 w z; l

4 W8 F1 \$ O7 F8 u. ^& G0 I( `9 g

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

$ |. A% u s; M8 J0 s! F

下:

! a* {7 p' z: }% b2 x* ^

6 T) q, f* B6 Y! i

Typedef struct _ShFILEOPSTRUCT {

6 I6 S9 F# ]& j, w, J# n' ^

/ ~5 c7 D2 f. z8 U1 M5 J

HWND hWnd; //消息窗口

& g1 R6 ^* Y* {% O7 |

) x, r# `' R7 l0 J

UINT wFunc; //操作类型

( y! P; V" x6 k; Y/ z: q

$ g9 S! p% n3 C

LPCSTR pFrom; //源文件及路径

) W$ ?2 s" h* a! i! C

! D7 P; |- ? y- X

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

# s6 G$ |9 s9 v& a

6 P! I: h; R$ u6 [1 l; E

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

% |0 k ~: ?, v4 m

( G- l6 H0 s* l

BOOL fAnyOperationsAborted; //操作选择位

, _' y, m7 L2 x: b# G+ _

% M* i' r; L: |4 X# {2 G/ h

LPVOID hNameMappings; //文件映射

* f' J, x; g: Z3 V! k

! ^8 C+ v4 f( y" M" s" {$ O

LPCSTR lpszProgressTitle; //进度窗口标题

! F0 R" _0 R7 O* R8 c

' G( v) ]) `/ M

- X4 F# x+ T W; G& R2 T! `) A4 J! U

} SHFILEOPSTRUCT, FAR* LPSHFILEOPSTRUCT;

# S W0 C- r k

& \. L0 i1 b J" c+ X( |5 s

1 l6 k5 w, W" [

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

8 u M* E. X2 B9 v

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

) u. n. M7 M+ j

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

" W) O/ I P9 ]7 j

个,则应是:

& _# e/ y! T# f. K* r9 N6 E! O

7 i; {- `1 T) K5 g) Y

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

6 f6 x4 y$ [" U: }; m+ [3 K2 A0 F) n5 P

( s s3 @7 B0 y5 z+ F5 G- V

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

z' r4 p' A9 |. M9 L% U

3 p8 |# ?. x. f& N8 R9 a

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

! c/ t, a% {" l# s6 j X }

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

2 ?9 G% p7 ` z8 D$ k: [3 X* v

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

" r6 @& k( u" a1 I3 J3 E l

2 U4 S) t3 X# v7 P6 B R+ c

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

2 O9 r, G [5 B, k

/ T7 @& z* ~. I# Z( K

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

) t# M. _9 t ]! K

1 B; p8 l# m4 { U# f X) R3 Z

" @) C" ~/ I' Z- F8 I

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

5 Z: r0 T0 |, n& F: \

; E6 K7 e2 q2 J/ c% q

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

, |6 s6 O5 f) d& _+ ?$ j. k8 U

1 o* J" n6 O0 {3 c; j0 r

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

# v# Z( C+ B" H! q! d, s

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

1 V5 w2 s2 }2 T8 d- ^* I

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

( Z8 a8 I6 V0 `7 w+ _9 [. v

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

+ k$ T \9 o2 ~6 H# v% U

组合。

; D3 e/ U: {# w" W" P: K$ s

! G+ `+ W( r, W) R9 \! z% ^, L

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

, H. @: H' I4 E8 Z2 K {1 d

4 }! z" z! a( H1 O1 M7 I, c: a

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

' \: y3 ~( m; O) [

/ f" z; z. P V5 ]

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

! {3 P* v1 L P0 R O( b3 C5 u

候,如

$ T! q: X5 B n8 a# Y# D# w/ i

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

' p+ l( z& K! m! O( W+ Q

此项则

) ?( y* ~. h5 a, e/ B" K

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

6 t- ] ?4 `, z4 o2 \

" ~: d7 E7 j2 b- }% s

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

$ {; e1 w) Y2 T: k

现错误

( w. `) j- g6 e& {

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

" L" |- i! t% U8 Q M

+ R& q% f' y Y9 f

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

7 e- i8 m5 {) C$ W: F) w5 A

进行更

$ w. B0 x g) p. n% [

换文件名提示。

& _- m% J8 y( F8 V. ~. J. \

& H* y* N9 l8 |9 y

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

: N: C+ r# l0 f

, B" Z" O% D! d; ?% O5 _ n! y$ |6 p

---- FOF_WANTMAPPINGHANDLE: 要求SHFileOperation()

Q- Q: ]" S$ f) p1 L! R) C4 F7 V2 ]

函数返

$ w$ A$ j3 r! E" |8 e1 @9 U; R; K

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

( g+ l+ U% {" S# n% C7 P

& u" p; b$ P: [( B

hNameMappings成员中。SHFILEOPSTRUCT将包含一个

) C: X* L( I1 S: n

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

" Z2 F& S/ Z& X. g: c$ t8 P

个处于

) ?9 E7 B0 F* J0 I/ p- U

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

! V2 f* S2 C3 N' p# O: Q9 |

, `7 B R+ K0 t1 N8 G4 W

二、 实例操作

# ^, F5 J$ b5 D& @$ P* n! }0 r9 L

9 m% a* x( o0 d: q

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

1 X1 V. s" V+ Q8 o9 ~; X$ k

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

' G" H; X/ T# `! ~5 Z. M

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

" T& `- |- r6 l$ u% ]: F' R* J( a

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

" K! I* {# }, z; s" S# o

* p, {. _5 n& @! D$ T$ W8 Q" H

if(!m_wndMyToolBar.Create(this)||

$ s9 F+ i# ^/ n0 q; r" G5 Q

3 C- i) Q& S: v) r; E

!m_wndMyToolBar.LoadToolBar(IDR_MYTOOLBAR))

) Q/ u, l4 H" ]$ l& I

) k) s% d, R5 p) }* d1 K

{

% m6 `, g! g0 N

6 K4 t. U* l2 P4 T) _ P& Z

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

3 b( | O K) F

& B6 R1 Y; i: k) c* c' ]

x1 t4 J; E8 _

return -1;

! D; S% n: n( ~* T' |* L8 M

5 v5 c7 I, c' M' F* S

}

/ k! ^8 _$ ~- J& O. O% |9 J

$ v, t, y7 l, A. Q. \

: L; T6 p5 S9 z( I7 G

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

: `9 ~6 C- }3 G6 X# P2 [& N

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

/ i# {. ?% t6 a7 ^% e8 L

$ S' R+ y' U* M2 h5 z1 `5 b

void OnFilecopy()

- P" A5 E% k# o! a* k$ N

{

5 z0 E% J x$ ?+ E0 a) e

int nOk;

3 {9 L9 I: G6 {; x1 m

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

* H& l0 F( S9 M: U

\\pwin98\\command\0";

' _" Y1 w- d% G6 ?) H6 @4 ~4 S

//可以改变源路径

) m8 a7 t5 Z7 [1 x$ o; d/ Z

! p' b1 {" _! x/ q; O* J

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

. Z! ]+ ~: j3 ~! a$ M/ L

//设置目的路径

; e- F2 T% Y- `; c& Z% m

4 [ X& T7 ^) W1 x2 [) \: X

char strTitle[]="File copying";

4 l4 W1 J( j* N H& X& V

//进度题头

" P6 _& f$ ~* W: M# A5 K$ V6 V; G

K4 X/ e5 r3 ?' N

SHFILEOPSTRUCT FileOp;

8 O: Y9 Q1 c2 T- ]; L& a* ^1 J! q

" T; B: _. E, E' `2 e* H" S

FileOp.hwnd=m_hWnd;

( h8 x t, R$ ~ T

, t( x0 u( O: T

FileOp.wFunc=FO_COPY;

" S$ j5 B* A, H9 E5 o' p

. K) V6 e! P F- w8 O

//执行文件拷贝

0 a0 A% k) s; d% y3 g: ]

0 o6 i( L+ i- p4 ~0 E* \ R$ ~2 @

FileOp.pFrom=strSrc;

+ N; W# E) }, x/ m! ] J* E4 t

& O- Q0 x2 G& C: v0 V. l' H

FileOp.pTo=strDst;

; Y8 q0 p- ], H! R; g* M# A8 x" P

* c" U6 ~% b, w" w# X, c+ b. B$ y$ `

FileOp.fFlags=FOF_ALLOWUNDO;

, O& v3 @, t$ k6 N

9 n/ y' O- _% P" P' |) ?4 R

FileOp.hNameMappings=NULL;

! H( Q& f8 }! U$ X4 _

7 f6 Y, G4 y) T. g

FileOp.lpszProgressTitle=strTitle;

7 n' b' s9 r& s- O1 A

/ }1 e4 E8 I( M3 X; P0 S( X9 A

nOk=SHFileOperation(&FileOp);

0 N" X/ U. u1 Z* c. u! V

6 |/ x; C6 ]) ^9 N

if(nOk)

# L% W# m) w! c6 y7 R, P; \

) |$ @7 M% x0 z( F! V+ ?6 Z; `

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

& |; `) `2 r( |1 F6 `# F

/ v6 p) U' ?+ R2 Q

else

0 R- F- H( Z8 @* X4 i4 R, {" m

4 o- T/ |2 V/ H4 a, I

TRACE("SHFileOperation finished

( {% P8 s1 ` K) N/ g5 f

successfully\n");

1 F% Y ~: m9 {. Q) \! P1 P; s

) ?" r* h* R: F3 O# [

if(FileOp.fAnyOperationsAborted)

+ e. L0 x- ~: [ X+ Q

6 v* b \% g _ e* K1 d

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

6 h3 }! ?; P8 ^; u

}

2 w/ V p+ @; ?* \# P* F) g

- l! C8 ]3 T' [/ Z: J

# e2 ^$ D+ X% F

三、 结束语

7 @- ?, x$ Q G! s& B3 }

/ Y6 Y$ h2 i' g5 a* b5 a I

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

7 U/ b1 _ S. t

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

; e) m: k' C9 L4 \6 r# \2 e, l; t

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

. E9 T) H* y% G

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

5 m8 n* j. J3 G

6 {) {8 S0 Y, |1 H- @$ K8 b5 S

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

# Q( J' V; q* @1 n4 c7 P3 h

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

! [" _- o d. L; a' [; G' A

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

回顶部