QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

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

$ M& A+ H6 i; x7 ^# P

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

6 w. a! L2 F: |

张明武

( ^8 L9 ]+ d1 t1 v$ d* m+ T' q

. O+ s l4 J. d: l& L2 F2 K( A

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

: X2 ]% M1 L6 b4 e. G6 q6 ]; T

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

j+ C& f, W& f5 i/ m6 L8 ?4 O

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

- a" }! K; O7 o( C; i/ T. A+ D

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

! \- {4 d8 k# @4 t }! T

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

7 Y% h. Z- |0 H- q

+ E: I5 Y$ G. q, I: E' O0 G1 u

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

; y3 Z( P# ~- U4 L" d# g

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

6 L/ @8 F+ X! o. H$ P/ [! m

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

) [* }0 D; k% m5 L7 W

R' Y* y1 D8 S. N5 V/ J; A

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

9 E' w+ {, i5 {2 E3 E

文件的拷贝操作。

. \6 x6 p! a6 \" t; x+ y' k+ N' k

0 A* l9 c, y% G) B! R/ z

一、 原理与结构

0 H- n% u" c6 [! `. [! \

/ o& L" M- n) k# g: J! `* U

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

. u* w7 F6 r) j, v. j" d! [& k

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

5 K; i# C# k' t* g

/ A+ q! T" E. t' |: F

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

. `$ K+ W8 A; D' _% n

lpFIleOp);

2 ^! t. D) A! G+ e4 d

( L; ]; n3 r1 F

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

1 M6 U6 M! \3 S6 [4 _

下:

) h1 H0 k. O; Y' g( X9 O y

, K$ S3 M( K5 d4 Y9 Y% d

Typedef struct _ShFILEOPSTRUCT {

4 x q M* m4 @, A! ^" f! N

; @! W& g; Q9 K- t- h

HWND hWnd; //消息窗口

6 ?( t& ?4 B% ?) s# {- B( `

( ~6 U6 c$ C4 ~# C

UINT wFunc; //操作类型

* ^/ |( z& `* K# L' M* O

' W) N' X9 Y& h9 E: @; o4 g

LPCSTR pFrom; //源文件及路径

, V1 T1 D4 w$ `+ I! }% S: I

( {( L o+ p0 k

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

& H- t7 Q1 u3 W( u9 ?# R0 o

/ B' D+ g9 z/ _3 i2 v2 o* {+ n! {

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

! X! }3 t% ], k. {

0 ^6 K6 {& ]8 C: K1 m+ h# [: R

BOOL fAnyOperationsAborted; //操作选择位

' q w9 Y7 `( d2 q

B: X0 K) Z/ w; M

LPVOID hNameMappings; //文件映射

) b5 @6 K7 n u+ Z4 L! f4 N0 D# }" i

% W8 B9 g' o7 J( N2 ~

LPCSTR lpszProgressTitle; //进度窗口标题

8 B8 Z" r0 L/ o+ k" a

# \. l* k; j d- C# M

4 J* h8 w7 f7 u @" s- N& ~+ U, a3 d

} SHFILEOPSTRUCT, FAR* LPSHFILEOPSTRUCT;

9 C' d1 U) b' i7 I

. q; v# y+ S5 i2 M( p% v

& I2 r1 v; y% M( a" o3 U

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

5 p' k- ], k" `3 z+ T% Q

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

( C/ w* d- x! @' X8 E8 e

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

+ t0 X: c* I# m. P9 }) p

个,则应是:

3 _3 i( I' ^. W% f4 ]. Z6 J) [( s' D+ m

1 p' p k0 |7 o% B; ?

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

, |" h' ?" m' ]% T

7 M8 {. |- G+ O4 |! u

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

9 P) \: B$ q3 K0 F2 i. ]" X" H

8 S. y) L( r! P P/ o& F4 ]) j. C0 i

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

) d/ m% ~9 E" U$ N) Q

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

6 a2 b G5 D" u: ]6 U$ |$ g5 Y

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

p- {% l- @1 ~, ?( t

- u# ]+ |& F* x5 b8 g, `7 f5 b

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

. p0 y, B8 Q/ B4 o

4 Y" I* c ]' Q( i0 k e8 w5 I

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

4 m% L% N- B7 N" A

$ y- E: v3 j! U; v

" Z6 a1 g4 r+ x$ V* M) k8 R& D

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

! z2 N1 @" ~. c* B+ o

5 ~2 N$ V6 r7 d

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

: \( k7 F& V- U( y g

z# q9 I. {# j: H" }% x' o

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

2 I$ T3 Z/ _+ ]; l- L

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

v* D1 x9 B0 |4 Z5 ]

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

# a+ e0 K& r( G0 H, v

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

- ?$ u+ P- b' y9 k& r4 {

组合。

# ?. l! Y( y* D5 l. F

& }: Q$ R+ W. s( s6 A9 _/ g% {

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

* x* l. T4 q" n; U2 w; [

) I/ R7 w4 M+ U: d( }5 n+ r

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

' z- [7 U- k/ v) q# }6 N

3 k: Z0 o$ w7 a

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

' O% [1 t X5 O- Z6 {

候,如

) a2 t6 N- s, S

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

' ^( H" q, {9 o0 \6 M( E

此项则

3 w6 j) N7 c; T) ]+ |/ |

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

8 ?- y, D1 G5 `, v( _

. _! E' _8 K( Y; ?

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

$ I6 {0 ?- M& a2 f

现错误

9 u$ c7 A7 @; H7 _* E

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

! `; }+ E4 X3 `4 _. o. R% Y! c& W# N

6 G* m# U0 j! O4 l

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

* Q4 F6 O$ J+ {$ a" { p6 o# v( g

进行更

5 d( e( x! }7 o5 j+ r0 \* ~2 F

换文件名提示。

' B# ^, o n8 d" ~

8 ?0 c$ T8 R8 X5 J/ G# {7 L6 G

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

I& h9 @8 t- E5 t

3 v2 d% t6 V8 W* s

---- FOF_WANTMAPPINGHANDLE: 要求SHFileOperation()

$ g+ v" a" s y R

函数返

3 f1 ]/ R7 E1 g. p# p; A

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

8 e0 ?% I. g$ \

) J- R9 Y7 F( l( I2 \+ `* d

hNameMappings成员中。SHFILEOPSTRUCT将包含一个

& t8 H+ m7 O L m

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

2 d2 S3 w5 [, d; H( A8 N" a0 g4 k

个处于

% }2 }6 ]6 i& {# `* g

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

0 S F1 z9 F, b+ ~

9 X; Y" ]$ t! b3 y0 P$ O: f

二、 实例操作

- W. [/ F+ ~1 L& W

" ~' b. [8 ^: o% \ H1 w4 c$ [

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

* N9 J7 ?# Q2 z# A6 E* H

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

; j* V; y* b% v9 W! r& E

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

) y: h) }% \( T# |& d

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

: a4 ^+ F( o! Z& n0 i b7 b

X9 X3 Z5 v1 L+ n

if(!m_wndMyToolBar.Create(this)||

! t, t3 r4 J1 k2 q& ^

/ A9 [% p5 ~; X

!m_wndMyToolBar.LoadToolBar(IDR_MYTOOLBAR))

: Q! o* ~/ K8 N- S8 ]

; P# a, Z/ T# c# x2 f

{

/ m+ D1 D2 u6 F3 P! K( U

) q6 M/ E' O3 P9 f5 j- q; L! v

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

$ j4 S( L7 |) \% ]+ T+ B

. c# s9 O9 a! R& t. a

( T+ N# ?1 x! \' K. e

return -1;

! x) Q5 Q- ?1 Y. T

: S, s0 {& X! W& W2 P

}

$ s" }4 y: ^& R- _/ J7 w. y

6 F" h6 E u' k) J% F# d5 I

( K" m3 \! S+ @2 x- h

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

- U: \* G: P$ F, U

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

E$ A6 |: h; g% f. Q

$ p" {! o( l W. B/ V, T8 H

void OnFilecopy()

- U: ?$ K: P+ F/ s! T

{

1 _9 X0 C& R5 e& g

int nOk;

3 A4 L6 e3 u0 e. w

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

) n# e- L5 l8 b$ X

\\pwin98\\command\0";

' j, `3 k9 k) T3 H* {6 V4 |# y

//可以改变源路径

) c2 O: {4 A6 P' U: W3 F

$ N b) k% f/ V$ U3 v3 a

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

; G7 G+ c7 X4 g" _: k

//设置目的路径

8 U! I" i& f; r4 T

" _# S: y1 E0 H, n+ V2 v

char strTitle[]="File copying";

4 k1 S' Z* k3 a, j' s, x

//进度题头

* S' A9 Y, H2 `/ G

+ ~! Q3 w+ V2 H- \4 I% ?4 N

SHFILEOPSTRUCT FileOp;

; K6 c/ d1 ?3 n3 G5 G

/ ^. e1 F: i5 }' {- r' i

FileOp.hwnd=m_hWnd;

7 H7 Y2 g0 [& s* t0 L7 `" J

7 `! D$ D3 K$ e3 W, h" d0 }, C

FileOp.wFunc=FO_COPY;

, _4 a! H9 I) k& E' E

7 W3 ?, x `, o, d' \2 q4 o% X

//执行文件拷贝

. Y. ~. r+ w- G

5 t1 t# c, \3 N$ g3 S. ?

FileOp.pFrom=strSrc;

. Y6 h% a) c7 J& E* D

! S, G( \; C# Y0 }* ^7 m2 B& I. ~

FileOp.pTo=strDst;

V" E* _3 {" ]/ @8 e' C* W

7 n- N0 j* y4 y6 O7 q8 L' [

FileOp.fFlags=FOF_ALLOWUNDO;

8 z' O: h. ]' _

9 L0 z3 X: f! z0 T

FileOp.hNameMappings=NULL;

( ^ o+ Z- x0 u: M4 R* w

m: A, \( a u/ E8 N

FileOp.lpszProgressTitle=strTitle;

& l, L0 a; z! g, C2 \1 S& V$ x

C6 h& I0 P9 s$ S( I2 b* e

nOk=SHFileOperation(&FileOp);

2 y$ H8 i& C: k. [5 n1 r

: N$ Y+ x A- q6 p/ Z

if(nOk)

" s: _: Q; A: a% ]4 e

4 \! b8 }, M9 e6 C* I

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

' t% d2 s( |9 @& A; C

1 ^* H2 D5 h! W& h

else

% m4 P. K. Q6 `1 E

" i% y f8 s' p" x; y9 x

TRACE("SHFileOperation finished

7 X: M: |1 C# L, O1 N7 A

successfully\n");

% h, s& x1 B# \/ H

5 i% w0 L5 m A

if(FileOp.fAnyOperationsAborted)

. ]* j: x! k, J0 d: O; a" g

% M9 ~5 Z/ \5 U3 Z

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

! Q% f& A' e y$ _) {1 v

}

* s; W c' n1 N5 E1 I3 A9 [) E

- d; ~+ ^/ J: l: c9 O$ q

$ Z. k" P# T9 n. o

三、 结束语

' E2 Q/ [2 e3 Z. I5 M

6 |' o" @' f- Y- D

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

% X2 M( R4 ]) h) q( ?

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

6 m, e$ Y7 _8 I9 |9 k/ T" E

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

( G: {( e( {! R+ q

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

4 @ e- s: I- ^+ p

. O( N/ e' ^) v2 x1 j }

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

/ L; q$ E- f+ u' W+ f

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

' F+ z4 v- O9 Q# I

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

回顶部