Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

FTP upload - rename file after upload

Posted on 2012-03-30
12
798 Views
Last Modified: 2012-03-31
I've found this function that I use for uploading a database file to a FTP server, and it works fine. But I need to have an additional parameter in the function, so that after uploading the file to the folder indicated by the sDir paramter, it checks if a new parameter sDirRen is diffenrent from sDir, and if it is, it renames the file on the ftp server.

similar to the FTP command: "ren sDir/filename sDirRen/filename"

Can someone please help me with this modification to the  function shown below :) ?

Function FTPFile(ByVal HostName As String, _
    ByVal UserName As String, _
    ByVal Password As String, _
    ByVal LocalFileName As String, _
    ByVal RemoteFileName As String, _
    ByVal sDir As String, _
    ByVal sMode As String) As Boolean
   
    On Error GoTo Err_Function
       
' Declare variables
Dim hConnection, hOpen, hFile  As Long ' Used For Handles
Dim iSize As Long ' Size of file for upload
Dim Retval As Variant ' Used for progress meter
Dim iWritten As Long ' Used by InternetWriteFile to report bytes uploaded
Dim iLoop As Long ' Loop for uploading chuncks
Dim iFile As Integer ' Used for Local file handle
Dim FileData(BUFFER_SIZE - 1) As Byte ' buffer array of BUFFER_SIZE (100) elements 0 to 99

' Open Internet Connecion
hOpen = InternetOpen("FTP", 1, "", vbNullString, 0)

' Connect to FTP
hConnection = InternetConnect(hOpen, HostName, INTERNET_DEFAULT_FTP_PORT, UserName, Password, INTERNET_SERVICE_FTP, IIf(PassiveConnection, INTERNET_FLAG_PASSIVE, 0), 0)

' Change Directory
Call FtpSetCurrentDirectory(hConnection, sDir)

' Open Remote File
hFile = FtpOpenFile(hConnection, RemoteFileName, GENERIC_WRITE, IIf(sMode = "Binary", FTP_TRANSFER_TYPE_BINARY, FTP_TRANSFER_TYPE_ASCII), 0)

' Check for successfull file handle
If hFile = 0 Then
    MsgBox "Internet - Failed!"
    ShowError
    FTPFile = False
    GoTo Exit_Function
End If

' Set Upload Flag to True
FTPFile = True

' Get next file handle number
iFile = FreeFile

' Open local file
Open LocalFileName For Binary Access Read As iFile

' Set file size
iSize = LOF(iFile)

' Iinitialise progress meter
Retval = SysCmd(acSysCmdInitMeter, "Uploading File (" & RemoteFileName & ")", iSize / 1000)

' Loop file size
For iLoop = 1 To iSize \ BUFFER_SIZE
       
    ' Update progress meter
    Retval = SysCmd(acSysCmdUpdateMeter, (BUFFER_SIZE * iLoop) / 1000)
       
    'Get file data
    Get iFile, , FileData
     
    ' Write chunk to FTP checking for success
    If InternetWriteFile(hFile, FileData(0), BUFFER_SIZE, iWritten) = 0 Then
        MsgBox "Upload - Failed!"
        ShowError
        FTPFile = False
       GoTo Exit_Function
    Else
        ' Check buffer was written
        If iWritten <> BUFFER_SIZE Then
            MsgBox "Upload - Failed!"
            ShowError
            FTPFile = False
            GoTo Exit_Function
        End If
    End If
   
Next iLoop

' Handle remainder using MOD

    ' Update progress meter
    Retval = SysCmd(acSysCmdUpdateMeter, iSize / 1000)

    ' Get file data
    Get iFile, , FileData
   
    ' Write remainder to FTP checking for success
    If InternetWriteFile(hFile, FileData(0), iSize Mod BUFFER_SIZE, iWritten) = 0 Then
        MsgBox "Upload - Failed!"
        ShowError
        FTPFile = False
        GoTo Exit_Function
    Else
        ' Check buffer was written
        If iWritten <> iSize Mod BUFFER_SIZE Then
            MsgBox "Upload - Failed!"
            ShowError
            FTPFile = False
            GoTo Exit_Function
        End If
    End If
               
Exit_Function:

' remove progress meter
Retval = SysCmd(acSysCmdRemoveMeter)

'close remote file
Call InternetCloseHandle(hFile)

'close local file
Close iFile

' Close Internet Connection
Call InternetCloseHandle(hOpen)
Call InternetCloseHandle(hConnection)

Exit Function

Err_Function:
MsgBox "Error in FTPFile : " & Err.Description
GoTo Exit_Function

End Function
0
Comment
Question by:Bojerne
  • 6
  • 6
12 Comments
 
LVL 57
ID: 37786719
Many FTP clients/servers won't let you do that (rename).  Instead give it the name you want it to end up with right away by making RemoteFileName different then LocalFileName

Jim.
0
 
LVL 57
ID: 37786737
Sorry, just re-read what you wrote and I missed the point a bit; it's sDir that you want to make sure that is correct as it is what is being used to set the FTP directory:

' Change Directory
Call FtpSetCurrentDirectory(hConnection, sDir)

Between that and RemoteFileName, you'lll be able to put a file right where you want it and there should be no reason that you need to re-name it.

Jim.
0
 
LVL 1

Author Comment

by:Bojerne
ID: 37786774
Hi Jim

It's not because I don't know where to put the file - it's part of the customers solution that it should be done this way - first copied, then renamed - it's because of the way their system picks up the orders from the ftp server - so I need that functionality although it's a bit silly :) Can you help me ?
0
Migrating Your Company's PCs

To keep pace with competitors, businesses must keep employees productive, and that means providing them with the latest technology. This document provides the tips and tricks you need to help you migrate an outdated PC fleet to new desktops, laptops, and tablets.

 
LVL 1

Author Comment

by:Bojerne
ID: 37786839
I guess FtpRenameFile could work
0
 
LVL 57

Accepted Solution

by:
Jim Dettman (Microsoft MVP/ EE MVE) earned 500 total points
ID: 37786864
Yes, FtpRenameFile would be the call:

RetVal = FtpRenameFile(hConnection, RemoteFileName, NewRemoteFileName)

Jim.
0
 
LVL 1

Author Comment

by:Bojerne
ID: 37786912
Yes I tried that, but can't make it work

I've put in this in the function shown in the question header

 If sDirRen <> sDir And FTPFile Then
        Call FtpRenameFile(hConnection, sDir & RemoteFileName, sDirRen & RemoteFileName)    End If

And I've also put in this declaration, but it fails to do the rename

Public Declare Function FtpRenameFile Lib "wininet.dll" _
    Alias "FtpRenameFileA" (ByVal hFtpSession As Long, _
    ByVal lpszExisting As String, ByVal lpszNew As String) As Boolean
0
 
LVL 57
ID: 37786947
<< If sDirRen <> sDir And FTPFile Then
        Call FtpRenameFile(hConnection, sDir & RemoteFileName, sDirRen & RemoteFileName)    End If
>>

  The remarks on RenameFile read:

"The lpszExisting and lpszNew parameters can be either partially or fully qualified file names relative to the current directory. A backward slash (\) or forward slash (/) can be used as the directory separator for either name. FtpRenameFile translates the directory name separators to the appropriate character before they are used. "

 So it sounds like it might work like this:

If sDirRen <> sDir And FTPFile Then
        Call FtpRenameFile(hConnection, sDir & "\" & RemoteFileName, sDirRen & "\" & RemoteFileName)
End If


Give that a go.  Not sure it will work though.  Note that it says "Current directory".  It may only allow a file rename and not a directory move.

<< - it's part of the customers solution that it should be done this way - first copied, then renamed - it's because of the way their system picks up the orders from the ftp server - >>

  Only thing I can think of is that they are trying to avoid picking up a partial file (reading it as it is being uploaded).   Uploading it and then shifting it to another directory is basically an atomic operation, so by doing that they are ensuring that the upload is complet before they try to grab it.

Jim.
0
 
LVL 1

Author Comment

by:Bojerne
ID: 37787035
Yes, thats exactly what theyre triyng to avoid - reading a partially uploaded file :)

My sDir and sDirRen alreay contains a "/" so that can't be the problem I guess :) Any other ideas ?
0
 
LVL 57
ID: 37787132
Try it this way:

If sDirRen <> sDir And FTPFile Then
        Call FtpRenameFile(hConnection, RemoteFileName, sDirRen & RemoteFileName)
End If

  Beyond that, no, no more ideas.  I typically don't use the wininet.dll, but even so, the only way I know to "move" a file on a FTP server from one directory to another is with the rename command, but not all clients/servers support that either.

Jim.
0
 
LVL 1

Author Comment

by:Bojerne
ID: 37787499
I've now tried the command manually and directly on the ftp server and can't make it work there - so maybe it's not the code :) ?
0
 
LVL 57
ID: 37787684
<<I've now tried the command manually and directly on the ftp server and can't make it work there - so maybe it's not the code :) ?>>

 Sounds like a server issue then if you can'y rename it manually with a client.  I would ask them what server software they are running and version, then find out if it supports the rename command.

Jim.
0
 
LVL 1

Author Comment

by:Bojerne
ID: 37790585
It was them who requested the rename procedure, so I've asked them why it fails when trying to do it manually.

Thank you for the advice
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A little background as to how I came to I design this code: Around 5 years ago I designed an add-in that formatted Excel files to a corporate standard, applying different cell colours and font type depending on whether the cells contained inputs,…
Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
The viewer will learn how to create two correlated normally distributed random variables in Excel, use a normal distribution to simulate the return on different levels of investment in each of the two funds over a period of ten years, and, create a …
This Micro Tutorial demonstrate the bugs in Microsoft Excel for Mac with Pivot Charts.

808 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question