ZipFile corrupted after downloading using Java [duplicate] - java

This question already has answers here:
How can I download and save a file from the Internet using Java?
(23 answers)
Closed 8 years ago.
Downloaded Zip files using Java, when it's open saying that Can't open.
Want to know what is the pblm?
Is it because of less memory?
Here is the code for downloading zipFiles
try {
for(int i=0;i<URL_LOCATION.length;i++) {
url = new URL(URL_LOCATION[i]);
connection = url.openConnection();
stream = new BufferedInputStream(connection.getInputStream());
int available = stream.available();
b = new byte[available];
stream.read(b);
File file = new File(LOCAL_FILE[i]);
OutputStream out = new FileOutputStream(file);
out.write(b);
}
} catch (Exception e) {
System.err.println(e.toString());
}
Soln for this: Refered Link is How to download and save a file from Internet using Java?
BufferedInputStream in = null;
FileOutputStream fout = null;
try
{
in = new BufferedInputStream(new URL(urlString).openStream());
fout = new FileOutputStream(filename);
byte data[] = new byte[1024];
int count;
while ((count = in.read(data, 0, 1024)) != -1)
{
fout.write(data, 0, count);
}
}
finally
{
if (in != null)
in.close();
if (fout != null)
fout.close();
}

You are using the available()-call to determine how many bytes to read. Thats blatantly wrong (see javadoc of InputStream for details). available() only tells you about data immediately available, not about the real stream length.
You need a loop and read from the stream until it return -1 (for EndOfStream) as number of bytes read.
I recommend you review the tutorial on streams: http://docs.oracle.com/javase/tutorial/essential/io/bytestreams.html

Related

ZipOutputStream on mp3 corrupts files - Creates data files not audio files [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 7 years ago.
Improve this question
I am using ZipOutputStream in an Android app to package and export mp3 files. The package and export appears to work fine, when the files are extracted, they are not playable. Running file command on the output shows the file type as data. Prior to zipping the file type is listed as Audio.
Here's the code I'm using to compress the files:
protected File compressFiles(File outputFile, File... inputFiles) {
int bufferSize = 1024 * 4; // 4KB
ZipOutputStream zipOutputStream = null;
try {
OutputStream fileOutputStream = new FileOutputStream(outputFile);
zipOutputStream = new ZipOutputStream(new BufferedOutputStream(fileOutputStream));
int count = inputFiles.length;
File file = null;
for (int i = 0; i < inputFiles.length; i++) {
file = inputFiles[i];
String fileName = file.getName();
ZipEntry entry = new ZipEntry(fileName);
entry.setTime(file.lastModified());
FileInputStream inputStream = new FileInputStream(file);
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
zipOutputStream.putNextEntry(entry);
byte[] buffer = new byte[bufferSize];
int bytesRead;
while ((bytesRead = bufferedInputStream.read()) != -1) {
zipOutputStream.write(buffer, 0, bytesRead);
}
zipOutputStream.closeEntry();
inputStream.close();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (zipOutputStream != null) {
try {
zipOutputStream.finish();
// zipOutputStream.flush();
zipOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return outputFile;
}
You are using the wrong overload of the BufferedInputStream.read() method.
You probably meant to pass in the byte[] buffer as a parameter, but instead, you didn't pass in any parameters. As a result you are only writing out zeroes from the buffer variable. In fact, even the bytesRead variable has the wrong value, as it returns the actual byte being read instead of the number of bytes.
To fix, simply change this line:
while ((bytesRead = bufferedInputStream.read()) != -1) {
to this:
while ((bytesRead = bufferedInputStream.read(buffer)) != -1) {

How to download a PDF from a given URL in Java? [duplicate]

This question already has answers here:
How can I download and save a file from the Internet using Java?
(23 answers)
Closed 4 years ago.
I want to make a Java application that when executed downloads a file from a URL. Is there any function that I can use in order to do this?
This piece of code worked only for a .txt file:
URL url= new URL("http://cgi.di.uoa.gr/~std10108/a.txt");
BufferedReader in = new BufferedReader(
new InputStreamReader(url.openStream()));
PrintWriter writer = new PrintWriter("file.txt", "UTF-8");
String inputLine;
while ((inputLine = in.readLine()) != null){
writer.write(inputLine+ System.getProperty( "line.separator" ));
System.out.println(inputLine);
}
writer.close();
in.close();
Don't use Readers and Writers here as they are designed to handle raw-text files which PDF is not (since it also contains many other information like info about font, and even images). Instead use Streams to copy all raw bytes.
So open connection using URL class. Then just read from its InputStream and write raw bytes to your file.
(this is simplified example, you still need to handle exceptions and ensure closing streams in right places)
System.out.println("opening connection");
URL url = new URL("https://upload.wikimedia.org/wikipedia/en/8/87/Example.JPG");
InputStream in = url.openStream();
FileOutputStream fos = new FileOutputStream(new File("yourFile.jpg"));
System.out.println("reading from resource and writing to 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();
System.out.println("File downloaded");
Since Java 7 we can also use Files.copy and the try-with-resources to automatically close the InputStream (the stream doesn't have to be closed manually in this case):
URL url = new URL("https://upload.wikimedia.org/wikipedia/en/8/87/Example.JPG");
try (InputStream in = url.openStream()) {
Files.copy(in, Paths.get("someFile.jpg"), StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e) {
// handle exception
}

Read first bytes of a file

I need a very simple function that allows me to read the first 1k bytes of a file through FTP. I want to use it in MATLAB to read the first lines and, according to some parameters, to download only files I really need eventually. I found some examples online that unfortunately do not work. Here I'm proposing the sample code where I'm trying to download one single file (I'm using the Apache libraries).
FTPClient client = new FTPClient();
FileOutputStream fos = null;
try {
client.connect("data.site.org");
// filename to be downloaded.
String filename = "filename.Z";
fos = new FileOutputStream(filename);
// Download file from FTP server
InputStream stream = client.retrieveFileStream("/pub/obs/2008/021/ab120210.08d.Z");
byte[] b = new byte[1024];
stream.read(b);
fos.write(b);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fos != null) {
fos.close();
}
client.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
the error is in stream which is returned empty. I know I'm passing the folder name in a wrong way, but I cannot understand how I have to do. I've tried in many way.
I've also tried with the URL's Java classes as:
URL url;
url = new URL("ftp://data.site.org/pub/obs/2008/021/ab120210.08d.Z");
URLConnection con = url.openConnection();
BufferedInputStream in =
new BufferedInputStream(con.getInputStream());
FileOutputStream out =
new FileOutputStream("C:\\filename.Z");
int i;
byte[] bytesIn = new byte[1024];
if ((i = in.read(bytesIn)) >= 0) {
out.write(bytesIn);
}
out.close();
in.close();
but it is giving an error when I'm closing the InputStream in!
I'm definitely stuck. Some comments about would be very useful!
Try this test
InputStream is = new URL("ftp://test:test#ftp.secureftp-test.com/bookstore.xml").openStream();
byte[] a = new byte[1000];
int n = is.read(a);
is.close();
System.out.println(new String(a, 0, n));
it definitely works
From my experience when you read bytes from a stream acquired from ftpClient.retrieveFileStream, for the first run it is not guarantied that you get your byte buffer filled up. However, either you should read the return value of stream.read(b); surrounded with a cycle based on it or use an advanced library to fill up the 1024 length byte[] buffer:
InputStream stream = null;
try {
// Download file from FTP server
stream = client.retrieveFileStream("/pub/obs/2008/021/ab120210.08d.Z");
byte[] b = new byte[1024];
IOUtils.read(stream, b); // will call periodically stream.read() until it fills up your buffer or reaches end-of-file
fos.write(b);
} catch (IOException e) {
e.printStackTrace();
} finally {
IOUtils.closeQuietly(inputStream);
}
I cannot understand why it doesn't work. I found this link where they used the Apache library to read 4096 bytes each time. I read the first 1024 bytes and it works eventually, the only thing is that if completePendingCommand() is used, the program is held for ever. Thus I've removed it and everything works fine.

Read Image from Socket [duplicate]

This question already has an answer here:
Closed 11 years ago.
Possible Duplicate:
Read Image File Through Java Socket
void readImage() throws IOException
{
socket = new Socket("upload.wikimedia.org", 80);
DataOutputStream bw = new DataOutputStream(new DataOutputStream(socket.getOutputStream()));
bw.writeBytes("GET /wikipedia/commons/8/80/Knut_IMG_8095.jpg HTTP/1.1\n");
bw.writeBytes("Host: wlab.cs.bilkent.edu.tr:80\n\n");
DataInputStream in = new DataInputStream(socket.getInputStream());
File file = new File("imgg.jpg");
file.createNewFile();
DataOutputStream dos = new DataOutputStream(new FileOutputStream(file));
int count;
byte[] buffer = new byte[8192];
while ((count = in.read(buffer)) > 0)
{
dos.write(buffer, 0, count);
dos.flush();
}
dos.close();
System.out.println("image transfer done");
socket.close();
}
-Create a socket
-Create output stream
-Request the page that includes image
-Read socket to an input stream
-Write to file
I am trying to read an image from socket.
But it is not working.
It seems to read and the image is opened but can not be seen
Where is the problem?
You need to skip HTTP headers to get correct image.
I've already answered to this question today, look at: Read Image File Through Java Socket
The second problem, that you are trying to receive an image from wikipedia without referer and wikipedia restrict to do that (you receiving access denied every time). Try to use another image URL (google image for example).
You can use URL objects directly to fetch HTTP content. The input stream returned by the URL object will only contain content at the URL. The example method below takes a URL, fetches its content and writes the content to a given file.
public static void createImageFile(URL url, File file) throws IOException{
FileOutputStream fos = null;
InputStream is = null;
byte[] b = new byte[1024]; // 1 kB read blocks.
URLConnection conn;
try{
conn = url.openConnection();
/* Set some connection options here
before opening the stream
(i.e. connect and read timeouts) */
is = conn.getInputStream();
fos = new FileOutputStream(file);
int i = 0;
do{
i = is.read(b);
if(i != -1)
fos.write(b, 0, i);
}while(i != -1)
}finally{
/* Don't forget to clean up. */
if(is != null){
try{
is.close();
}catch(Exception e){
/* Don't care */
}
}
if(fos != null){
try{
fos.close();
}catch(Exception e){
/* Don't care */
}
}
}
}

How do I get the InputStream of decompressed data from an InputStream of GZIPed data?

I call a service which returns a gzipped file. I have the data as an InputStream (courtesy of javax.activation.DataHandler.getInputStream();) from the response.
What I would like to do is, without writing anything to disk, get an InputStream of the decompressed data in the file that is in the archive. The compressed file in this case is an xml document that I am trying to unmarshal using javax.xml.bind.Unmarshaller which takes an InputStream.
I'm currently trying to write the InputStream to an OutputStream (decompressing the data) and then I'll need to write it back to an InputStream. It's not working yet so I thought I would see if there was a better (I would hope so) approach.
I can write the initial InputStream to disk and get a gz file, and then read that file, get the compressed file out of it and go from there but I'd rather keep it all in memory is possible.
Update 1: Here is my current (not working - get a "Not in GZIP format" exception):
ByteArrayInputStream xmlInput = null;
try {
InputStream in = dh.getInputStream(); //dh is a javax.activation.DataHandler
BufferedInputStream bis = new BufferedInputStream(in);
ByteArrayOutputStream bo = new ByteArrayOutputStream();
int bytes_read = 0;
byte[] dataBuf = new byte[4096];
while ((bytes_read = bis.read(dataBuf)) != -1) {
bo.write(dataBuf, 0, bytes_read);
}
ByteArrayInputStream bin = new ByteArrayInputStream(bo.toByteArray());
GZIPInputStream gzipInput = new GZIPInputStream(bin);
ByteArrayOutputStream out = new ByteArrayOutputStream();
dataBuf = new byte[4096];;
bytes_read = 0;
while ((bytes_read = gzipInput.read(dataBuf)) > 0) {
out.write(dataBuf, 0, bytes_read);
}
xmlInput = new ByteArrayInputStream(out.toByteArray());
If instead of writing to a ByteArrayOutputStream I write to a FileOutputStream the first time around I get a compressed file (which I can manually open to get the xml file within) and the service (eBay) says it should be a gzip file so I'm not sure why I get a "Not in GZIP format" error.
Update 2: I tried something a little different - same error ("Not in GZIP format"). Wow, I just tried to end that parenthesis with a semi-colon. Anyways, here is my second attempt, which still does not work:
ByteArrayInputStream xmlInput = null;
try {
GZIPInputStream gzipInput = new GZIPInputStream(dh.getInputStream());
ByteArrayOutputStream bo = new ByteArrayOutputStream();
int bytes_read = 0;
byte[] dataBuf = new byte[4096];
while ((bytes_read = gzipInput.read(dataBuf)) != -1) {
bo.write(dataBuf, 0, bytes_read);
}
xmlInput = new ByteArrayInputStream(bo.toByteArray());
Decorate the input stream with a GZIPInputStream.
InputStream decompressed = new GZIPInputStream(compressed);
The following code should work. Keep in mind you'll have to handle exceptions properly.
OutputStream out = null;
InputStream in = null;
try {
out = /* some output stream */;
in = new java.util.GZIPInputStream(/*some stream*/);
byte[] buffer = new byte[4096];
int c = 0;
while (( c = in.read(buffer, 0, 4096)) > 0) {
out.write(buffer, 0, c);
}
} finally {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
Take a look at GZIPInputStream. Here's an example; the class handles this very transparently, it's almost no work to use.

Categories

Resources