How to write files to an SD Card from the internet? - java

An example would be a simple image.
I have tried so many things and it just refuses to work despite making a whole lot of sense.
What I've done so far is I'm able to grab 25 pictures and add them to
/sdcard/app name/sub/dir/filename.jpg
They all appear there according to the DDMS but they always have a filesize of 0.
I'm guessing it's probably because of my input stream?
Here's my function that handles the downloading and saving.
public void DownloadPages()
{
for (int fileC = 0; fileC < pageAmount; fileC++)
{
URL url;
String path = "/sdcard/Appname/sub/dir/";
File file = new File(path, fileC + ".jpg");
int size=0;
byte[] buffer=null;
try{
url = new URL("http://images.bluegartr.com/bucket/gallery/56ca6f9f2ef43ab7349c0e6511edb6d6.png");
InputStream in = url.openStream();
size = in.available();
buffer = new byte[size];
in.read(buffer);
in.close();
}catch(Exception e){
}
if (!new File(path).exists())
new File(path).mkdirs();
FileOutputStream out;
try{
out = new FileOutputStream(file);
out.write(buffer);
out.flush();
out.close();
}catch(Exception e){
}
}
}
It just keeps giving me 25 files in that directory but all of their file sizes are zero. I have no idea why. This is practically the same code I've used in a java program.
PS...
If you're gonna give me a solution... I've already tried code like this. It doesn't work.
try{
url = new URL(urlString);
in = new BufferedInputStream(url.openStream());
fout = new FileOutputStream(filename);
byte data[] = new byte[1024];
int count;
System.out.println("Now downloading File: " + filename.substring(0, filename.lastIndexOf(".")));
while ((count = in.read(data, 0, 1024)) != -1){
fout.write(data, 0, count);
}
}finally{
System.out.println("Download complete.");
if (in != null)
in.close();
if (fout != null)
fout.close();
}
}
Here's an image of what my directories look like
http://oi48.tinypic.com/2cpcprm.jpg

A bit change to your second option, try it as following way,
byte data[] = new byte[1024];
long total = 0;
int count;
while ( ( count = input.read(data)) != -1 )
{
total += count;
output.write( data,0,count );
}
This one is different in while statement while ((count = in.read(data, 0, 1024)) != -1)

Using Guava something like this should work:
String fileUrl = "xxx";
File file = null;
InputStream in;
FileOutputStream out;
try {
Uri url = new URI(fileUrl);
in = url.openStream();
out = new FileOutputStream(file)
ByteStreams.copy(in, out);
}
catch (IOException e) {
System.out.println(e.toString());
}
finally {
in.close();
out.flush();
out.close();
}

Related

Spring rest upload file is corrupted

I have a java application which uses spring rest to upload a jar file.But the uploaded file is corrupted and I am not able to access the jar file from the server.Please help.
fileloc = fileloc.replace("$", "/");
String filename = uploadedFileRef.getOriginalFilename();
String path = fileloc + filename;
byte[] buffer = new byte[1000];
File outputFile = new File(path);
FileInputStream reader = null;
FileOutputStream writer = null;
int totalBytes = 0;
try {
outputFile.createNewFile();
reader = (FileInputStream) uploadedFileRef.getInputStream();
writer = new FileOutputStream(outputFile);
int bytesRead = 0;
while ((bytesRead = reader.read(buffer)) != -1) {
writer.write(buffer);
totalBytes += bytesRead;
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
reader.close();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
You call
writer.write(buffer);
so you write always the buffer size. Imagine the last read reads 10 bytes only but you will write 1000 bytes anyway.
Use
write(buffer, 0, bytesRead );
Or just check the question

When image is sent to server I get this error "java.io.UTFDataFormatException: malformed input around byte 1869" [duplicate]

I have two projects; one for my server and one for my client, I am able to send images to the server with ease. But I am wondering how would you be able to download that image you just sent to the server back to the client when I press the download button I have created on my client GUI? My code is written in java.
Many Thanks
This is my serverhandler
String fileName;
fileName = "RecievedImageoutreach1.jpg";
DataOutputStream dout = new DataOutputStream(sock.getOutputStream());
//Coding for image transfer
int flag=0,i;
String extn="";
for(i=0; i<fileName.length(); i++)
{
if(fileName.charAt(i)=='.' || flag==1)
{
flag=1;
extn += fileName.charAt(i);
}
}
if(extn.equals(".jpg") || extn.equals(".gif"))
{
try{
File file = new File(fileName);
FileInputStream fin = new FileInputStream(file);
dout.writeUTF(fileName);
byte[] readData = new byte[1024];
while((i = fin.read(readData)) != -1)
{
dout.write(readData, 0, i);
}
//ta.appendText("\nImage Has Been Sent");
dout.flush();
fin.close();
}catch(IOException ex)
{System.out.println("Image ::"+ex);}
}
}
And this is my client
public void download() throws IOException {
// Get input from the server
DataInputStream dis = new DataInputStream (sock.getInputStream());
String str,extn = "";
str = dis.readUTF();
int flag=0,i;
for(i=0;i<str.length();i++)
{
if(str.charAt(i)=='.' || flag==1)
{
flag=1;
extn+=str.charAt(i);
}
}
//**********************reading image*********************************//
if(extn.equals(".jpg") || extn.equals(".gif"))
{
File file = new File("Downloaded"+str);
FileOutputStream fout = new FileOutputStream(file);
//receive and save image from client
byte[] readData = new byte[1024];
while((i = dis.read(readData)) != -1)
{
fout.write(readData, 0, i);
if(flag==1)
{
ta.append("Image Has Been Downloaded");
flag=0;
}
}
fout.flush();
fout.close();
}
}
But when run nothing occurs? i have linked the client method to run when a button is clicked.
I would do something like this:
//Server Handler
File file = new File(fileName);
FileInputStream fin = new FileInputStream(file);
// dout.writeUTF(fileName);
byte[] readData = new byte[1024];
fin.read(readData);
fin.close();
dout.write(readData, 0, readData.length);
dout.flush();
/* while((i = fin.read(readData)) != -1)
{
dout.write(readData, 0, i);
}*/
//ta.appendText("\nImage Has Been Sent");
dout.flush();
fin.close();
}catch(IOException ex)
{System.out.println("Image ::"+ex);}
}
//Receiving image
if(extn.equals(".jpg") || extn.equals(".gif"))
{
//give path to new file
File file = new File(".//Downloaded"+str);
FileOutputStream fout = new FileOutputStream(file);
//receive and save image from client
byte[] readData = new byte[1024];
int offset =0;
while((i = dis.read(readData,0,readData.length-offset)) != -1){
offset += i;
}
fout.write(readData, 0, readData.length);
if(flag==1)
{
ta.append("Image Has Been Downloaded");
flag=0;
}
fout.flush();
fout.close();
}
}
Assuming that you would have to provide file name and then press download button. So on server side convert the image into byte stream and write over the connection socket. On client side recieve bytes into buffer and then create FileOutputStream providing the directory for output. Write the recieved bytes onto the file using the outputstream created.

ANDROID GC_FOR_ALLOC freed in my app going wrong

That's my android code which takes 30 min to copy a 3MB .log file into a .zip and gives lots of GC_FOR_ALLOC. I also tried to change buffersize from 1k to 8k
File tempFolder=new File(Environment.getExternalStorageDirectory()+LOG_FILE_DIRECTORY_TEMP);
String filePath= Environment.getExternalStorageDirectory()+LOG_FILE_DIRECTORY_TEMP+ "/";
String fileName ="";
String zipFileName="";
String date=DATE_FORMAT_TEMP.format(new Date());
fileName = Settings.LOG_FILE_PREFIX + date+"_" + IMEI +.log;
zipFileName = Settings.LOG_FILE_PREFIX + date+"_" + IMEI +.zip;
br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
String result="";
String line = "";
while((line = br.readLine())!=null)
result += line;
result = getHeader() + result;
fos = new FileOutputStream(file);
fos.write(result.getBytes());
File zipFile=new File(filePath+zipFileName);
iStream = new FileInputStream(file);
oStream = new FileOutputStream(zipFile);
zos = new ZipOutputStream(oStream);
ze = new ZipEntry(fileName);
zos.putNextEntry(ze);
byte[] buffer = new byte[1024];
while((length = iStream.read(buffer)) != -1)
zos.write(buffer, 0, length);
zos.flush();
oStream.flush();
In your code it looks like you are opening and reading the file twice (your BufferedReader and your iStream object). Also, you are loading the entire file into memory twice before writing anything to memory. That's still only 6MB but you probably are hitting your memory stack limit - unless you use android:largeHeap="true" in your manifest.
Before you do that though, try just reading/writing each part:
public void zip(String[] _files, String zipFileName) {
try {
BufferedInputStream origin = null;
FileOutputStream dest = new FileOutputStream(zipFileName);
ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(
dest));
byte data[] = new byte[BUFFER];
for (int i = 0; i < _files.length; i++) {
Log.v("Compress", "Adding: " + _files[i]);
FileInputStream fi = new FileInputStream(_files[i]);
origin = new BufferedInputStream(fi, BUFFER);
ZipEntry entry = new ZipEntry(_files[i].substring(_files[i].lastIndexOf("/") + 1));
out.putNextEntry(entry);
int count;
while ((count = origin.read(data, 0, BUFFER)) != -1) {
out.write(data, 0, count);
}
origin.close();
}
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
Here is the reference: http://javatechig.com/android/how-to-programmatically-zip-and-unzip-file-in-android

Downloading Large JSON File to local file using Java

I'm attempting to download a JSON from the following URL - http://api.crunchbase.com/v/1/companies.js - to a local file. I'm using Java 1.7 and the following JSON Libraries - http://www.json.org/java/ - to attempt to make it work.
Here's my code:
public static void download(String address, String localFileName) {
OutputStream out = null;
URLConnection conn = null;
InputStream in = null;
try {
URL url = new URL(address);
out = new BufferedOutputStream(
new FileOutputStream(localFileName));
conn = url.openConnection();
in = conn.getInputStream();
byte[] buffer = new byte[1024];
int numRead;
long numWritten = 0;
while ((numRead = in.read(buffer)) != -1)
{
out.write(buffer, 0, numRead);
numWritten += numRead;
System.out.println(buffer.length);
System.out.println(" " + buffer.hashCode());
}
System.out.println(localFileName + "\t" + numWritten);
} catch (Exception exception) {
exception.printStackTrace();
} finally {
try {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
} catch (IOException ioe) {
}
}
}
When I run the code everything seems to work until midway through the loop the program seems to stop and not continue reading the JSON Object.
Does anyone know why this would stop reading? How could I fix the issue?
Try This:
public void saveUrl(String filename, String urlString) throws MalformedURLException, IOException
{
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();
}
}
Does anyone know why this would stop reading? How could I fix the issue?
I can't see anything obviously wrong with the client-side code. In the absence of any other evidence on the client side, I'd look at the server-side logs to see if there are any clues there.
IMO, the most likely explanation is one of the following:
There's a bug in the server-side code that is generating the JSON and it is crashing halfway through.
The server (or a proxy / reverse proxy) has a timeout on the time allowed for some part of the interaction, and this particular request is taking too long.

Android - file download problem - incomplete file

I have checked many code snippets, tried with and without buffer and I can't get to download whole file to SD card. The code I use currently is:
try {
url = new URL("http://mywebsite.com/directory/");
} catch (MalformedURLException e1) { }
String filename = "someKindOfFile.jpg"; // this won't be .jpg in future
File folder = new File(PATH); // TODO: add checking if folder exist
if (folder.mkdir()) Log.i("MKDIR", "Folder created");
else Log.i("MKDIR", "Folder not created");
File file = new File(folder, filename);
try {
conn = url.openConnection();
is = conn.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
ByteArrayBuffer baf = new ByteArrayBuffer(50);
int current = 0;
while ((current = bis.read()) != -1) {
baf.append((byte) current);
}
FileOutputStream fos = new FileOutputStream(file);
fos.write(baf.toByteArray());
fos.close();
is.close();
} catch (IOException e) { }
This code creates directory on SD card but downloads only 77 bytes of files. What might be the problem?
The error here is that he was writing the count variable converted to byte datatype instead of the bytes read from the input stream (those should be stored in a temporary byte[] buffer via bis.read(buffer))
The proper code block should be:
BufferedInputStream bis = new BufferedInputStream(is);
FileOutputStream fos = new FileOutputStream(file);
int current = 0;
byte[] buffer = new byte[1024];
while ((current = bis.read(buffer)) != -1) {
fos.write(buffer, 0, current);
}
fos.close();
is.close();

Categories