Reputation: 563
I am trying to upload an UTF-8 text file to a server in Blackberry. The upload works great but when I check the file in the server it's an ASCII file and what I need is an UTF-8 file.
This is the code that I use when I create the file:
FileConnection fc = (FileConnection)Connector.open(fileName);
if (!fc.exists()){
fc.create();
}
long byteOffset = fc.usedSize();
OutputStream outStream = fc.openOutputStream(byteOffset);
outStream.write(line.getBytes("UTF-8"));
outStream.close();
fc.close();
To send the file I use this:
public void run (){
httpConnection = null;
_connectionURL = null;
String lineEnd = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
int rc = -1;
OutputStream os = null;
try {
_connectionURL = Constants.UPLOAD_URL + getConnectionString();
httpConnection = (HttpConnection)Connector.open(_connectionURL);
byte [] postDataBytes = getData();
httpConnection.setRequestMethod("POST");
httpConnection.setRequestProperty("Connection", "Keep-Alive");
httpConnection.setRequestProperty("User-Agent", "BlackBerry");
httpConnection.setRequestProperty("Content-Type", "multipart/form-data;boundary=*****");
httpConnection.setRequestProperty(HttpProtocolConstants.HEADER_CONTENT_LANGUAGE, "en-US");
httpConnection.setRequestProperty(HttpProtocolConstants.HEADER_CACHE_CONTROL,"no-cache, no-store, no-transform");
os = httpConnection.openOutputStream();
os.write((twoHyphens + boundary + lineEnd).getBytes());
os.write(("Content-Disposition: form-data; name=\"uploadedfile\";filename=\"" + fileName +"\"" + lineEnd).getBytes());
os.write(lineEnd.getBytes());
os.write(postDataBytes);
os.write(lineEnd.getBytes());
os.write((twoHyphens + boundary + twoHyphens + lineEnd).getBytes());
os.flush();
// Response
rc = httpConnection.getResponseCode();
InputStream in = httpConnection.openInputStream();
int ch;
StringBuffer stringBuffer = new StringBuffer();
while( ( ch = in.read() ) != -1 ){
stringBuffer.append( (char)ch );
}
String responseString = stringBuffer.toString();
...
}catch (IOException ioe){
...
}
}
...
private byte[] getData() throws IOException {
int _c;
StringBuffer _stringBuffer = new StringBuffer("UTF-8");
FileConnection fileForUpload = (FileConnection) Connector.open(Constants.FOLDER_FILES+this.fileName, Connector.READ);
this.fileInputStream = fileForUpload.openDataInputStream();
this.postData = new URLEncodedPostData("UTF-8", false);
while( (_c = this.fileInputStream.read()) != -1){
_stringBuffer.append((char)_c);
}
postData.setData(_stringBuffer);
byte [] _postData = postData.getBytes();
fileForUpload.close();
return _postData;
}
I guess there is something wrong in getData() method or in the httpConnection properties, but i don't know what is it.
Thanks for your help
Upvotes: 0
Views: 333
Reputation: 28418
In addition to Jon Skeet's answer.
To read byte array from file you can simply use net.rim.device.api.io.IOUtilities
:
FileConnection fileForUpload =
(FileConnection) Connector.open(path, Connector.READ);
InputStream stream = fileForUpload.openInputStream();
byte[] data = IOUtilities.streamToBytes(stream);
Upvotes: 2
Reputation: 1500525
Look at this code, which appears twice:
while( ( ch = in.read() ) != -1 ){
stringBuffer.append( (char)ch );
}
That's treating each byte as a separate character, effectively in ISO-8859-1.
If you really want to convert the content to text, you should be using an InputStreamReader
with an encoding of UTF-8, then ideally reading blocks of characters (rather than one character at a time).
This isn't helping either:
byte [] _postData = postData.getBytes();
That will be using the platform default encoding to convert a string to bytes - that's almost never what you want.
Given that your getData
method is trying to read a file as a byte array, you shouldn't be converting it to text at all, IMO. If you know the file length beforehand, you should just create a byte array of the right size and repeatedly call InputStream.read(byte[], int, int)
, noting the return value to see how far you've read. If you don't, you can repeatedly read into a smallish buffer, then write the data you've just read into a ByteArrayOutputStream
which you can later get the byte array from.
Additionally, you don't appear to ever close any of your streams - which you should do in finally
statements, so that the streams are closed even if an exception is thrown.
Upvotes: 2