Forum Discussion
Nicolas_Menant
Employee
Mar 20, 2008Structure FileTransferContext and file_data
Hi,
i try to create an windows API to retrieve an external class from a BIGIP, update it and then upload it again on the box.
I have something that seems strange:
in the SDK for the structure FileTransferContext it says that file_data is of type char[]
or when i try to compile my code it says: cannot implicity convert type 'string' to 'byte[]'.
When i did the download of the file i had to make an explicit cast (char) FTC.file_data[j] to make it work.
Is it possible the SDK is wrong or am i missing something (which is quite possible since i have developped anything since a long long time)
Thanks for your help!
Here is part of my code:
iControl.SystemConfigSyncFileTransferContext FTC = new iControl.SystemConfigSyncFileTransferContext();
int exit = 0;
int i, j;
string element;
for (i = 0; i < listBox_class.Items.Count; i++)
{
element = "\""+listBox_class.Items[\i].ToString()+"\",\n";
FTC.file_data = new byte[element.Length];
for (j = 0; j < element.Length; j++)
FTC.file_data[j] = (byte)((int)element[j]);
if (j == 0)
FTC.chain_type = iControl.CommonFileChainType.FILE_FIRST_AND_LAST;
else if (j == (element.Length - 1))
FTC.chain_type = iControl.CommonFileChainType.FILE_MIDDLE;
else
FTC.chain_type = iControl.CommonFileChainType.FILE_LAST;
element = element.Remove(0);
my_interface.SystemConfigSync.upload_file(filename, FTC);
}
Another question:
When i use upload_file, it looks like it appends the new data to the existing file, is it possible to make it overwrite the previous file ? or do i have to delete the file before doing the upload ?
Thanks
4 Replies
- char[] is the happy medium I took on the SDK to cover all languages. Essentially it will be converted to a base64 string across the wire so for .NET that would be an array of bytes (byte[]).
There is a sample in the SDK for ConfigSync that illustrates most of the ConfigSync interfaces. Since your code looks like C, here's the routine in ConfigSyncMain.cs file in the SDK's ConfigSync sample:void handle_upload(string local_file, string config_name) { ConfigSync.SystemConfigSyncFileTransferContext ctx = new ConfigSync.SystemConfigSyncFileTransferContext(); bool bContinue = true; ctx.chain_type = CommonFileChainType.FILE_FIRST; long chunk_size = 1024; long total_bytes = 0; FileStream fs = new FileStream(local_file, FileMode.Open); BinaryReader r = new BinaryReader(fs); while (bContinue) { ctx.file_data = r.ReadBytes(Convert.ToInt32(chunk_size)); if ( ctx.file_data.Length != chunk_size ) { // At the end. Check to see if it is the first request also. if ( 0 == total_bytes ) { ctx.chain_type = CommonFileChainType.FILE_FIRST_AND_LAST; } else { ctx.chain_type = CommonFileChainType.FILE_LAST; } bContinue = false; } total_bytes += ctx.file_data.Length; // Upload bytes. ConfigSync.upload_configuration(config_name, ctx); // Move to middle ctx.chain_type = CommonFileChainType.FILE_MIDDLE; Console.WriteLine("Uploaded " + total_bytes + " bytes"); } }
Now, this uses the upload_configuration() method, but the upload_file() method works the same way. Also, this doesn't do you much good if you want to use a string (as opposed to a file read with BinaryReader) as input. To get a byte array from a string, you'll want to use the System.Text.ASCIIEncoding classes GetBytes() method. Here's a wrapper function that converts a string into a byte array.public static byte[] StrToByteArray(string str) { System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding(); return encoding.GetBytes(str); }
Also, this method shows how to "chunk" up the request's for very large uploads. Feel free to change "chunk_size" to something very large (or even the size of the input string) to make it all go in one shot.
To answer why your code always appends the data to the file, I don't see where your first write is using the FILE_FIRST or FILE_FIRST_OR_LAST chain type. This will tell the server to truncate the existing file before the write of the data. If you have FILE_MIDDLE or FILE_LAST as the first write, it will append to the file.
If you want a simple function that takes input as a string and uploads the entire string in one shot, this should do it for you (making use of the above conversion method)void uploadStringToFile(String target_file, String contents) { iControl.SystemConfigSyncFileTransferContext ctx = new iControl.SystemConfigSyncFileTransferContext(); ctx.file_data = StrToByteArray(contents); ctx.chain_type = iControl.CommonFileChainType.FILE_FIRST_AND_LAST; m_interfaces.SystemConfigSync.upload_file(target_file, ctx); }
Make sense?
-Joe - Nicolas_Menant
Employee
Hi,
It makes perfect sense! Thanks
i made a mistake by putting FILE_FIRST_AND_LAST instead of FILE_FIRST ><
and thanks for the function to translate a string in byte[].
I guess i'll need to check all those translation type!
Thanks again - safiyet_80777
Nimbostratus
Hi,
I want to this process with perl. How can I do?
Thanks. - Take a look at the PerlConfigSync sample in the iControl CodeShare. That may point you in the right direction.
http://devcentral.f5.com/wiki/iControl.PerlConfigSync.ashx
-Joe
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)Recent Discussions
Related Content
DevCentral Quicklinks
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com
Discover DevCentral Connects