Downloaded zip file is invalid - java

I'm trying to download (and later extract) a zip file from my dropbox account using this code
URL url = new URL("-");
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
try (InputStream stream = con.getInputStream()) {
Files.copy(stream, Paths.get(parent.getAbsolutePath() + File.separator + "zippedCache.zip"));
}
The file I'm trying to download is a folder with another folder in it (empty). When I attempt to open the zipped folder, I get something along the lines of "cannot open the folder the compressed zipped folder is invalid" (translated using Google translator). When I unzip it, it's empty.
Can anyone explain what the problem here is?
Edit: Also, the zip folder is empty when I download it using Java, however downloading it normally through a web browser works fine.

Please verify your code again using a HttpURLConnection. This should work out.
For using Https you would need something like urlConnection.setSSLSocketFactory or similar.

You should try to read the InputStream in parts into a byte array and write into a FileOutputStream. It's simpler I think.
Example:
InputStream stream = con.getInputStream();
byte[] buffer = new byte[4096];
FileOutputStream out = new FileOutputStream("anything.zip");
while (stream.read(buffer) != -1) {
out.write(buffer);
}

Related

File is not getting copied in Java using input and output stream reader

I am working in Java platform. I need to copy a file from the package to some folders in desktop. I am using input stream and output stream classes to do it, it is doing the job pretty well inside NetBeans.
The problem is, it's not copying the file while I am running the JAR file to test the application, and it is saying NULL.
File source = new File("src/jrepo/css/bs.css");
File dest = new File(ResultPath + "/css/bs.css");
InputStream is = null;
OutputStream os = null;
try {
is = new FileInputStream(source);
os = new FileOutputStream(dest);
byte[] buffer = new byte[1024];
int length;
while ((length = is.read(buffer)) > 0) {
os.write(buffer, 0, length);
}
} finally {
is.close();
os.close();
}
Your problem is with
new File("src/jrepo/css/bs.css");
The constructor for File(String) takes a full path to the file. You are using a relative path. If you are trying to read the file from the operating system, use the full path. If you are reading it from the jar file, then use this approach instead.
I found the way since I am using JavaFX, there is a problem which stops the file copying of CSS files. In order to resolve that issue just change the run time settings of the project in Netbeans. Right click the title of the project→go to Properties→Build→Packaging→uncheck the Binary Encode JavaFX CSS files checkbox and then save the project and rebuild it.

Getting the newest version (not the cached version) of a text file on a server using java Streams to read

I have a url of a text file and I want to read it:
URL url = new URL("example.com/textfile.txt");
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
String inpuline = null;
while ((inpuline = in.readLine()) != null) {
System.out.println(inpuline);
}
in.close();
The problem is when I change the Content of textfile.txt, my program does not realize the changes next time it runs.
After you change the txt file, you should verify that your server realized the changes and return the last version of your file. To verify this use a browser. If you didn't get the last version of your file something is wrong with the server. If you need to press Ctrl+F5 it means that the maybe some proxies or your browser cashed the old file.
After all trying the following workarounds may helps:
try {
URL url = new URL("example.com/textfile.txt");
Scanner s = new Scanner(url.openStream());
// read from your scanner
}
catch(IOException ex) {
ex.printStackTrace(); // for now, simply output it.
}
If you got the cached version of your file again, then try to use HttpURLConnection to download the file and write it to a temp file. Then read from that temp file and after that delete that temp file. Maybe downloading the file can force the server to get the newest version of that file. To avoid cached version of your file try this:
// Create a URLConnection object
URLConnection connection = myURL.openConnection();
// Disable caching
connection.setUseCaches(false);
Good Luck.

Compile Java file with external files inside. (chm)

I am making a 1 file program in java, and I have a .chm file that I want to be called when the user asks how to use the program. I don't want to have the file outside the .jar file.
Maybe what I'm asking is impossible, the only thing I know about compiling is that if I hit "clean and build" button it generates a .jar file out of my .java files. Is there a way to do this?
PS: I use NetBeans to create java programs.
You can include any file inside a jar (it is a zip file). Then you have to use getResource() to get an access to the embedded file in your jar. That would return an URL that you can use to get an InputStream by calling openStream() and read from it, possibly extracting it to the hard drive for display, etc.
The use is to put such files in a "resource" or "res" folder, inside the "src" directory. Here is how it looks in my Eclipse:
Then I access my images by:
URL uImg = getClass().getResource("/res/16/Actions-edit-delete-icon-16.png");
InputStream is = uImg.openStream();
// Read the content from 'is' e.g. to extract it somewhere
is.close();
EDIT: As an example, to extract your file "TJ.chm" from "res" directory of your jar into a file "/tmp/TJ.chm" you would do like:
// Add all necessary try/catch
InputStream is = ucmh.openStream();
OutputStream os = new BufferedOutputStream(new FileOutputStream("/tmp/TJ.chm"));
int len = 0;
byte[] buffer = new byte[8192]; // Or whichever size you prefer
while ((len = is.read(buffer)) > -1)
os.write(buffer, 0, len);
os.close();
is.close();

chaging directory saved in sd card

I've created this code to save a pdf file in sd card, but I want to change the directory that has the saved files, from /sdcard/, to /sdcard/MYDIR/
try {
URL url = new URL(f_url[0]);
URLConnection conection = url.openConnection();
conection.connect();
// getting file length
int lenghtOfFile = conection.getContentLength();
// input stream to read file - with 8k buffer
InputStream input = new BufferedInputStream(url.openStream(), 8192);
// Output stream to write file
OutputStream output = new FileOutputStream("/sdcard/yes.pdf");
To create a directory in Java, use mkdir() or mkdirs() on File.
To correctly create a directory or file on external storage on Android, do not hard-code /sdcard, largely because it is the wrong value on most Android devices. Use Environment.getExternalStorageDirectory() to access the root of external storage.
File dir=new File(Environment.getExternalStorageDirectory(), "MYDIR");
dir.mkdir();
OutputStream output=new FileOutputStream(new File(dir, "yes.pdf"));
The class you need is File. There you have methods like mkdirs() that creates the necessary directories.
You should make sure that you don't use hard coded paths in your application. On some devices your "/sdcard/" will fail. Check the class Environment and use the getExternalStorageDirectory() to get the path of the sd card.

The compressed (zipped) folder is invalid Java

I'm trying to zip files from server into a folder using ZipOutputStream.
After archive download it can't be opened after double click. Error "The compressed (zipped) folder is invalid" occures. But if I open it from context menu - > 7zip -> open file it works normal. What can be reason of the problem?
sourceFileName="./file.txt"'
sourceFile = new File(sourceFileName);
try {
// set the content type and the filename
responce.setContentType("application/zip");
response.addHeader("Content-Disposition", "attachment; filename=" + sourceFileName + ".zip");
responce.setContentLength((int) sourceFile.length());
// get a ZipOutputStream, so we can zip our files together
ZipOutputStream outZip = new ZipOutputStream((responce.getOutputStream());
// Add ZIP entry to output stream.
outZip.putNextEntry(new ZipEntry(sourceFile.getName()));
int length = 0;
byte[] bbuf = new byte[(int) sourceFile.length()];
DataInputStream in = new DataInputStream(new FileInputStream(sourceFile));
while ((in != null) && ((length = in.read(bbuf)) != -1)) {
outZip.write(bbuf, 0, length);
}
outZip.closeEntry();
in.close();
outZip.flush();
outZip.close();
7Zip can open a wide variety of zip formats, and is relatively tolerant of oddities. Windows double-click requires a relatively specific format and is far less tolerant.
You need to look up the zip format and then look at your file (and "good" ones) with a hex editor (such as Hex Editor Neo), to see what may be wrong.
(One possibility is that you're using the wrong compression algorithm. And there are several other variations to consider as well, particularly whether or not you generate a "directory".)
It could be that a close is missing. It could be that the path encoding in the zip cannot be handled by Windows. It might be that Windows has difficulty with the directory structure, or that a path name contains a (back)slash. So it is detective work, trying different files. If you immediately stream the zip to the HTTP response, then finish has to be called i.o. close.
After the code being posted:
The problem is the setContentLength giving the original file size. But when given, it should give the compressed size.
DataInputStream is not needed, and one should here do a readFully.
responce.setContentType("application/zip");
response.addHeader("Content-Disposition", "attachment; filename=file.zip");
//Path sourcePath = sourceFile.toPath();
Path sourcePath = Paths.get(sourceFileName);
ZipOutputStream outZip = new ZipOutputStream((responce.getOutputStream(),
StandardCharsets.UTF-8);
outZip.putNextEntry(new ZipEntry(sourcePath.getFileName().toString()));
Files.copy(sourcePath, outZip);
outZip.closeEntry();
Either finish or closethe zip at the end.
outZip.finish();
//outZip.close();
in.close();
I am not sure (about the best code style) whether to close the response output stream already oneself.
But when not closing finish() must be called, flush() will not suffice, as at the end data is written to the zip.
For file names with for instance Cyrillic letters, it would be best to add a Unicode charset like UTF-8. In fact let UTF-8 be the Esperanto standard world-wide.
A last note: if only one file one could use GZipOutputstream for file.txt.gz or query the browser's capabilities (request parameters) and deliver it compressed as file.txt.

Categories

Resources