I am trying to download an EXE file from my website. So just for example, I went ahead to rarlab's site, and downloaded my self a fresh install of their 64 bit WinRAR release (we all know what that is.)
Anyways, I uploaded the 64 bit "setup" exe file to my root folder of my site where it is easily reachable to download (for testing purposes.) Going on my site through any browser I can successfully download the "setup" file from rarlabs AND execute it like any other EXE file.
Now, this is the confusing part I cannot for the love of God figure out. Using this simple code, that I ripped of some other Stack Overflow answer, I can download any EXE file from a given URL.
The code...
public static void downloadEXE(URL url, String file) throws IOException {
InputStream in = url.openStream();
FileOutputStream fos = new FileOutputStream(new File(file));
int length = -1;
byte[] buffer = new byte[1024];// buffer for portion of data from
// connection
while ((length = in.read(buffer)) > -1) {
fos.write(buffer, 0, length);
}
fos.close();
in.close();
}
Where the URL and FILE arguments are...
URL url = new URL("http://www.website.com/winrar-x64-540.exe");
String file = "c:\\Users\\..\\Documents\\winrar-x64-540.exe";
Yes, this downloads the file from my site into my documents folder without any errors, but when I run it I get this error...
LINK TO ERROR IMAGE
Not stopping there, I decided to try using this same exact code to download the same 64 bit EXE "setup" file EXCEPT this time from the official site, rarlabs. You can take my word for it I used the correct URL, because this time I not only downloaded the EXE file using this code, but also was able to successfully run it!
Leaving me to suspect there is something wrong with my site, not the EXE file? I should also mention a very IMPORTANT discovery I found that will most likely help. I decided to compare the properties from the WORKING EXE file with the BROKEN diseased one. The size of the working one was 2.07 MB whilst the broken one was a whopping 375 bytes! The broken exe didn't match the properties the working exe had AT ALL.
Seeing the comparison of the two files leaves my thinking that my site is not at fault, as I am able to download and launch my file successfully through any browser, but the code is at error.
Please ask me any questions you need to figure out the problem. Let me know where I need to be specific. Thanks all. :)
You are probably not downloading anything usefull, maybe the server just rejects your request and you store that as a file?
What is the size of the downloaded file using java code? is it the same as the file you expect?
Try to open it with a notepad and see if it is actually an exe (some random ASCII signs, and not HTML, you'll know the difference).
In the case the server rejects your request and returns HTML, you probably need to set something in the request (like cookies - you may need to log in to obtain that, user-agent property, other stuff) Try to see how the communication looks like when done from browser, run firebug or something, activate the network tab and see how the requests looks like.
Related
How can I auto launch JNLP file "Programmatically".
I have been able to auto-download the JNLP file but then I have to click on the downloaded file to run it. I'm aware that I can 'open' it every time instead of 'saving' it and remembering this choice. But this is not what I want, I cannot tell client to open the file every time.
Can this be done programmatically?
I suspect that this(opening JNLP instead of saving, programmatically) can not be done, but I absolutely have no idea, any help would be appreciated.
Yes launching a JNLP file programmatically can be done, see below code is using Apache common io to copy streams (Line 3) but there are different ways to copy streams:
final File jnlp = File.createTempFile("temp", ".jnlp");
final URL url = new URL("http://your_jnlp_file_url");
IOUtils.copy(url.openStream(), new FileOutputStream(jnlp));
Desktop.getDesktop().open(jnlp);
I have based my code from below stack overflow question where one of the answers show how to call JNLP URL programmatically:
Combination of Launch4J and Java Web Start?
I am developing my app which contains some xml files used by some internal routines.
I would like to have the original xml files stored in a remote server, so that when a synchronization with such server is required by the user, the app updates the xml files, i.e. the version of the files present in remote is downloaded in local. Is it possible to realize such a setup? Is it possible to add a synchronize button inside the app? I develop in Android studio. For the moment, my app contains the local version of the xml files,
and the synchronization is missing.
Since these are not layout XML files,
Use something like this to download the file you need:
URL website = new URL("http://www.website.com/some_file.xml");
ReadableByteChannel rbc = Channels.newChannel(website.openStream());
FileOutputStream fos = new FileOutputStream("some_file.xml");
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
fos.close();
Put such block of code in the onClick method of the sync button
Modify the argument of the constructor of the FileOutputStream to save the file elsewhere
Save them somewhere like 'Environment.getExternalStorageDirectory() + "Android/package.name/files/some_file.xml'
And use the same path to get to the file and use it
I hope this helps
EDIT: As per your last comment, you need to identify each device using a uniqur identifier, which is usually hard to find being available on all android devices,I think you'd have to use Sign in/up system and thus means using PHP
Maybe there's better solution though
I have an app which converts jTable instances into an excel file. In my previous question, I had a problem in using FileOutputStream() and it turns out that the problem lies within the AD user's privilege in accessing folders/files. Since my superior wont allow me to change the privileges, I resorted using the FileWriter() instead, which worked well. The only problem is that it kept on warning the users that the file they are opening is corrupt. Here's the warning:
The file you are trying to open, 'filename.xls' is in a different format than specified by the file extension. Verify that the file is not corrupted and is from a trusted source before opening the file. Do you want to open the file now?
I searched for a solution which resides in Excel 2007's file extension security. Info can be found here
I made some configuration in the system registry of every workstation that the app covers.
I just want to ask if there's a away to remove the corrupt file warning in Office 14, because one of the workstation, which is my superior's workstation, has Office 14. The changes in the system registry didnt stop the corrupt file warning in his workstation.
I get the impression that you are indulging in "voodoo programming" practices; i.e. applying solutions that you don't understand to problems that you don't understand.
Firstly, this:
I had a problem in using FileOutputStream() and it turns out that the problem lies within the AD user's privilege in accessing folders/files. Since my superior wont allow me to change the privileges, I resorted using the FileWriter() instead, which worked well.
Frankly, this doesn't make sense. If you cannot open a file using new FileOutputStream(File), then you shouldn't be able to open it with new FileWriter(File). Why? Because the source code for the constructor is this:
public FileWriter(File file) throws IOException {
super(new FileOutputStream(file));
}
In other words, the first thing that the FileWriter constructor does is to call the FileOutputStream constructor that you say doesn't work!! (And the same applies to the other overloads of these constructors.)
Then your current problem is really about Excel not letting you open an XLS file because its filetype doesn't match its suffix. And your proposed solution is to mess around with the registry. But surely, the CORRECT approach is to find out why the file type doesn't match the suffix.
Have you made a mistaKe in the file format (e.g. 'cos you wrote it using a FileWriter)?
Have you chosen the wrong file suffix for the spreadsheet format you've used?
Are you downloading it to the user's machine with the wrong MIMEtype?
Banging on the registry on all of the client machines ... just because you read it in some website ... that's Voodooo!
I'm not surprised that your boss forbade you to mess around with AD privileges. At this point, he's probably worried that you'll do serious damage.
By the way, your registry hacking to make the warning go away is actually turning off a security check that is designed to help harden the user's PC against attack. That doesn't strike me as a sound solution to your problem.
This question already has answers here:
How to save uploaded file in JSF
(2 answers)
Closed 7 years ago.
Here with another question on Images ( which seems to be more difficult than I initialy predicted) I'm working on a java Web app with JSF 2.0 ( apache myFaces) and I want this app to be able to upload a picture to a destination on the server it's going to run on. I have a Windows r2 2008 Server running a mySQL Db, but I don't want to store the image in the db, I'd rather store it somewhere in the server and then just save the path as a string in the db.
I was told this is the best way, but I can't seem to find an example on how to save it on the server. I run the app on the Apache tomcat Server as a WAR file. so I don't know if I have to save the file to a path on the server drive (i.e. C:\images) or a special folder in the project itself ( within the java, html files) any help at all is greatly appreciated. I'm totally lost and have been stuck the whole day trying to figure this out.
The code I use to upload the image to the java class is this ( courtesy of CodyS):
InputStream is = uploadedFile.getInputStream();
byte[] buffer = new byte[(int) uploadedFile.getSize()];
is.read(buffer);
File f = new File("C:\\temp\\" + this.patient.getPk() + ".jpeg");
f.createNewFile();
FileOutputStream fos = new FileOutputStream(f);
fos.write(buffer); //This is where I write it to the C Drive
fos.close();
is.close();
instead of writing it to my C drive I'm going to run it on the server, but where should I store the image to later retriev and display in an xhtml file? I hope I'm being clear on what I need, let me know if I am not and I'll try to explain in another way.
instead of writing it to my C drive I'm going to run it on the server, but where should I store the image to later retriev and display in an xhtml file?
That depends on how much control you have over configuring the server. Ideal would be to configure a fixed path outside the Tomcat webapps folder. For example, /var/webapp/upload. You can set this path as a VM argument or environment variable so that your webapp can retrieve it programmatically without the need to change the code.
For example, when specifying as VM argument -Dupload.location=/var/webapp/upload, you can complete the upload as follows:
Path folder = Paths.get(System.getProperty("upload.location"));
String filename = FilenameUtils.getBaseName(uploadedFile.getName());
String extension = FilenameUtils.getExtension(uploadedFile.getName());
Path file = Files.createTempFile(folder, filename + "-", "." + extension);
try (InputStream input = uploadedFile.getInputStream()) {
Files.copy(input, file, StandardCopyOption.REPLACE_EXISTING);
}
String uploadedFileName = file.getFileName().toString();
// Now store it in DB.
As to serving the file back, most ideal would be to add the upload location as a separate <Context> to Tomcat. E.g.
<Context docBase="/var/webapp/upload" path="/uploads" />
This way you can access it directly by http://example.com/uploads/foo-123456.ext
If you have zero control over configuring the server, then, well, storing in the DB or sending to a 3rd party host such as Amazon S3 is your best bet.
See also:
How to provide relative path in File class to upload any file?
Reliable data serving
I would consider allowing the user to upload to Amazon S3 directly. Amazon offers a service for that. Using that service, the client would post a form with the file directly to S3. Once the file has arrived there, Amazon will redirect the client to one of your endpoints, to confirm that the data has arrived, passing you the relevant details.
The benefits are:
Your server does not spend a lot of time in receiving huge files. You can spend your CPU cycles on something a little bit more interesting.
The availability guaranteed by storing it on S3 is probably better then what you would get by storing it on your own Windows box.
It scales. At some point, your filesystem will run out of space. (Or you reach the limit of what you can store inside a folder.)
I'd suggest that you save your images in a subfolder which is in your application's WEB-INF folder. Remember that when you use Tomcat, your WAR files will be extracted automatically. This approach also has the advantage that you can always migrate your application to another server, you only have to save the path relative to WEB-INF folder in your DB.
I'm currently using commons-net library for FTP client in my app. I have to download from remote server some files, by some criteria based on the file name. This is a very simplified and reduced version of my actual code (because I do some checks and catch all possible exceptions), but the essence is there:
//ftp is FTPClient object
//...
files = ftp.listFiles();
for (FTPFile ftpFile : files) {
String name = ftpFile.getName();
if(conformsCriteria(name)) {
String path = outDirectory + File.separatorChar + name;
os = new FileOutputStream(path);
ftp.retrieveFile(name, os);
}
}
Now, what I noticed is that when I run this code, wait a few seconds, and then plug out network cable, output directory contains some "empty" files plus the files actually downloaded, which leads me to believe that this method is working somewhat asynchronously... But then again, some files are downloaded (size > 0KB), and there are these empty files (size = 0KB), which leads me to believe that it is still serialized download... Also, function retrieveFile() returns, I quote documentation:
True if successfully completetd, false if not
What I need is serialized download, because I need to log every unsuccessful download.
What I saw browsing through the commons-net source is that, if I'm not wrong, new Socket is created for each retrieveFile() call.
I'm pretty confused about this, so If someone could explain what is actually happening, and offer solution with this library, or recommend some other FTP java library that supports blocking download per file, that would be nice.
Thanks.
You could just use the java.net.URLConnection class that has been present forever. It should know how to handle FTP URLs just fine. Here is a simple example that should give the blocking behavior that you are looking for.
The caveat is that you have to manage the input/output streams yourself, but this should be pretty simple.
Ok, to briefly answer this in order not to confuse people who might see this question.
Yes, commons-net for FTP is working as I thought it would, that is, retrieveFile() method blocks until it's finished with the download.
It was (of course) my own "mistake" in the code that let me think otherwise.