高手请教!怎样自动将文件夹中新的文件上传到FTP

sisihu 2009-08-11 11:32:00
RT~
谢谢哦
...全文
93 点赞 收藏 8
写回复
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
sisihu 2009-08-11
谢谢楼上哦~
回复
MoXiaoRab 2009-08-11
可以监视...
介绍三种非驱动实现文件监视的方法。


=================================================================

通过 未公开API SHChangeNotifyRegister 实现

=================================================================
Windows 内部有两个未公开的函数(注:在最新的MSDN中,已经公开了这两个函数),分别叫做SHChangeNotifyRegister和 SHChangeNotifyDeregister,可以实现以上的功能。这两个函数位于Shell32.dll中,是用序号方式导出的。这就是为什么我们用VC自带的Depends工具察看Shell32.dll时,找不到这两个函数的原因。SHChangeNotifyRegister的导出序号是 2;而SHChangeNotifyDeregister的导出序号是4。
SHChangeNotifyRegister可以把指定的窗口添加到系统的消息监视链中,这样窗口就能接收到来自文件系统或者Shell的通知了。而对应的另一个函数,SHChangeNotifyDeregister,则用来取消监视钩挂。SHChangeNotifyRegister的原型和相关参数如下:
ULONG SHChangeNotifyRegister
(
HWND hwnd,
int fSources,
LONG fEvents,
UINT wMsg,
Int cEntries,
SHChangeNotifyEntry *pfsne
);
其中:
hwnd
将要接收改变或通知消息的窗口的句柄。
fSource
指示接收消息的事件类型,将是下列值的一个或多个(注:这些标志没有被包括在任何头文件中,使用者须在自己的程序中加以定义或者直接使用其对应的数值)
SHCNRF_InterruptLevel
0x0001。接收来自文件系统的中断级别通知消息。
SHCNRF_ShellLevel
0x0002。接收来自Shell的Shell级别通知消息。
SHCNRF_RecursiveInterrupt
0x1000。接收目录下所有子目录的中断事件。此标志必须和SHCNRF_InterruptLevel 标志合在一起使用。当使用该标志时,必须同时设置对应的SHChangeNotifyEntry结构体中的fRecursive成员为TRUE(此结构体由函数的最后一个参数pfsne指向),这样通知消息在目录树上是递归的。
SHCNRF_NewDelivery
0x8000。接收到的消息使用共享内存。必须先调用SHChangeNotification_Lock,然后才能存取实际的数据,完成后调用SHChangeNotification_Unlock函数释放内存。
fEvents
要捕捉的事件,其所有可能的值请参见MSDN中关于SHChangeNotify函数的注解。
wMsg
产生对应的事件后,发往窗口的消息。
cEntries
pfsne指向的数组的成员的个数。
pfsne
SHChangeNotifyEntry 结构体数组的起始指针。此结构体承载通知消息,其成员个数必须设置成1,否则SHChangeNotifyRegister或者 SHChangeNotifyDeregister将不能正常工作(但是据我试验,如果cEntries设为大于1的值,依然可以注册成功,不知何故)。
如果函数调用成功,则返回一个整型注册标志号,否则将返回0。同时系统就会将hwnd指定的窗口加入到操作监视链中,当有文件操作发生时,系统会向hwnd标识的窗口发送wMsg指定的消息,我们只要在程序中加入对该消息的处理函数就可以实现对系统操作的监视了。
如果要退出程序监视,就要调用另外一个未公开得函数SHChangeNotifyDeregister来取消程序监视。该函数的原型如下:
BOOL SHChangeNotifyDeregister(ULONG ulID);
其中ulID指定了要注销的监视注册标志号,如果卸载成功,返回TRUE,否则返回FALSE。
=================================================================

通过 FindFirstChangeNotification 实现

=================================================================


FindFirstChangeNotification函数创建一个更改通知句柄并设置初始更改通知过滤条件.
当一个在指定目录或子目录下发生的更改符合过滤条件时,等待通知句柄则成功。
该函数原型为:
HANDLE FindFirstChangeNotification(
LPCTSTR lpPathName, //目录名
BOOL bWatchSubtree, // 监视选项
DWORD dwNotifyFilter // 过滤条件
);

当下列情况之一发生时,WaitForMultipleObjects函数返回
1.一个或者全部指定的对象在信号状态(signaled state)
2.到达超时间隔


例程如下:
DWORD dwWaitStatus;
HANDLE dwChangeHandles[2];

//监视C:\Windows目录下的文件创建和删除

dwChangeHandles[0] = FindFirstChangeNotification(
"C:\\WINDOWS", // directory to watch
FALSE, // do not watch the subtree
FILE_NOTIFY_CHANGE_FILE_NAME); // watch file name changes

if (dwChangeHandles[0] == INVALID_HANDLE_VALUE)
ExitProcess(GetLastError());

//监视C:\下子目录树的文件创建和删除

dwChangeHandles[1] = FindFirstChangeNotification(
"C:\\", // directory to watch
TRUE, // watch the subtree
FILE_NOTIFY_CHANGE_DIR_NAME); // watch dir. name changes

if (dwChangeHandles[1] == INVALID_HANDLE_VALUE)
ExitProcess(GetLastError());

// Change notification is set. Now wait on both notification
// handles and refresh accordingly.

while (TRUE)
{

// Wait for notification.

dwWaitStatus = WaitForMultipleObjects(2, dwChangeHandles,FALSE, INFINITE);

switch (dwWaitStatus)
{
case WAIT_OBJECT_0:

//在C:\WINDOWS目录中创建或删除文件 。
//刷新该目录及重启更改通知(change notification).

AfxMessageBox("RefreshDirectory");
if ( FindNextChangeNotification(dwChangeHandles[0]) == FALSE )
ExitProcess(GetLastError());
break;

case WAIT_OBJECT_0 1:
//在C:\WINDOWS目录中创建或删除文件 。
//刷新该目录树及重启更改通知(change notification).

AfxMessageBox("RefreshTree");
if (FindNextChangeNotification(dwChangeHandles[1]) == FALSE)
ExitProcess(GetLastError());
break;

default:
ExitProcess(GetLastError());
}
}


=================================================================

通过 ReadDirectoryChangesW 实现

=================================================================

bool Monitor()
{


HANDLE hFile = CreateFile(
"c:\\",
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
NULL,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS,
NULL
);
if( INVALID_HANDLE_VALUE == hFile ) return false;

char buf[ 2*(sizeof(FILE_NOTIFY_INFORMATION)+MAX_PATH) ];
FILE_NOTIFY_INFORMATION* pNotify=(FILE_NOTIFY_INFORMATION *)buf;
DWORD BytesReturned;
while(true)
{
if( ReadDirectoryChangesW( hFile,
pNotify,
sizeof(buf),
true,
FILE_NOTIFY_CHANGE_FILE_NAME|
FILE_NOTIFY_CHANGE_DIR_NAME|
FILE_NOTIFY_CHANGE_ATTRIBUTES|
FILE_NOTIFY_CHANGE_SIZE|
FILE_NOTIFY_CHANGE_LAST_WRITE|
FILE_NOTIFY_CHANGE_LAST_ACCESS|
FILE_NOTIFY_CHANGE_CREATION|
FILE_NOTIFY_CHANGE_SECURITY,
&BytesReturned,
NULL,
NULL ) )
{
char tmp[MAX_PATH], str1[MAX_PATH], str2[MAX_PATH];
memset( tmp, 0, sizeof(tmp) );
WideCharToMultiByte( CP_ACP,0,pNotify->FileName,pNotify->FileNameLength/2,tmp,99,NULL,NULL );
strcpy( str1, tmp );

if( 0 != pNotify->NextEntryOffset )
{
PFILE_NOTIFY_INFORMATION p = (PFILE_NOTIFY_INFORMATION)((char*)pNotify+pNotify->NextEntryOffset);
memset( tmp, 0, sizeof(tmp) );
WideCharToMultiByte( CP_ACP,0,p->FileName,p->FileNameLength/2,tmp,99,NULL,NULL );
strcpy( str2, tmp );
}

// your process
}
else
{
break;
}
}

return true;
}
回复
sisihu 2009-08-11
那可不可以通过监控文件夹来实现自动上传呢?当有新的文件时就上传
但是监控文件夹有新文件怎么弄呢
回复
webxeyes 2009-08-11
找找MFC中的FTP支持类,看着就会上传了

使用Shell监视文件夹变化进行上传,基本上就完全同步了
回复
zaodt 2009-08-11
分两步:

1、先实现手动上传;

2、加个定时器,实现自动上传。
回复
sisihu 2009-08-11
to:yuhudie203
网上一般都是FTP客户端的资源,自动上传的好像很少哦
回复
岁月小龙 2009-08-11
好的
回复
yuhudie203 2009-08-11
建议你去网上找找FTP上传服务器的相关资料
回复
发动态
发帖子
VC/MFC
创建于2007-09-28

1.5w+

社区成员

VC/MFC相关问题讨论
申请成为版主
社区公告
暂无公告