I'm trying to develop a Java program which retrieves a file from the Google Drive and try to reupload it "as is". However, during that process, It loses the format.
Here is how I retrive the file:
private static java.io.File downloadFile(File uploadedFile)
throws IOException {
java.io.File downloadedFile = new java.io.File(parentDir, uploadedFile.getTitle() + UUID.randomUUID().toString());
try (OutputStream out = new FileOutputStream(downloadedFile)) {
drive.files().export(uploadedFile.getId(), "text/html").executeMediaAndDownloadTo(out);
}
return downloadedFile;
}
Here is how I update the file:
private static File updateFile(Drive service, String fileId, File file, java.io.File newContent) throws IOException {
FileContent mediaContent = new FileContent("text/html", newContent);
return service.files().update(fileId, file, mediaContent).execute();
}
And here is how I combine those methods (pretty dummy):
java.io.File downloaded = downloadFile(files.get(0));
updateFile(drive, files.get(0).getId(), files.get(0), downloaded);
This is the file before and after:
The process is fine when I export & re-import the Google file as RTF or PDF, but I really need an editable format. Did I miss something?
This is the expected outcome. PDFs are one way of ensuring the formats are preserved. For Google Docs, not so much.
Related
I want to add some string data to a video file but I don't want the video file to get corrupted. What I want to achieve is :-
1.) Add text to a video file.
2.) Extract the text from that video file.
What I tried is :-
public class VideoData{
public static void main(String[] args) {
//create file object
File file = new File("I:/java/MyFolder/SmallVideo.mp4");
try
{
//create FileInputStream object
FileInputStream fin = new FileInputStream(file);
byte fileContent[] = new byte[(int)file.length()];
fin.read(fileContent);
//create string from byte array
String strFileContent = new String(fileContent);
System.out.println("File content : ");
System.out.println(strFileContent);
File dest=new File("I://java//OtherFolder//SmallVideo.mp4");
BufferedWriter bw=new BufferedWriter(new FileWriter(dest));
bw.write(strFileContent + "\nThis is my Text");
bw.flush();
}
catch(FileNotFoundException e)
{
System.out.println("File not found" + e);
}
catch(IOException ioe)
{
System.out.println("Exception while reading the file " + ioe);
}
}
}
Please Help me to do the above mentioned tasks.
An MP4 file is a container that stores properly encoded video, audio, images and subtitles. It's a binary file with standard format specification which means you cannot simply add any extra data to it. Modifying the data could corrupt the file and the decoders (simply video players) might fail to render it.
Also in your code, you read the binary data from mp4 file and converted it to String. That shouldn't be the case. A video file data must be handled in binary mode, not as text.
I didn't understand your actual goal. If you are looking to store some text in MP4 file, you could consider storing it in the meta data section of the video file. See here for an example by using a third party library.
Steganography is a technique of embedding text in images and videos. I guess that's beyond your scope.
I am currently storing and downloading my Thymeleaf templates in S3.
I am using the following function to retrieve the Template from S3:
public String getTemplateFile(String name, File localFile) {
ObjectMetadata object = s3Client.getObject(new GetObjectRequest(connectionProperties.getBucket(), name), localFile);
boolean success = localFile.exists() && localFile.canRead();
return localFile.getPath();
}
After doing this the file is successfully downloaded in the desired location.
But when trying to access the file from the FlyingSaucer PDF generator the file doesn't exist, despite it is already downloaded in FILE_LOCATION_PATH. (I can open the file... the file is there but the function doesn't see it)
String xHtmlStringDocument =
convertHtmlToXhtml(templateEngine
.process(FILE_LOCATION_PATH,
initializeLetterHtmlTemplateContext(letter)));
When I run the program again and again I get the same result. But when I STOP the program and RUN it AGAIN then everything works because the file form the last execution is now recognized by the program.
This sounds to me like an asynchronous function issue.
Does anybody know how can I fix this?
Thanks in advance.
EDITED (following suggestion)
New function: Same result:
(And the file was created, the Download from S3 was successful)
java.io.FileNotFoundException: ClassLoader resource "static/templates/template.html" could not be resolved
public String getTemplateFileN(String name, File localFile) throws IOException {
S3Object fullObject = null;
InputStream in = null;
try {
fullObject = s3Client.getObject(new GetObjectRequest(connectionProperties.getBucket(), name));
System.out.println("Content-Type: " + fullObject.getObjectMetadata().getContentType());
System.out.println("Content: ");
displayTextInputStream(fullObject.getObjectContent());
in = fullObject.getObjectContent();
System.out.println(localFile.toPath());
Files.copy(in, localFile.toPath());
} //then later
finally {
// To ensure that the network connection doesn't remain open, close any open input streams.
if (fullObject != null) {
fullObject.close();
}
if (in != null) {
in.close();
}
}
return localFile.getPath();
}
Checking javadoc
https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/s3/AmazonS3Client.html#getObject-com.amazonaws.services.s3.model.GetObjectRequest-java.io.File-
I see not method signature ObjectMetadata getObject(GetObjectRequest getObjectRequest,String file)
There is
ObjectMetadata getObject(GetObjectRequest getObjectRequest,
File destinationFile)
Where you provide File (not String) as second argument. Make sure the file is not opened for write before you try reading it!
My Java application requires access to a large excel file (1GB+ in size) saved on remote shared folder. I'm using SmbFile to get the file with authentication.
Note: Downloading of the file is not an option mainly for size reasons.
The problem is that I need the excel file to be a Java IO File and not SmbFile since the other libraries that I'm using to parse the excel only accepts Java IO File.
Is there any way to convert this SmbFile into a Java compatible File?
See implementation details of your library:
This library will take a provided InputStream and output it to the file system. (...) Once the file is created, it is then streamed into memory from the file system.
The reason for needing the stream being outputted in this manner has to do with how ZIP files work. Because the XLSX file format is basically a ZIP file, it's not possible to find all of the entries without reading the entire InputStream.
(...) This library works by reading out the stream into a temporary file. As part of the auto-close action, the temporary file is deleted.
If you need more control over how the file is created/disposed of, there is an option to initialize the library with a java.io.File. This file will not be written to or removed
So it doesn't matter if you use the File or InputStream API - the whole file will need to be downloaded anyhow.
The simplest solution is to pass the SmbFile.getInputStream() to
StreamingReader.builder().read(smbFile.getInputStream())
but alternatively you can first download the file eg. by means of IOUtils.copy() or Files.copy()
File file = new File("...");
try (
in = smbFile.getInputStream();
out = new FileOutputStream(file)
) {
IOUtils.copy(in, out);
}
or
try (in = smbFile.getInputStream()) {
Files.copy(smbFile.getInputStream(), file.toPath());
}
and pass file to
StreamingReader.builder().read(file)
Using Apache Commons IO library
https://mvnrepository.com/artifact/commons-io/commons-io
NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication("", "user", "key");
SmbFile smbFile = new SmbFile("smb://IP/pitoka.tmp", auth)
InputStream initialStream = smbFile.getInputStream();
File targetFile = new File("/tmp/pitoka.tmp");
FileUtils.copyInputStreamToFile(initialStream, targetFile);
I hope help you.
jcifs.smb.SmbFile smbFile = new SmbFile("smb://host/fileShare/.../file");
java.io.File javaFile = new File(smbFile.getUncPath());
System.out.println(smbFile);
System.out.println(javaFile);
Output
smb://host/fileShare/.../file
\\host\fileShare\...\file
javadoc of smbFile.getUncPath() says
Retuns the Windows UNC style path with backslashs intead of forward
slashes.
I am using jcifs-1.3.17.jar on Windows 10.
Recently i had a similar situation, however, I hadn't found a good solution in the internet, but I wrote a basic code that did what I need easily.
In your case, you will need to copy the excel file from the source (Remote Directory) using SmbFile with authentication to the destination (Local Directory) and only after, convert the excel file path of the destination (getCanonicalPath() function) and convert it from SmbFile format to File format with the code below.
After, create your File object with the file destination path and do what you want.
I use JCIFS to work with remote shared directories using the SMBFILE class.
First, you need to import the main libraries:
import java.io.File;
import java.io.IOException;
import jcifs.smb.SmbFile;
Second, you need to create a static method to convert from SmbFile format to File format:
/**
* This method convert a directory path from SmbFile format to File format.<br />
* <p><strong>Sintax:</strong> <br /> convertSmbFileToFile("Canonical Path")</p>
* <p><strong>Example:</strong> <br /> convertSmbFileToFile("smb://localhost/D$/DOCUMENTOS/workspace/tests2/access")</p>
* #param smbFileCanonicalPath String
* #see String
*/
public static String convertSmbFileToFile(String smbFileCanonicalPath) {
String[] tempVar = smbFileCanonicalPath.substring(6).replace("$", ":").split("/");
String bar = "\\";
String finalDirectory = "";
for (int i = 1; i < tempVar.length; i++) {
finalDirectory += tempVar[i] + bar;
if (i == tempVar.length - 1) {
finalDirectory = finalDirectory.substring(0,finalDirectory.length()-1);
}
}
return finalDirectory;
}
Opcional, you could also create a static method to convert from File format to SmbFile format:
/**
* This method convert a directory path from File format to SmbFile format.<br />
* <p><strong>Sintax:</strong> <br /> convertFileToSmbFile("Canonical Path")</p>
* <p><strong>Example:</strong> <br /> convertFileToSmbFile("D:\DOCUMENTOS\workspace\tests2\access")</p>
* #param fileCanonicalPath String
* #see String
*/
public static String convertFileToSmbFile(String fileCanonicalPath) {
return "smb://localhost/" + fileCanonicalPath.toString().replace(":", "$").replace("\\", "/");
}
Finally, you can call the methods like the below example:
String dirDest = "access/";
try {
File localDirFile = new File(dirDest);
SmbFile localSmbDirFile = new SmbFile(convertFileToSmbFile(localDirFile.getCanonicalPath()));
File localDirFile2 = new File(convertSmbFileToFile(localSmbDirFile.getCanonicalPath()));
System.out.println("Original File Format: " + localDirFile.getCanonicalPath());
System.out.println("Original File Format to SmbFile Format: " + localSmbDirFile.getCanonicalPath());
System.out.println("Converted SmbFile Format to File Format: " + localDirFile2.getCanonicalPath());
} catch (IOException e) {
System.err.println("[ERR] IO Exception - " + e);
}
Result of previous code run:
Original File Format: D:\DOCUMENTOS\workspace\tests2\access
Original File Format to SmbFile Format: smb://localhost/D$/DOCUMENTOS/workspace/tests2/access
Converted SmbFile Format to File Format: D:\DOCUMENTOS\workspace\tests2\access
Extra Information: getCanonicalPath()
Maybe this code will help you and I am available to talk about if you want.
Good Luck!
It's just a matter of structure I guess, with SmbFile we have two arguments while with File we have just one argument.
So, my Idea is to declare a File with the same path of the SmbFile and try to handle your file.
For example, in my I want to delete recursively the content of my folder :
SmbFile sFile = new SmbFile(path, auth)
if (sFile.exists()) {
File file = new File(path);
deleteDirectory(file);
}
boolean deleteDirectory(File directoryToBeDeleted) {
File[] allContents = directoryToBeDeleted.listFiles();
if (allContents != null) {
for (File file : allContents) {
deleteDirectory(file);
}
}
return directoryToBeDeleted.delete();
}
I hope this peace of code help you, and sorry for my english !
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
I have been uploading files from a website quite happily using a combination of Play Framework (1.2.4) with Java and jQuery/javascript.
On the client side I attach a blob object to a FormData object and then send that to my Play Framework controller, which accepts the file. I have written a class UploadImg to upload this file to Amazon S3. I then initiate the class by passing in a File object and filename (which is a String), and call the doUpload() method:
public static void myController(File f){
UploadImg imgToUpload = new UploadImg(File file, String filename);
imgToUpload.doUpload();
// ...
I now have a bunch of images on my desktop and I writing a 'bulk uploader'. I did something lik:
File img = new File("/pics/Repin 301.jpg");
UploadImg fileToUpload = new UploadImg(img);
fileToUpload.doUpload()
But I get an error telling me that my input is null.
The path /pics/ doesn't look like it would point to your desktop, if pics is relative to where you are running the app from then drop the leading slash.
Try this to confirm the file is being found:
File img = new File("/pics/Repin 301.jpg");
if(img.exists()) {
UploadImg fileToUpload = new UploadImg(img);
fileToUpload.doUpload()
}else{
System.out.println("File not found");
}