问题
I have an SSIS package that im building in BIDS. Currently my control flow pulls a Uri and Folder Destination out of a table, downloads the Uri to the given destination. What I would like to do is update that table with the filesize. the source table looks like this:
SourceUri | SourceName | Destination | Date | DownloadCount| FileSize
I've tried to get the filesize via the Uri Headers but it doesn't seem to work, is there a Task i could add that would get the filesize for my downloaded uri ( i already have the filename and the destination in variables) ?
Thanks
回答1:
You can make use of System.IO.FileInfo
to get the file size from within SSIS Script Task
. Following example shows how this can be achieved. The example was created in SSIS 2008 R2
.
Step-by-step process:
On the SSIS package's connection create an OLE DB connection to connect to the SQL Server as shown in screenshot #1. I have named the connection as SQLServer.
In the SQL Server database, create a table named
dbo.Downloads
and populate with records using the scripts given under SQL Scripts section. Screenshot #2 shows data in the table.On the SSIS package, create 8 variables as shown in screenshot #3. Set the variable LocalFolder with value
c:\temp\
. Set the variable SQLGetData with valueSELECT Id, SourceUri, SourceName FROM dbo.Downloads
. Set the variable SQLUpdate with valueUPDATE dbo.Downloads SET Destination = ?, Date = GETDATE(), DownloadCount = COALESCE(DownloadCount, 0) + 1, FileSize = ? WHERE Id = ?
.On the package's Control Flow tab, place an Execute SQL Task, Foreach loop container, and Script Task & Execute SQL Task within Foreach Loop container as shown in screenshot #4.
Configure the first Execute SQL Task named 'Get data' as shown in screenshots #5 and #6. This task with fetch the records and store it in an Object variable.
Configure the Foreach Loop container as shown in screenshots #7 and #8. This task will loop through the resultset.
Replace the Main() method within the script task with the code provided under the Script Task Code section. The code uses the
System.IO.FileInfo
object to fetch the file size after it has been downloaded.Configure the second Execute SQL Task named 'Update' as shown in screenshots #9 and #10. This task will update the database after the file downloads.
Screenshot #11 shows that the folder path
C:\temp\
is empty before the package execution.Screenshot #12 shows package execution.
Screenshot #13 shows that the folder path
C:\temp\
contains the downloaded contents after the package execution.Screenshot #14 shows data in table dbo.Downloads after package execution. Screenshots #15 and #16 show the properties of the downloaded files. Note the file size updated in the table with the file size on the properties dialog.
NOTE
: System.IO.File will fetch only the Size and not Size on disk. The file size updated in the database table is in bytes.Screenshot #17 shows that the folder path
C:\temp\
contains the downloaded contents after the second package execution. Note the DownloadCount value.
Hope that helps.
SQL Scripts:
CREATE TABLE [dbo].[Downloads](
[Id] [int] IDENTITY(1,1) NOT NULL,
[SourceUri] [varchar](255) NOT NULL,
[SourceName] [varchar](255) NOT NULL,
[Destination] [varchar](255) NULL,
[Date] [datetime] NULL,
[DownloadCount] [int] NULL,
[FileSize] [int] NULL,
CONSTRAINT [PK_Downloads] PRIMARY KEY CLUSTERED ([Id] ASC)) ON [PRIMARY]
GO
INSERT INTO dbo.Downloads (SourceUri, SourceName) VALUES
('http://www.google.com/intl/en_com/images/srpr/', 'logo1w.png'),
('http://upload.wikimedia.org/wikipedia/commons/6/63/', 'Wikipedia-logo.png');
GO
Script task code:
C# code that can be used only in SSIS 2008 and above
.
public void Main()
{
Variables varCollection = null;
Dts.VariableDispenser.LockForRead("User::SourceUri");
Dts.VariableDispenser.LockForRead("User::SourceName");
Dts.VariableDispenser.LockForRead("User::LocalFolder");
Dts.VariableDispenser.LockForWrite("User::Destination");
Dts.VariableDispenser.LockForWrite("User::FileSize");
Dts.VariableDispenser.GetVariables(ref varCollection);
System.Net.WebClient myWebClient = new System.Net.WebClient();
string sourceUri = varCollection["User::SourceUri"].Value.ToString();
string sourceName = varCollection["User::SourceName"].Value.ToString();
string webResource = sourceUri + sourceName;
string fileName = varCollection["User::LocalFolder"].Value.ToString() + sourceName;
myWebClient.DownloadFile(webResource, fileName);
System.IO.FileInfo fileInfo = new System.IO.FileInfo(fileName);
varCollection["User::Destination"].Value = fileName;
varCollection["User::FileSize"].Value = Convert.ToInt32(fileInfo.Length);
Dts.TaskResult = (int)ScriptResults.Success;
}
Screenshot #1:
Screenshot #2:
Screenshot #3:
Screenshot #4:
Screenshot #5:
Screenshot #6:
Screenshot #7:
Screenshot #8:
Screenshot #9:
Screenshot #10:
Screenshot #11:
Screenshot #12:
Screenshot #13:
Screenshot #14:
Screenshot #15:
Screenshot #16:
Screenshot #17:
回答2:
After downloading the file, you can use a script task to get the file size or any other information you need using the standard .NET FileInfo class and save it to a package variable.
来源:https://stackoverflow.com/questions/6698448/need-to-get-filesize-via-ssis-package-task