Does not read the entire input stream in android - android

I am trying to read a response from a server and transform it from InputStream to String but something goes wrong and i cannot see right now why.
InputStream is = entity.getContent();
FileOutputStream folder = new FileOutputStream(
Environment.getExternalStorageDirectory()
+ "/test.xml");
try {
byte[] buf = new byte[1048576];
int current = 0;
int newCurrent = 0;
while ((current = is.read(buf)) != -1) {
newCurrent = newCurrent + current;
folder.write(buf, 0, current);
}
System.out.println("returned folder" + folder);
folder.flush();
} catch (IOException e) {
System.out.println("error on reading input: " + e.getMessage());
}
This is the error:
error on reading input: Socket closed
This is the error I get and another problem that i don't understand is why it does not read the entire content from InputStream(maybe because it's all in one line?).
Thanks.

you dont need to read entire stream in one shot and put it in a byte array, in fact you read it in parts through while loop and put the contents in file stream gradually:
int count;
byte[] filebytes = new byte[1024];
while((count = is.read(filebytes)) != -1){
folder.write(filebytes, 0, count); //writing buffer into file
}
in.close();
folder.flush();
folder.close();

According to stacktrace your crash happens in readLine() while your code uses is.read(buf).
DO these match together?

Related

Download(copy?) a file from my res/raw folder to the default Android download location?

I am making a soundboard for practice and I want to give the user the ability to download the sound (that I have included in the app in the res/raw folder) onClick of a menu item but I can only find information about downloading from an internet url, not something that I already included in the apk.
What is the best way to do this? I would like to give them the option to save to an SD card also if this is possible. A point towards the correct class to use in the documentation would be great! I've been googling to no avail.
Thanks!
Try something like this:
public void saveResourceToFile() {
InputStream in = null;
FileOutputStream fout = null;
try {
in = getResources().openRawResource(R.raw.test);
String downloadsDirectoryPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath();
String filename = "myfile.mp3"
fout = new FileOutputStream(new File(downloadsDirectoryPath + filename));
final 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();
}
}
}
I don't know about the raw but I did a similar thing in my app using the assets folder. My files are under the assets/backgrounds folder as you can probably guess from the code below.
You can modify this code and make it work for you (I know I will only have 4 files which is why I have i go from 0 to 4 but you can change this to whatever you want).
This code copies the file starting with prefix_ (like prefix_1.png, prefix_2.png, etc) to my cache directory but you can obviously change the extension, the filename or the path you would like to save the assets to.
public static void copyAssets(final Context context, final String prefix) {
for (Integer i = 0; i < 4; i++) {
String filename = prefix + "_" + i.toString() + ".png";
File f = new File(context.getCacheDir() + "/" + filename);
if (f.exists()) {
f.delete();
}
if (!f.exists())
try {
InputStream is = context.getAssets().open("backgrounds/" + filename);
int size = is.available();
byte[] buffer = new byte[size];
is.read(buffer);
is.close();
FileOutputStream fos = new FileOutputStream(f);
fos.write(buffer);
fos.close();
} catch (Exception e) {
Log.e("Exception occurred while trying to load file from assets.", e.getMessage());
}
}
}

Android: Unzipping files throws data errors or CRC errors

I'm working on a project that downloads a zip file and unzips locally. The issue I'm hitting is that the unzip process works like 5% of the time.
It's a mystery to me at this point because sometimes it works, but most of the time it throws data or crc errors. It'll even switch between erros even though the zip file hasn't changed.
I've tried zip files that were created by numerous tools wondering if the format was incorrect. But to no avail. Even zips created in the terminal don't work.
Here's my unzipping code:
try {
String _location = model.getLocalPath();
FileInputStream fin = new FileInputStream(localFile);
ZipInputStream zin = new ZipInputStream(fin);
ZipEntry ze = null;
byte[] buffer = new byte[1024];
while((ze = zin.getNextEntry()) != null) {
if(_cancel) break;
System.out.println("unzipping " + ze.getName());
if(ze.isDirectory()) {
File f = new File(_location + ze.getName());
f.mkdirs();
} else {
FileOutputStream fout = new FileOutputStream(_location + ze.getName());
for(int c = zin.read(buffer); c > 0; c = zin.read(buffer)) {
fout.write(buffer,0,c);
}
zin.closeEntry();
fout.close();
}
}
zin.close();
if(_cancel) {
handler.post(dispatchCancel);
return;
}
} catch(Exception e) {
System.out.println("UNZIP ERROR!");
System.out.println(e.getMessage());
System.out.println(e.toString());
e.printStackTrace();
}
And here's how I typically create the zip file.
$>zip -r myzip.zip myzip/
Here are the two error outputs:
java.util.zip.ZipException: CRC mismatch
at java.util.zip.ZipInputStream.readAndVerifyDataDescriptor(ZipInputStream.java:209)
at java.util.zip.ZipInputStream.closeEntry(ZipInputStream.java:173)
at com.XX.XX.XXIssueDownloader$7.run(XXIssueDownloader.java:222)
at java.lang.Thread.run(Thread.java:1020)
java.util.zip.ZipException: data error
at java.util.zip.ZipInputStream.read(ZipInputStream.java:336)
at java.io.FilterInputStream.read(FilterInputStream.java:133)
at com.XX.XX.XXIssueDownloader$7.run(XXIssueDownloader.java:219)
at java.lang.Thread.run(Thread.java:1020)
Anyone have any idea why I might get these errors? I'm not getting anywhere with these.
There are two things very important when loading Zip files.
Make sure you're using a request method that doesn't contain the Accept-Encoding: header. If it's in the request then the response is not a zip file, it's a gzip compressed zip file. So if you're writing that directly to disk while it's downloading then it won't actually be a zip file. You can use something like this to load the zip file:
URL url = new URL(remoteFilePath);
URLConnection connection = url.openConnection();
InputStream in = new BufferedInputStream(connection.getInputStream());
FileOutputStream f = new FileOutputStream(localFile);
//setup buffers and loop through data
byte[] buffer = new byte[1024];
long total = 0;
long fileLength = connection.getContentLength();
int len1 = 0;
while((len1 = in.read(buffer)) != -1) {
if(_cancel) break;
total += len1;
_Progress = (int) (total * 100 / fileLength);
f.write(buffer,0,len1);
handler.post(updateProgress);
}
f.close();
in.close();
When using input and out streams, do NOT use the read(buffer) or write(buffer) method, you need to use read/write(buffer,0,len). Otherwise what you're writing or reading may end up with garbage data in it. The former (read(buffer)) will always read the entire buffer, but there may actually not be a full buffer, for example if the last iteration of the loop only read 512 bytes. So here's how you'd unzip the file:
String _location = model.getLocalPath();
FileInputStream fin = new FileInputStream(localFile);
ZipInputStream zin = new ZipInputStream(fin);
ZipEntry ze = null;
while((ze = zin.getNextEntry()) != null) {
if(_cancel) break;
System.out.println("unzipping " + ze.getName());
System.out.println("to: " + _location + ze.getName());
if(ze.isDirectory()) {
File f = new File(_location + ze.getName());
f.mkdirs();
} else {
byte[] buffer2 = new byte[1024];
FileOutputStream fout = new FileOutputStream(_location + ze.getName());
for(int c = zin.read(buffer2); c > 0; c = zin.read(buffer2)) {
fout.write(buffer2,0,c);
}
zin.closeEntry();
fout.close();
}
}
zin.close();

end of stream error while downloading file? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Android:“Unexpected end of stream” exception downloading large files
I'm downloading a file with the following code below. The file is approx. 5MB in size. However, I'm getting a java.io.IOException "unexpected end of stream" error when the download is around 60-90%
I don't understand how to solve it and it's driving me crazy.
EDIT: Could someone at least just test it, if it downloads a file successfully on your phone. This will allow me to determine whether the problem is my phone or the code.
try {
URL url = new URL(full_url);
conexion = (URLConnection)url.openConnection();
conexion.setReadTimeout(20000);
conexion.connect();
File file = new File(root.getAbsolutePath()+"/", fileName);
int lenghtOfFile = conexion.getContentLength();
System.out.println("content-length-header is: " + lenghtOfFile);
InputStream input = conexion.getInputStream();
OutputStream output = new FileOutputStream(file);
byte data[] = new byte[8192];
long total = 0;
contentView.setTextViewText(R.id.status_text,"Downloading file " + (78 - GlobalData.missingFiles.size()) + " of " + 77);
int downloadProgress = (int)((total*100)/lenghtOfFile);
int lastProgressUpdate=0;
while ((count = input.read(data)) != -1) {
System.out.println("available bytes:" + input.available());
total += count;
downloadProgress = (int)((total*100)/lenghtOfFile);
Log.e("totaltotal","" + (int)((total*100)/lenghtOfFile));
output.write(data,0,count);
if(downloadProgress%20==0 && downloadProgress != lastProgressUpdate) {
notification.contentView.setProgressBar(R.id.status_progress, 100,downloadProgress, false);
notificationManager.notify(1,notification);
lastProgressUpdate=downloadProgress;
}
if(downloadProgress == 100){
GlobalData.downloadFiles.add("" +fileName);
GlobalData.missingFiles.remove(fileName);
}
}
output.flush();
output.close();
input.close();
if(downloadProgress != 100){
File temp_file = new File(root.getAbsolutePath()+"/", fileName);
try{
if(temp_file.exists()){
boolean del_main = temp_file.delete();
Log.e("File","Does file exists: " + del_main);
Log.e("FilePath","PATH: " + temp_file.getAbsolutePath());
}else{
Log.e("File Exists NOT","NOT EXISTING");
}
}catch(Exception e){
Log.e("FileDelete","deleting is giving problems");
}
}
} catch (Exception e) {
Log.e("PRINTSTACK","STACK:" + e.getMessage());
e.printStackTrace();
System.out.println("Downloading didn't work");
killService();
}
For some reason the input stream is closing prematurely. Often this is since an inputstream is read mulitple times at once, but I'm guessing this is not the case here, even though you for some reason have conexion available in a wider scope than we see here.
You say conexion = (URLConnection)url.openConnection(); instead of the expected URLConnection conexion = url.openConnection();. Please make sure you do not try to fetch the input stream twice.
The only other thing I can see that is weird when I look is that you use the inputstream from conexion.getInputStream() directly. Try wrapping it in a buffered input stream as such:
InputStream input = new BufferedInputStream(connexion.getInputStream());

Copying Xml File From Res/Xml Folder to Device Storage

I'm trying to copy an xml file from the res/xml folder to the device storage but I'm really struggling on how to do this.
I know that the starting point is to get an InputStream to read the xml file. This is achieved by using this:
InputStream is = getResources().openRawResource(R.xml.xmlfile);
Eventually the output stream will be:
file = new File("xmlfile.xml");
FileOutputStream fileOutputStream = new FileOutputStream(file);
But I'm really struggling on how to read and copy all the information from the initial xml file correctly and accurately.
So far, I've tried using various InputStream and OutputStream to read and write (DataInputStream, DataOutputStream, OutputStreamWriter, etc.) but I still didn't managed to get it correctly. There are some unknown characters (encoding issue?) in the produced xml file. Can anyone help me on this? Thanks!
From res/xml you can't you have to put all files in your assets folder then use below code
Resources r = getResources();
AssetManager assetManager = r.getAssets();
File f = new File(Environment.getExternalStorageDirectory(), "dummy.xml");
InputStream is = = assetManager.open("fileinAssestFolder.xml");
OutputStream os = new FileOutputStream(f, true);
final int buffer_size = 1024 * 1024;
try
{
byte[] bytes = new byte[buffer_size];
for (;;)
{
int count = is.read(bytes, 0, buffer_size);
if (count == -1)
break;
os.write(bytes, 0, count);
}
is.close();
os.close();
}
catch (Exception ex)
{
ex.printStackTrace();
}
I think you should use the raw folder instead. Have a look at http://developer.android.com/guide/topics/resources/providing-resources.html.
You can also use this code:
try {
InputStream input = getResources().openRawResource(R.raw.XZY);
OutputStream output = getApplicationContext().openFileOutput("xyz.mp3", Context.MODE_PRIVATE);
byte data[] = new byte[1024];
long total = 0;
int count;
while ((count = input.read(data)) != -1) {
total += count;
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
} catch (Exception e) {
}
And when you need file use this code:
File k =getApplicationContext().getFileStreamPath("xyz.mp3");

Image uploaded from the android app space seems corrupted

In my android application, I need to upload a image in my Assets/Drawable/raw folder to the server.
I tried the following:
InputStream fileInputStream;
if(imageChanged) {
File file = New File("filename");
fileInputStream = new FileInputStream(file);
}else {
fileInputStream = ctx.getAssets().open("default.png");
}
int bytesAvailable;
byte[] buffer = new byte[102400];
while((bytesAvailable = fileInputStream.available()) > 0) {
int bufferSize = Math.min(bytesAvailable, 102400);
if(bufferSize<102400){
buffer = new byte[bufferSize];
}
int bytesRead = fileInputStream.read(buffer, 0,bufferSize);
dos.write(buffer, 0, bytesRead);
}
This executes fine. I am able to read the inputstream and write bytes to the DataOutputStream, the image is uploaded to the server.
Anyhow, the image at the server appears to be corrupted - only for the default image (uploaded in the 'else' block. The 'if' block image is not getting corrupted)
I also tried placing default.png in the 'raw' folder and tried the below
fileInputStream = ctx.getResources().openRawResource(R.drawable.default);
Same result here - the image at the server is corrupted.
I am starting to doubt if this is because the default.png is in the application space.
Can I get some help towards the proper way to upload an image in the application space (drawable/asset/raw)?
thanks!
nimi
It might have to do with the buffer size? I tried two different methods to read/write a png from the assets folder and both produced a working image. I used FileOutputStream to write to the sdcard but that should not be an issue.
InputStream is, is2;
FileOutputStream out = null, out2 = null;
try {
//method 1: compressing a Bitmap
is = v.getContext().getAssets().open("yes.png");
Bitmap bmp = BitmapFactory.decodeStream(is);
String filename = Environment.getExternalStorageDirectory().toString()+File.separator+"yes.png";
Log.d("BITMAP", filename);
out = new FileOutputStream(filename);
bmp.compress(Bitmap.CompressFormat.PNG, 90, out);
//method 2: Plain stream IO
String filename2 = Environment.getExternalStorageDirectory().toString()+File.separator+"yes2.png";
out2 = new FileOutputStream(filename2);
Log.d("BITMAP", filename2);
int r, i=0;
is2 = v.getContext().getAssets().open("yes.png");
while ((r = is2.read()) != -1) {
Log.d ("OUT - byte " + i, "Value: " + r);
out2.write(r);
i++;
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (out != null)
out.close();
if (out2 != null)
out2.close();
} catch (IOException e) {
e.printStackTrace();
}
}

Categories

Resources