You can do this using forcetk if you are planning to do this in javascript
here is sample code -
<apex:page docType="html-5.0" title="File Uploader">
Select a file to upload as a new Chatter File.
var client = new forcetk.Client();
client.setSessionToken('{!$Api.Session_ID}');
function upload() {
var file = $("#file")[0].files[0];
client.createBlob('ContentVersion', {
Origin: 'H', // 'H' for Chatter File, 'C' for Content Document
PathOnClient: file.name
}, file.name, 'VersionData', file, function(response){
console.log(response);
$("#message").html("Chatter File created: <a target=\"_blank\" href=\"/" + response.id + "\">Take a look!</a>");
}, function(request, status, response){
$("#message").html("Error: " + status);
});
}
here is internal forcetk implementation for sf blob [link - https://github.com/developerforce/Force.com-JavaScript-REST-Toolkit/blob/master/forcetk.js] -
/* Low level function to create/update records with blob data
* @param path resource path relative to /services/data
* @param fields an object containing initial field names and values for
* the record, e.g. {ContentDocumentId: "069D00000000so2",
* PathOnClient: "Q1 Sales Brochure.pdf"}
* @param filename filename for blob data; e.g. "Q1 Sales Brochure.pdf"
* @param payloadField 'VersionData' for ContentVersion, 'Body' for Document
* @param payload Blob, File, ArrayBuffer (Typed Array), or String payload
* @param callback function to which response will be passed
* @param [error=null] function to which response will be passed in case of error
* @param retry true if we've already tried refresh token flow once
*/
forcetk.Client.prototype.blob = function(path, fields, filename, payloadField, payload, callback, error, retry) {
var that = this;
var url = (this.visualforce ? '' : this.instanceUrl) + '/services/data' + path;
var boundary = randomString();
var blob = new Blob([
"--boundary_" + boundary + '\n'
+ "Content-Disposition: form-data; name=\"entity_content\";" + "\n"
+ "Content-Type: application/json" + "\n\n"
+ JSON.stringify(fields)
+ "\n\n"
+ "--boundary_" + boundary + "\n"
+ "Content-Type: application/octet-stream" + "\n"
+ "Content-Disposition: form-data; name=\"" + payloadField
+ "\"; filename=\"" + filename + "\"\n\n",
payload,
"\n\n"
+ "--boundary_" + boundary + "--"
], {type : 'multipart/form-data; boundary=\"boundary_' + boundary + '\"'});
var request = new XMLHttpRequest();
request.open("POST", (this.proxyUrl !== null && ! this.visualforce) ? this.proxyUrl: url, this.asyncAjax);
request.setRequestHeader('Accept', 'application/json');
request.setRequestHeader(this.authzHeader, "Bearer " + this.sessionId);
request.setRequestHeader('X-User-Agent', 'salesforce-toolkit-rest-javascript/' + this.apiVersion);
if (this.proxyUrl !== null && ! this.visualforce) {
request.setRequestHeader('SalesforceProxy-Endpoint', url);
}
if (this.asyncAjax) {
request.onreadystatechange = function() {
// continue if the process is completed
if (request.readyState == 4) {
// continue only if HTTP status is good
if (request.status >= 200 && request.status < 300) {
// retrieve the response
callback(request.response ? JSON.parse(request.response) : null);
} else if(request.status == 401 && !retry) {
that.refreshAccessToken(function(oauthResponse) {
that.setSessionToken(oauthResponse.access_token, null,oauthResponse.instance_url);
that.blob(path, fields, fileName, file, callback, error, true);
},
error);
} else {
// return status message
error(request, request.statusText, request.response);
}
}
}
}
request.send(blob);
return this.asyncAjax ? null : JSON.parse(request.response);
}
I can see in the source for BulkConnection the version of createBatchWithFileAttachments
you are calling.
That method attempts to use the string file as a path relative to the rootDirectory
. That wouldn't make so much sense for a URL.
Instead have a look at the alternative method:
public BatchInfo createBatchWithInputStreamAttachments(JobInfo jobInfo, InputStream batchContent,
Map<String, InputStream> attachments)
You will need to create your own InputStream for each file or URL to pull them in appropriately.
Best Answer
Blob
class so we cannot tell. (The size that the Blob class reports is the size of the original data.) Salesforce do count the space used as "File Storage" rather than "Data Storage" though.