How to download files from publicly available google drive URL using Java? - java

I have been trying to download files/whole directory from publicly available google drive link URL using Java. I am able to read files which are present in my google drive using google drive libraries but I am not able to understand how to pass google drive link URL.
Also, I tried to use typical method of downloading files from URL but it produced error java.io.IOException: Server returned HTTP response code: 400 for URL.
URL url;
URLConnection con;
DataInputStream dis;
FileOutputStream fos;
byte[] fileData;
try {
url = new URL("https://drive.google.com/drive/folders/<some-alphanumeric-code>/<file-name>"); //File Location goes here
con = url.openConnection(); // open the url connection.
dis = new DataInputStream(con.getInputStream());
fileData = new byte[con.getContentLength()];
for (int q = 0; q < fileData.length; q++) {
fileData[q] = dis.readByte();
}
dis.close(); // close the data input stream
fos = new FileOutputStream(new File("/Users/abhijeetkunwar/file.png")); //FILE Save Location goes here
fos.write(fileData); // write out the file we want to save.
fos.close(); // close the output stream writer
}
catch(Exception m) {
System.out.println(m);
}
Kindly suggest the solution please.

The link you are using contains the folder id, the folder should also be readable by everyone.
In this instance you can use the files.list method from the Google drive api and access it using 'folderid' in parents which will return a list of all of the files within that folder.
For this to work the folder needs to be public to viewers which yours seem to be, after our conversation in chat.

Related

FileNotFoundException when attempting to read json asset

I'm working on an app that needs to send an automatic email on button click. the problem I am currently have is that I need to read a json file and when I pass the path of the json stored in assets into into a new FileReader() I get a file not found Exception. here is how I am getting the path. (wondering if Uri.parse().toString is redundant):
private static final String CLIENT_SECRET_PATH =
Uri.parse("file:///android_asset/raw/sample/***.json").toString()
and here is the method I am passing it into:
sClientSecrets = GoogleClientSecrets
.load(jsonFactory, new FileReader(CLIENT_SECRET_PATH));
the json file that I am attemping to access is in my apps asset folder under the app root in android project directory (/app/assets/)
I am not sure what I am doing wrong here but I'm sure it is something simple. please help point me in the right direction.
You should not access the assets using direct file path.
The files are packed and the location will change on each device.
You need to use a helper function to get the assets path
getAssets().open()
See this post for more information.
Keep your file directly inside assets directory rather then raw-sample.
And then file path will be like this
private static final String CLIENT_SECRET_PATH =
Uri.parse("file:///android_asset/***.json").toString()
hope your problem will be solved..
You can use this function to get JSON string from assets and pass that string to the FileReader.
public String loadJSONFromAsset() {
String json = null;
try {
InputStream is = getActivity().getAssets().open("yourfilename.json");
int size = is.available();
byte[] buffer = new byte[size];
is.read(buffer);
is.close();
json = new String(buffer, "UTF-8");
} catch (IOException ex) {
ex.printStackTrace();
return null;
}
return json;
}
#Rohit i was able to use the method you provided as a starting point. the only issue with it was that the gmail api that i am using requires a Reader as its parameter, not a string. here is what i did. and i am no longer getting filenotfoundexception. thank you very much.
public InputStreamReader getJsonStreamReader(String file){
InputStreamReader reader = null;
try {
InputStream in = getAssets().open(file);
reader = new InputStreamReader(in);
}catch(IOException ioe){
Log.e("launch", "error : " + ioe);
}
return reader;
}

How do you send an html file along with its images through a socket in java

I'm required for a project to send an html file through a socket in Java. I managed to get the text to appear in the browser but none of the pictures load. I found this code online to help me send the html file in the first place, but I am wondering if there is any way to send the pictures. I have all of the images in an img folder, which is where the html file is located.
public class SimpleFileServer {
public final static int SOCKET_PORT = 9000; // you may change this
public final static String FILE_TO_SEND = "D:\\Project 2\\index.html"; // you may change this
public static void main (String [] args ) throws IOException {
FileInputStream fis = null;
BufferedInputStream bis = null;
OutputStream os = null;
ServerSocket servsock = null;
Socket sock = null;
try {
servsock = new ServerSocket(SOCKET_PORT);
while (true) {
try {
sock = servsock.accept();
// send file
File myFile = new File (FILE_TO_SEND);
byte [] mybytearray = new byte [(int)myFile.length()];
fis = new FileInputStream(myFile);
bis = new BufferedInputStream(fis);
bis.read(mybytearray,0,mybytearray.length);
os = sock.getOutputStream();
os.write(mybytearray,0,mybytearray.length);
System.out.println("Done.");
} finally {
if (bis != null) bis.close();
if (os != null) os.close();
if (sock!=null) sock.close();
}
}
} finally {
if (servsock != null) servsock.close();
}
}
}
Are you sure your project does not also require you to parse the HTML and request the images separately? It sounds like you're simulating something like a web server. Generally speaking a browser will download the HTML of a page, parse it, then send follow-up requests to the server for each image or other resource (CSS, off-site Javascript, etc.) contained in the page.
Doing one request per resource can also simplify your server, because it only has to deal with the resource being requested at the time, which pushes some of the logic and complication back onto the client to be able to know which resources to ask for.
Things have changed somewhat in HTTP 2, but that's another matter that is probably outside the scope of your question.
Typically, image files are not included in the html download, but are requested subsequently as the html file is parsed. The problem of why the images are not showing in your case can probably be fixed by correcting the src locations in the tags. IF you do need to download everything together though, I would recommend sending a .zip archive
I think you are trying to achieve the "save as" functionality in web browsers.
You need to save the html file separately and the assets such as image files, embedded contents separately.
Since you already have the images in img folder, you need to alter the src attribute of image tag in the html - to pick the images from the image folder.

download the files from Gdrive to local system by using java

Drive Quickstart: Run a Drive App in Java example works for uploading files fine. I want to download the files from Gdrive to local system by using java.
For download they are given a method
private static InputStream downloadFile(Drive service, File file) {
if (file.getDownloadUrl() != null && file.getDownloadUrl().length() > 0) {
try {
HttpResponse resp =
service.getRequestFactory().buildGetRequest(new GenericUrl(file.getDownloadUrl())).execute();
return resp.getContent();
} catch (IOException e) {
// An error occurred.
e.printStackTrace();
return null;
}
} else {
// The file doesn't have any content stored on Drive.
return null;
}
}
The above method,how can i give inputs? and from where i give the inputs? Can anyone give a complete code for download like Quickstart upload class.
any help will be appreciated.
you can use google drive api and send Http get request, you can see this tutorial
https://developers.google.com/drive/manage-downloads
Thanks Hanan it works fine.By using the retrieveAllFiles() i can list all the documents.And i have stored the retrieved documents in my local by using this below code.Is it a correct way to download.
for(File f:result){
i++;
System.out.println("File Name==>"+f.getTitle());
System.out.println("File Id==>"+f.getId());
System.out.println("File ext==>"+f.getFileExtension());
System.out.println("File size==>"+f.getFileSize());
InputStream in = downloadFile(service,f);
byte b[] = new byte[in.available()];
in.read(b);
java.io.File ff = new java.io.File("/home/test/Desktop/gdocs/"+f.getTitle());
FileOutputStream fout = new FileOutputStream(ff);
fout.write(b);
fout.close();
}
It stores all the documents in local. The text (.txt) files are open properly in my local, but the image files or pdf files are not open properly.It gives some error messages like file corrupted. There is no content in the image or pdf documents how can i get content and store it. Any suggestions

Google App Engine for Java and Google Cloud Storage

I have an Google App Engine (Java) based application which stores the file data in Google Cloud storage.
This file download servlet works fine in my local eclipse environment and when deployed to appspot domain, this works for simple text files but for any documents (displayed in the browser in a new tab), but if I try with any other binary files (doc, jpeg, gif etc) seem to do nothing, no error is thrown as well at the server side . I checked directly in the file folders in Google Cloud storage, files are stored properly and able to access it directly, but cannot do so via the app engine.
Can you please let me know if I am missing something?
The code snippet below,
try {
FileService newfileService = FileServiceFactory.getFileService();
AppEngineFile file = new AppEngineFile(cloudpath) ;
FileReadChannel channel = newfileService.openReadChannel(file, false);
BufferedInputStream bis = new BufferedInputStream(Channels.newInputStream(channel));
BufferedOutputStream bos = new BufferedOutputStream(resp.getOutputStream());
resp.setHeader("Content-Disposition", "inline;filename=\"" + file.getNamePart() + "");
int b = 0;
while((b = bis.read()) != -1) {
bos.write(b);
}
bos.flush();
} catch (Exception e) {
e.printStackTrace();
}
Instead of trying to stream the file yourself you should use the BlobstoreService.serve method. This takes care or streaming and can be used on files of any size.
Something like
BlobstoreService blobService = BlobstoreServiceFactory.getBlobstoreService();
blobService.serve(blobService.createGsBlobKey(cloudpath), resp);
you'll try the following order of statements.
...
resp.setContentType("application/octet-stream");
resp.setHeader("Content-Disposition", "inline;filename=\"" + file.getNamePart() + "");
BufferedOutputStream bos = new BufferedOutputStream(resp.getOutputStream());
int b=0;
...

Java + Google Web Toolkit (google apps engine) download file from server

I have deployed an application in Google App Engine and and I want to upload and download data from server using java code at desktop and server code for download request and one more: Where do I store the data in apps engine?
To store binary data (file contents) you have three options:
Blob property of Datastore entities
Blobstore
Google Cloud Storage
You can save your file anywhere on your server, you just need to know the path.
how i direct it as output stream?
Here is a code snippet that can help you.
File fileOnServer = new File("Hello.txt"); // Give full path where your file is located
byte[] file = new byte[(int) fileOnServer.length()];
FileInputStream fileInputStream = new FileInputStream(fileOnServer);
fileInputStream.read(file);
int contentLength = (int) file.length;
response.setContentLength(contentLength);
response.setHeader("Content-Disposition", "attachment; filename=\"Hello.txt\"");
out = response.getOutputStream();
int bytesWritten = 0;
byte[] buffer = new byte[1024];
while (bytesWritten < contentLength) {
int bytes = Math.min(1024, contentLength - bytesWritten);
System.arraycopy(file, bytesWritten, buffer, 0, bytes);
if (bytes > 0) {
out.write(buffer, 0, bytes);
bytesWritten += bytes;
} else if (bytes < 0);
}
get download to user end?
Well you can add ClickHandler on a Button on your client side and override onClick method.
public void onClick(ClickEvent event) {
Window.open("UrlToYourServelet", "_blank", "null");
}
Hope this helps!
EDIT
I have found a solution. You can upload the file at any free file hosting site like this. This site provides a URL for every uploaded file. So in your servelet, make a HTTP request to the URL and download the file in byte[] and write it on outputStream as shown in the code above.

Categories