How to convert AppEngineFile to an array of bytes?
I have my File created from the blobkey like this
AppEngineFile file = fileService.getBlobFile(new BlobKey("blob key"));
I already tried something like this
FileService fileService = FileServiceFactory.getFileService();
// Create a new Blob file with mime-type "text/plain"
AppEngineFile file = fileService.getBlobFile(new BlobKey(video.getBlobkey()));
BlobstoreInputStream b = new BlobstoreInputStream(new BlobKey(video.getBlobkey()));
RandomAccessFile f = new RandomAccessFile(file.getFullPath(), "r");
byte[] pixels = b.read(); //doesn't work
The idea is to send this array of bytes with a POST request.
Here is my code i have to build the request:
String attachmentName = "test";
String attachmentFileName = "test.mp4";
String crlf = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
HttpURLConnection httpUrlConnection = null;
URL url = new URL("http://example.com/server.cgi");
httpUrlConnection = (HttpURLConnection) url.openConnection();
httpUrlConnection.setUseCaches(false);
httpUrlConnection.setDoOutput(true);
DataOutputStream request = new DataOutputStream(httpUrlConnection.getOutputStream());
request.writeBytes(twoHyphens + boundary + crlf);
request.writeBytes("Content-Disposition: form-data; name=\"" + attachmentName + "\";filename=\"" + attachmentFileName + "\"" + crlf);
request.writeBytes(crlf);
// Get a file service
FileService fileService = FileServiceFactory.getFileService();
// Create a new Blob file with mime-type "text/plain"
AppEngineFile file = fileService.getBlobFile(new BlobKey(video.getBlobkey()));
BlobstoreInputStream b = new BlobstoreInputStream(new BlobKey(video.getBlobkey()));
RandomAccessFile f = new RandomAccessFile(file.getFullPath(), "r");
byte[] pixels = b.read();
request.write(pixels);
request.writeBytes(crlf);
request.writeBytes(twoHyphens + boundary + twoHyphens + crlf);
request.flush();
request.close();
InputStream responseStream = new BufferedInputStream(httpUrlConnection.getInputStream());
BufferedReader responseStreamReader = new BufferedReader(new InputStreamReader(responseStream));
String line = "";
StringBuilder stringBuilder = new StringBuilder();
while ((line = responseStreamReader.readLine()) != null)
{
stringBuilder.append(line).append("\n");
}
responseStreamReader.close();
String response = stringBuilder.toString();
System.out.println(response);
You can simply do this:
FileReadChannel ch = fileservice.openReadChannel(file, true);
byte[] data = getBytes(Channels.newInputStream(ch));
and use this handy method (useable elsewhere):
public static byte[] getBytes(InputStream is) throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int len;
byte[] data = new byte[100000]; // adapt buffer size to your needs
while ((len = is.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, len);
}
buffer.flush();
return buffer.toByteArray();
}
AppEngineFile file = ...
int size = (int) fileservice.stat(file).getLength().longValue();
FileReadChannel ch = fileservice.openReadChannel(file, true);
ByteBuffer dst = ByteBuffer.allocate(size);
try {
int sum=0;
while (sum<size) {
int read = ch.read(dst);
sum+=read;
}
} finally {ch.close();}
bytes byte[] = dst.array();
(This is NOT the way of reading from a Channel in Java, but it seems there is a bug in appengine that requires you know the exact count of bytes).
Related
I have FileDownloader class that downloads the file from google drive and than these files can be used by other classes. I need also to extract filename somehow. The problem is that this solution below works good for direct links, but it doesn't work when links are shorten with bit.ly for example...
Could you please advise how I can change the code to get the right file name?
public class FileDownloader {
private static final int BUFFER_SIZE = 4096;
public static void downloadFile(String fileURL, String saveDir)
throws IOException {
URL url = new URL(fileURL);
HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
int responseCode = httpConn.getResponseCode();
// checking HTTP response code first
if (responseCode == HttpURLConnection.HTTP_OK) {
String fileName = "";
String disposition = httpConn.getHeaderField("Content-Disposition");
String contentType = httpConn.getContentType();
int contentLength = httpConn.getContentLength();
if (disposition != null) {
// extracts file name from header field
int index = disposition.indexOf("filename*=UTF-8''");
if (index > 0) {
fileName = disposition.substring(index + 17,
disposition.length());
}
} else {
// extracts file name from URL
fileName = fileURL.substring(fileURL.lastIndexOf("/") + 1,
fileURL.length());
}
System.out.println("Content-Type = " + contentType);
System.out.println("Content-Disposition = " + disposition);
System.out.println("Content-Length = " + contentLength);
System.out.println("fileName = " + fileName);
// opens input stream from the HTTP connection
InputStream inputStream = httpConn.getInputStream();
String saveFilePath = saveDir + File.separator + fileName;
// opens an output stream to save into file
FileOutputStream outputStream = new FileOutputStream(saveFilePath);
int bytesRead = -1;
byte[] buffer = new byte[BUFFER_SIZE];
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
outputStream.close();
inputStream.close();
System.out.println("File downloaded");
} else {
System.out.println("No file to download. Server replied HTTP code: " + responseCode);
}
httpConn.disconnect();
}
Alternate Code to get File details from any HTTP URL using Java API:
URL url = new URL("http://www.example.com/somepath/filename.extension");
System.out.println(FilenameUtils.getBaseName(url.getPath()));
// filename
System.out.println(FilenameUtils.getName(url.getPath()));
// filename.extension
I am using the S3 REST API as I do not want to use the 100+ MB Java SDK for a simple file upload. I am having a little trouble here setting the ACL while uploading a text file. The code gives a response OK without the marked line below but that leaves the ACL to private read only. I want to make the file public by adding the marked line. But that gives me a Forbidden message. Any help here?
int BUFFER_SIZE = 4096;
String name = "file.txt";
String method = "PUT";
String bucket = "bucket";
String secretKey = "******";
String filePath = "F:\\file.txt";
SimpleDateFormat df = new SimpleDateFormat("EEE', 'dd' 'MMM' 'yyyy' 'HH:mm:ss' 'Z", Locale.US);
Date date = new Date();
String formattedDate = df.format(date);
File uploadFile = new File(filePath);
URL url = new URL("http://bucket.s3.amazonaws.com/" + name);
HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
String resource = "/" + bucket + "/" + name;
String contentType = "text/plain";
String signn = method + "\n\n" + contentType + "\n" + formattedDate + "\n" + resource ;
Mac hmac = Mac.getInstance("HmacSHA1");
hmac.init(new SecretKeySpec(
secretKey.getBytes("UTF-8"), "HmacSHA1"));
String signature = (new BASE64Encoder()).encode(
hmac.doFinal(signn.getBytes("UTF-8"))).replaceAll("\n", "");
String authAWS = "AWS " + "**SECRET**" + ":" + signature;
httpConn.setDoOutput(true);
httpConn.setRequestMethod(method);
httpConn.setRequestProperty("Accept", "*/*");
httpConn.setRequestProperty("Date", formattedDate);
httpConn.setRequestProperty("Content-type", contentType);
httpConn.setRequestProperty("Authorization", authAWS);
httpConn.setRequestProperty("x-amz-acl", "public-read"); // <----- THIS LINE HERE!
OutputStream outputStream = httpConn.getOutputStream();
FileInputStream inputStream = new FileInputStream(uploadFile);
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead = -1;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
outputStream.close();
inputStream.close();
System.out.println("Response message : " + httpConn.getResponseMessage());
I want to upload an image to FTP Server. Currently i am using JDeveloper 12c(12.1.3.0).
My Code:
private static final int BUFFER_SIZE = 4096;
public String fileUploadMethod(String imagePath){
String ftpUrl = "ftp://";
String host = "http://192.168.0.42";
String user = "XXXXXX";
String pass = "XXXXXX";
String filePath = "783771-1.jpg";
String uploadPath = imagePath;
ftpUrl =ftpUrl + user +":"+ pass+"#"+host+"/"+filePath+";";
System.out.println("Upload URL: " + ftpUrl);
try {
URL url = new URL(ftpUrl);
URLConnection conn = url.openConnection();
OutputStream outputStream = conn.getOutputStream();
FileInputStream inputStream = new FileInputStream(uploadPath);
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead = -1;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
inputStream.close();
outputStream.close();
System.out.println("File uploaded");
return "File uploaded";
} catch (IOException ex) {
ex.printStackTrace();
}
return null;
}
I am getting an error MalFormedURLException i.e. in detail message "unknown protocol:ftp"
Is there any other option to upload an image using JDeveloper.
Any idea regarding this.
Thanks, Siddharth
Your ftpUrl is wrong. Remove http:// in the host variable. Should be ok then
I haven't really tried ftp upload. But I had tried with multipart form upload. As far as I know, MAF doesnt provide Out-Of-Box support for file upload. What I did was essential recreating the HTTP stream for the image upload.
The POC code is attached below. This may be definitely the CRUDEST implementation but I am not sure if there is a better way.
public void doUpload() {
try {
DeviceManager dm = DeviceManagerFactory.getDeviceManager();
String imgData =
dm.getPicture(50, DeviceManager.CAMERA_DESTINATIONTYPE_FILE_URI, DeviceManager.CAMERA_SOURCETYPE_CAMERA,
false, DeviceManager.CAMERA_ENCODINGTYPE_PNG, 0, 0);
imgData = imgData.substring(7, imgData.length());
int start = imgData.lastIndexOf('/');
String fileName = imgData.substring(start+1, imgData.length());
RestServiceAdapter restServiceAdapter = Model.createRestServiceAdapter();
restServiceAdapter.clearRequestProperties();
String requestMethod = RestServiceAdapter.REQUEST_TYPE_POST;
String requestEndPoint = restServiceAdapter.getConnectionEndPoint("serverBaseUrl");
String requestURI = "/workers/100000018080264";
String request = requestEndPoint + requestURI;
HashMap httpHeadersValue = new HashMap();
httpHeadersValue.put("X-ANTICSRF", "TRUE");
httpHeadersValue.put("Connection", "Keep-Alive");
httpHeadersValue.put("content-type","multipart/form-data; boundary=----------------------------4abf1aa47e18");
// Get the connection
HttpConnection connection = restServiceAdapter.getHttpConnection(requestMethod, request, httpHeadersValue);
OutputStream os = connection.openOutputStream();
byte byteBuffer[] = new byte[50];
int len;
//String temp is appended before the image body
String temp = "------------------------------4abf1aa47e18\r\nContent-Disposition: form-data; name=\"file\"; filename=\"" +fileName+ "\"\r\nContent-Type: image/jpeg\r\n\r\n";
InputStream stream = new ByteArrayInputStream(temp.getBytes("UTF-8"));
if (stream != null) {
while ((len = stream.read(byteBuffer)) >= 0) {
os.write(byteBuffer, 0, len);
}
stream.close();
}
FileInputStream in = new FileInputStream(imgData);
if (in != null) {
while ((len = in.read(byteBuffer)) >= 0) {
os.write(byteBuffer, 0, len);
}
in.close();
}
//The below String is appended after the image body
InputStream stream2 =new ByteArrayInputStream("\r\n------------------------------4abf1aa47e18--\r\n".getBytes("UTF-8"));
if (stream2 != null) {
while ((len = stream2.read(byteBuffer)) >= 0) {
os.write(byteBuffer, 0, len);
}
stream2.close();
}
int status = connection.getResponseCode();
InputStream inputStream = restServiceAdapter.getInputStream(connection);
ByteArrayOutputStream incomingBytes = new ByteArrayOutputStream() // get and process the response.
while ((len = inputStream.read(byteBuffer)) >= 0) {
incomingBytes.write(byteBuffer, 0, len);
}
String ret = incomingBytes.toString();
incomingBytes.close();
} catch (Exception e) {
e.printStackTrace();
}
}
I am trying to upload a file to a server with following code, the upload works, but the payload is added to the file, you can see it for example uploading a text file:
private Integer doFileUpload(final String urlServer) {
HttpURLConnection connection = null;
DataOutputStream outputStream = null;
FileInputStream fileInputStream = null;
final String pathToOurFile = mFileInfo.getProviderPath();
final String lineEnd = "\r\n";
final String twoHyphens = "--";
final String boundary = "*****";
int fileLength;
int bytesToRead, bufferSize;
final long fileSize;
byte[] buffer;
final int maxBufferSize = 1 * 1024 * 1024;
try {
final File file = new File(pathToOurFile);
fileInputStream = new FileInputStream(file);
final URL url = new URL(urlServer);
connection = (HttpURLConnection) url.openConnection();
final String[] payload = { twoHyphens + boundary + lineEnd,
"Content-Disposition: form-data; name=\"uploadedfile\";filename=\"" + pathToOurFile + "\"" + lineEnd, lineEnd, lineEnd,
twoHyphens + boundary + twoHyphens + lineEnd };
int payloadLength = 0;
for (final String string : payload) {
payloadLength += string.getBytes("UTF-8").length;
}
Logger.d(AsyncEgnyteUploadFile.LOGGING_TAG, "payload length: " + payloadLength);
fileLength = (int) file.length();
Logger.d(AsyncEgnyteUploadFile.LOGGING_TAG, "bytes: " + fileLength);
connection.setFixedLengthStreamingMode(fileLength + payloadLength);
fileSize = fileLength;
// Allow Inputs & Outputs
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
connection.setReadTimeout(5000);
connection.setConnectTimeout(5000);
connection.setRequestProperty("Authorization", "Bearer " + mToken);
// Enable POST method
connection.setRequestMethod(HttpPost.METHOD_NAME);
connection.setRequestProperty("Connection", "close");
// This header doesn't count to the number of bytes being sent.
connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
connection.connect();
outputStream = new DataOutputStream(connection.getOutputStream());
outputStream.writeBytes(payload[0]);
outputStream.writeBytes(payload[1]);
outputStream.writeBytes(payload[2]);
bufferSize = Math.min(fileLength, maxBufferSize);
buffer = new byte[bufferSize];
long totalBytesRead = 0;
long lastProgressTime = 0;
// Read file
bytesToRead = fileInputStream.read(buffer, 0, bufferSize);
boolean stopUploading = (FileState.UPLOADING != mFileInfo.getState() || isCancelled());
while (bytesToRead > 0 && !stopUploading)
{
outputStream.write(buffer);
totalBytesRead += bytesToRead;
Logger.d(AsyncEgnyteUploadFile.LOGGING_TAG, "bytes written: " + totalBytesRead);
final long now = System.currentTimeMillis();
bufferSize = (int) Math.min(fileLength - totalBytesRead, maxBufferSize);
buffer = new byte[bufferSize];
bytesToRead = fileInputStream.read(buffer, 0, bufferSize);
}
outputStream.writeBytes(payload[3]);
outputStream.writeBytes(payload[4]);
// Responses from the server (code and message)
final int serverResponseCode = connection.getResponseCode();
if (serverResponseCode == HttpStatus.SC_OK || serverResponseCode == HttpStatus.SC_CREATED) {
mAlreadyUploaded = true;
return JBError.JBERR_SUCCESS;
} else {
Log.e(AsyncEgnyteUploadFile.LOGGING_TAG, "error code: " + serverResponseCode);
return serverResponseCode;
}
} catch (final SocketTimeoutException e) {
..
} catch (final UnknownHostException e) {
..
} catch (final SocketException e) {
..
} catch (final IOException e) {
..
} catch (final Exception ex) {
..
} finally {
closeAll(connection, fileInputStream, outputStream);
}
}
Uploading a text file with only 12345 inside with this code results in following:
--*****
Content-Disposition: form-data; name="uploadedfile";filename="/storage/emulated/0/Download/3.txt"
12345
--*****--
What am I doing wrong?
You copy code is wrong. This is how to copy between streams in Java:
while ((count = in.read(buffer)) > 0)
{
out.write(buffer, 0, count);
}
Notes:
You must check all reads for end of stream.
You must use the read count in the write() method.
You don't need a new buffer per read, and you don't need a buffer the size of the file. This will work with any buffer size greater than zero. I usually use 8192.
I suspect that your server is not designed / configured to handle "multi-part" uploads.
It certainly looks like it is treating this as a plain upload ... and I cannot see anything wring with the multi-part encapsulation.
(EJP is correct, but that is not what is causing your problem here. Your example shows that all of the characters were sent ...)
public static String fileUploadFromPath(String url, String path) throws Throwable {
System.out.println("IN fileUploadFromPath ");
String responseData = "";
String NL = System.getProperty("line.separator");
try {
System.out.println("url ************ " + url);
File file = new File(path);
System.out.println("file ************ " + file.getAbsolutePath()
+ " : " + file.exists());
StringBuilder text = new StringBuilder();
if (file.exists()) {
BufferedReader br = new BufferedReader(new FileReader(file));
String line;
while ((line = br.readLine()) != null) {
text.append(line);
text.append(NL);
}
HttpClient httpClient = new DefaultHttpClient();
HttpPost postRequest = new HttpPost(url);
// System.out.println("postRequest ************ " +
// postRequest);
MultipartEntity multipartContent = new MultipartEntity();
ByteArrayBody key = new ByteArrayBody(text.toString()
.getBytes(), AgricultureUtils.getInstance()
.getTimeStamp() + ".3gp");
multipartContent.addPart(AgricultureUtils.getInstance()
.getTimeStamp() + ".3gp", key);
postRequest.setEntity(multipartContent);
HttpResponse response = httpClient.execute(postRequest);
BufferedReader in = new BufferedReader(new InputStreamReader(
response.getEntity().getContent()));
StringBuffer sb = new StringBuffer("");
String content = "";
while ((content = in.readLine()) != null) {
sb.append(content + NL);
}
in.close();
/*
* File myDir = new File(Constants.dirctory); if
* (!myDir.exists()) { myDir.mkdirs(); } File myFile = new
* File(myDir, fileName); FileOutputStream mFileOutStream = new
* FileOutputStream(myFile);
* mFileOutStream.write(sb.toString().getBytes());
* mFileOutStream.flush(); mFileOutStream.close();
*/
System.out.println("response " + sb);
}
} catch (Throwable e) {
System.out.println("Exception In Webservice ----- " + e);
throw e;
}
return responseData;
}
I want to upload an audio file into server.
I am able upload audio file to server through above code but the file is not working(not playing in system). If u have any idea please help me.
You should be using neither FileReader nor StringBuilder here as it treats the data as characters (encoded according to the default system character set). Really, you should not be using a Reader at all. Binary data should be handled via InputStream, e.g.
final ByteArrayOutputStream out = new ByteArrayOutputStream();
try (final InputStream in = new FileInputStream(file)) {
final byte[] buf = new byte[2048];
int n;
while ((n = in.read(buf)) >= 0) {
out.write(buf, 0, n);
}
}
final byte[] data = out.toByteArray();
Did you check checksum on server? Is it arriving unmodified?
If not, try other method to post files. This one helped me a lot:
/**
* Post request (upload files)
* #param sUrl
* #param params Form data
* #param files
* #return
*/
public static HttpData post(String sUrl, Hashtable<String, String> params, ArrayList<File> files) {
HttpData ret = new HttpData();
try {
String boundary = "*****************************************";
String newLine = "rn";
int bytesAvailable;
int bufferSize;
int maxBufferSize = 4096;
int bytesRead;
URL url = new URL(sUrl);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setDoInput(true);
con.setDoOutput(true);
con.setUseCaches(false);
con.setRequestMethod("POST");
con.setRequestProperty("Connection", "Keep-Alive");
con.setRequestProperty("Content-Type", "multipart/form-data;boundary="+boundary);
DataOutputStream dos = new DataOutputStream(con.getOutputStream());
//dos.writeChars(params);
//upload files
for (int i=0; i<files.size(); i++) {
Log.i("HREQ", i+"");
FileInputStream fis = new FileInputStream(files.get(i));
dos.writeBytes("--" + boundary + newLine);
dos.writeBytes("Content-Disposition: form-data; "
+ "name="file_"+i+"";filename=""
+ files.get(i).getPath() +""" + newLine + newLine);
bytesAvailable = fis.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
byte[] buffer = new byte[bufferSize];
bytesRead = fis.read(buffer, 0, bufferSize);
while (bytesRead > 0) {
dos.write(buffer, 0, bufferSize);
bytesAvailable = fis.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fis.read(buffer, 0, bufferSize);
}
dos.writeBytes(newLine);
dos.writeBytes("--" + boundary + "--" + newLine);
fis.close();
}
// Now write the data
Enumeration keys = params.keys();
String key, val;
while (keys.hasMoreElements()) {
key = keys.nextElement().toString();
val = params.get(key);
dos.writeBytes("--" + boundary + newLine);
dos.writeBytes("Content-Disposition: form-data;name=""
+ key+""" + newLine + newLine + val);
dos.writeBytes(newLine);
dos.writeBytes("--" + boundary + "--" + newLine);
}
dos.flush();
BufferedReader rd = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String line;
while ((line = rd.readLine()) != null) {
ret.content += line + "rn";
}
//get headers
Map<String, List<String>> headers = con.getHeaderFields();
Set<Entry<String, List<String>>> hKeys = headers.entrySet();
for (Iterator<Entry<String, List<String>>> i = hKeys.iterator(); i.hasNext();) {
Entry<String, List<String>> m = i.next();
Log.w("HEADER_KEY", m.getKey() + "");
ret.headers.put(m.getKey(), m.getValue().toString());
if (m.getKey().equals("set-cookie"))
ret.cookies.put(m.getKey(), m.getValue().toString());
}
dos.close();
rd.close();
} catch (MalformedURLException me) {
} catch (IOException ie) {
} catch (Exception e) {
Log.e("HREQ", "Exception: "+e.toString());
}
return ret;
}
This is taken from:
http://moazzam-khan.com/blog/?p=490
Check link for dependencies and usage.