I can unzip the 1st and 2nd entry of a zip file I am reading from the web, but then I get the MalformedInputException error. The zip file consists of unicode file names of mp3 files. I created the zip file that I placed on the web using Winzip (I tried both v11 and V18).
The mp3 files are all at the 'root' level in the zip file, i.e. not stored in subfolders.
I tried first with ZipInputStream. The last attempt (below) is with ArchiveInputStream. (I noticed that ArchiveInputStream didn't have a closeEntry() method like ZipInputStream - not that it made any difference).
The error always occurs on the line that gets the next entry.
while ((entry = (ZipArchiveEntry)zipStream.getNextEntry()) != null)
The code is
private void unizpMediaFile(String mediaDirectory, String zipFileURL) {
InputStream inputStream = null;
ArchiveInputStream zipStream = null;
ArchiveEntry entry = null;
try {
// make sure can write to (probably) sd card
File mediaFileDirectory = createMediaDirectory(mediaDirectory);
if (mediaFileDirectory == null)
return;
inputStream = getHttpInputStream(zipFileURL);
if (inputStream == null) {
return;
}
zipStream = new ArchiveStreamFactory().createArchiveInputStream(ArchiveStreamFactory.ZIP,new BufferedInputStream(
inputStream) );
while ((entry = (ZipArchiveEntry)zipStream.getNextEntry()) != null) {
Log.i(TAG,"Entry:" + entry.getName());
if (entry.isDirectory()) {
if (false == new File( mediaFileDirectory.getAbsoluteFile()
+ File.separator + entry.getName()).mkdirs()) {
return;
}
} else {
OutputStream out = new FileOutputStream(mediaFileDirectory.getAbsoluteFile()
+ File.separator + entry.getName());
int size;
byte[] buffer = new byte[4096];
FileOutputStream outStream = new FileOutputStream(
mediaFileDirectory.getAbsoluteFile()
+ File.separator + entry.getName());
BufferedOutputStream bufferOut = new BufferedOutputStream(
outStream, buffer.length);
while ((size = zipStream.read(buffer, 0, buffer.length)) != -1) {
bufferOut.write(buffer, 0, size);
}
bufferOut.flush();
bufferOut.close();
out.close();
Log.i(TAG,"Entry:" + entry.getName() + " closed.");
}
}
maintOpDetails.append(res.getString(R.string.load_complete));
updateLoadDetails(maintOpDetails.toString() );
} catch (FileNotFoundException e) {
Log.e(TAG, "unizpMediaFile" + e.toString());
storeErrorMessage(res.getString(R.string.error_reading_media_zip_file,
zipFileURL, e.toString()));
} catch (IOException e) {
Log.e(TAG, "unizpMediaFile" + e.toString());
storeErrorMessage(res.getString(R.string.error_reading_media_zip_file,
zipFileURL, e.toString()));
} catch (ArchiveException e) {
Log.e(TAG, "unizpMediaFile" + e.toString());
storeErrorMessage(res.getString(R.string.error_reading_media_zip_file,
zipFileURL, e.toString()));
}
finally {
if (inputStream != null){ try {inputStream.close();} catch (Exception e){} }
if (zipStream != null){ try {zipStream.close();} catch (Exception e){} }
}
}
private InputStream getHttpInputStream(String url) {
HttpResponse response;
InputStream is = null;
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpGet httppost = new HttpGet("http://" + url);
try {
response = httpClient.execute(httppost);
HttpEntity ht = response.getEntity();
BufferedHttpEntity buf;
buf = new BufferedHttpEntity(ht);
is = buf.getContent();
} catch (ClientProtocolException e) {
Log.e(TAG, "getHttpInputStream" + e.toString());
storeErrorMessage(res.getString(R.string.error_reading_file_at_url,
url, e.toString()));
} catch (ConnectTimeoutException cte) {
Log.e(TAG, "getHttpInputStream" + cte.toString());
storeErrorMessage(res.getString(R.string.connect_timetout_error, url));
} catch (IOException e) {
Log.e(TAG, "getHttpInputStream" + e.toString());
storeErrorMessage(res.getString(R.string.error_reading_file_at_url,
url, e.toString()));
}
return is;
}
From the log I get
I/LoadLanguageLessonService(3102): Entry:evet.mp3
I/LoadLanguageLessonService(3102): Entry:evet.mp3 closed.
I/LoadLanguageLessonService(3102): Entry:hay?r.mp3
I/LoadLanguageLessonService(3102): Entry:hay?r.mp3 closed.
E/LoadLanguageLessonService(3102): unizpMediaFilejava.nio.charset.MalformedInputException: Length: 1
(The cut/paste from the log to here caused the unicode filename values to be converted to the '?' you see above.)
I checked out various SO postings with no luck.
Any ideas?
Some followup
I modified my code to first download the zip file to my phone and then unzip it from there. No luck doing it that way either.
I also used the following code
ZipFile zipFile = null;
try {
zipFile = new ZipFile(zipFilename);
Enumeration<?> enu = zipFile.entries();
while (enu.hasMoreElements()) {
ZipEntry zipEntry = (ZipEntry) enu.nextElement();
String name = zipEntry.getName();
long size = zipEntry.getSize();
long compressedSize = zipEntry.getCompressedSize();
Log.e(TAG, String.format("name: %-20s | size: %6d | compressed size: %6d\n",
name, size, compressedSize));
}
} catch (IOException e) {
e.printStackTrace();
throw e;
}
to list all the entries in the zip file and found that the unicode characters all show up as a small black diamond with a question mark inside (after cut/paste into SO the characters show up just with the ? mark).
I also downloaded AndroZip and WinZip for Android and viewed the zip file via both apps on my phone. Again the unicode file names were corrupted.
At this point I am stuck. I think I will shift gears and see about downloading the files one by one.
Related
I'm trying to upload some files to a Local FTP server. The observable list has all the files, and are uploaded by looping the array
I'm using the commons-net-3.6.jar Library.
The Directory and everything get's created but the images uploaded are corrupted. Huge change in color (looks like an old static TV image with colors)
What am i doing wrong?
NOTE! Something I noticed was that the sizes of file's are the same in KB but differs slightly by bytes.
ObservableList<File> uploadFiles = FXCollections.observableArrayList();
FTPClient client = new FTPClient();
InputStream fis = null;
FTPConnection con = new FTPConnection();
con.readData(); //gets username and password
uploadFiles = Something.getFiles(); //Gets Files
try {
client.connect(con.getServerIp());
client.login(con.getUsername(), con.getPassword());
String pathname = getPathname();
client.makeDirectory(pathname);
for (int i = 0; i < uploadFiles.size(); i++) {
fis = new FileInputStream(uploadFiles.get(i));
String filename = uploadFiles.get(i).getName();
String uploadpath = pathname+"/"+filename;
System.out.println("Uploading File : " + uploadpath);
client.storeFile(uploadpath, fis);
}
client.logout();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fis != null) {
fis.close();
}
client.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
Setting the file type to Binary did the Trick!
client.setFileType(FTP.BINARY_FILE_TYPE);
I am trying to Edit a existing file which is in my R.raw folder
i am able to read the file
but when i run the write function it is not working .
public void tofile(View v){
BufferedWriter bw=null;
FileWriter fw =null;
try {
String path = ("/Page2/res/raw/text.txt");
File file = new File(path);
fw = new FileWriter(file);
bw = new BufferedWriter(fw);
bw.write("hello");
bw.flush();
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
i even tried
fw = new FileWriter(file,true);
if i add toast between even line it seems to get stuck at
fw = new FileWriter(fw);
You can't able to Write
As #CommonsWare said you can't write on resources but you could use internal storage using openFileOutput and openFileInput and BufferedReaders and BufferedWriters. You can check it here
from the answer of #rodkarom in the following link
Write to a Text File Resource in Android
and #Andro Selva says same thing in the following link
How to write a file in Android to the raw folder?
you can able to read the content from the textfile which is present in the res/raw folder dude
read the file from res folder
public String readStringFromResource(Context ctx, int resourceID) {
StringBuilder contents = new StringBuilder();
String sep = System.getProperty("line.separator");
try {
InputStream is = ctx.getResources().openRawResource(R.raw.trails);
BufferedReader input = new BufferedReader(new InputStreamReader(is), 1024*8);
try {
String line = null;
while (( line = input.readLine()) != null){
contents.append(line);
contents.append(sep);
}
}
finally {
input.close();
}
}
catch (FileNotFoundException ex) {
Log.e(TAG, "Couldn't find the file " + resourceID + " " + ex);
return null;
}
catch (IOException ex){
Log.e(TAG, "Error reading file " + resourceID + " " + ex);
return null;
}
return contents.toString();
}
check it and inform
I am creating an XML file from my Database and storing it in Internal storage. I require data from XML file into a single string. For which, i am using the following method.
BufferedReader br;
try {
br = new BufferedReader(new FileReader(new File(pathDAR)));
String line;
StringBuilder sb = new StringBuilder();
while ((line = br.readLine()) != null) {
sb.append(line.trim());
String temp = sb.toString().substring(38);
Log.v("XML TO String", "" + temp);
Log.v("Lengths : ", "" + temp.length() + " " + sb.length());
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
I have been getting string in the Log, but it seems to be stopping abruptly in the middle.
For e.g. I am supposed to get records string like this. Beginning and ending with database tag.
<database name="DAR.db"><table name="DARWorkDetails"><row><col name="id">1</col><col name="date">05-28-2013</col><col name="visited_city_ID">1264</col><col name="employee_ID">107</col><col name="work_type_ID">1</col><col name="name">null</col><col name="customer_Id">null</col><col name="customer_type_ID">null</col><col name="sub_customer_id">null</col><col name="reason_ID">14</col><col name="reason">ABM SM MEETING</col><col name="remarks">gfhii</col><col name="work_with">211,162</col><col name="IsCustomer">N</col><col name="created_by">107</col><col name="position_id">72</col><col name="designation_Id">3</col><col name="submit_date">05-28-2013</col><col name="IsFinal">null</col></row></table></database>
Instead i have been getting string like this :
<database name="DAR.db"><table name="DARWorkDetails"><row><col name="id">1</col><col name="date">05-28-2013</col><col name="visited_city_ID">1264</col><col name="employee_ID">107</col><col name="work_type_ID">1</col><col name="name">null</col><col name="customer_Id">null</col><col name="customer_type_ID">null</col><col name="sub_customer_id">null</col><col name="reason_ID">14</col><col name="reason">ABM SM MEETING</col><col name="remarks">gfhii</col><col name="work_with">211,162</col><col name="IsCustomer">N</col><col name="created_by">107</col><col name="position_id">72</col><col name="designation_Id">3</col><col name="submit_date">05-28-2013</col><col name="IsFinal">null</co
The String is stopping in the middle. For the sake of example i have only put small example string above. In reality my database has multiple records and i have counted length of the string to around 15640, before abrupt end of the string.
Are there any limitations with StringBuilder in regards to storing characters? I suppose there is memory issue since i have been able to get string fully for records fewer than 10. Problem seems to be arising when records go into upwards of 10. Any help in understanding of solving this issue would be much appreciated.
Please check
It may happen your output is perfect but your Log cat is not displaying it whole.
Log.v("XML TO String", "" + temp);
Log.v("Lengths : ", "" + temp.length() + " " + sb.length());
See reference
I created this class to read strings from a xml file saved in internal storage device, it returns a list , if you want the whole extended string you only need concatenate to link together, if doesn't found the file return an empty list this is all you need to read XML files and parse to Strings, I hope to help!
public class readXMLFile {
private String filePath = "FileStorage";
private String fileName = "File.xml";
private final String tag = "Internal Read Persistence";
File internalFileData;
public readXMLFile() {// default constructor
}
public File getXMLFile(Context context){
File directory = null;
ContextWrapper cw = new ContextWrapper(context);
directory = cw.getDir(filePath, Context.MODE_PRIVATE);
internalFileData = new File(directory, fileName);
if(internalFileData.exists()){
Log.i("ReadXMLFile","File returned");
return internalFileData;
}
else{
Log.i(tag,"the file doesn't exists!");
return null;
}
}
public List<String> readFile(Context context) {
List<String> l = new LinkedList<String>();
try {
File directory = null;
ContextWrapper cw = new ContextWrapper(context);
directory = cw.getDir(filePath, Context.MODE_PRIVATE);
internalFileData = new File(directory, fileName);
if (internalFileData.exists()) {
Log.i("Internal Data", "the root exists!!");
try {
FileInputStream fis = new FileInputStream(internalFileData);
DataInputStream in = new DataInputStream(fis);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String line;
while ((line = br.readLine()) != null) {
l.add(line);
}
try {
if (in != null) {
in.close();
}
} catch (Exception e) {
Log.i(tag, "Exception closing persistence connection");
}
} catch (Exception e) {
Log.wtf("Fatal Exception", "Exception: " + e.getMessage());
}
} else {
Log.i(tag, "File doesn't exists");
return l;//return empty list
}
} catch (Exception e) {
Log.wtf(tag, "Exception DATA READING: " + e.getMessage());
return l;
}
Log.i(tag, "file found return");
return l;
}
}
Could you point me out to a code or url where I can find some examples how to use dropbox java api and upload binary files like, .doc files jpg and video files.
Current examples in the web only point to uploading a text file. But when I try to read files using java InputStream and convert them to byte array and pass into dropbox file upload functions files get corrupted. Same issue with downloading files as well. Thanks in Advance.
Regards,
Waruna.
EDIT--
Code Sample
FileInputStream fis = new FileInputStream(file);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte [] buf = new byte[1024];
for(int readNum; (readNum = fis.read(buf)) != -1;) {
bos.write(buf, 0, readNum);
System.out.println("read "+ readNum + "bytes,");
}
ByteArrayInputStream inputStream2 = new ByteArrayInputStream(bos.toByteArray());
Entry newEntry = mDBApi.putFile("/uploads/"+file.getName(), inputStream2, file.toString().length(), null, null);
System.out.println("Done. \nRevision of file: " + newEntry.rev + " " + newEntry.mimeType);
return newEntry.rev;
The 3rd argument of DropboxAPI.putFile() should be the number of bytes to read from the input stream - You are passing the length of the filename.
Instead of
Entry newEntry = mDBApi.putFile("/uploads/"+file.getName(), inputStream2,
file.toString().length(), null, null);
Use
Entry newEntry = mDBApi.putFile("/uploads/"+file.getName(), inputStream2,
bos.size(), null, null);
I don't think you need to convert to byte array, simply use FileInputStream is enough for a file, txt as well as binary. The following code works, I just tested with JPG.
DropboxAPI<?> client = new DropboxAPI<WebAuthSession>(session);
FileInputStream inputStream = null;
try {
File file = new File("some_pic.jpg");
inputStream = new FileInputStream(file);
DropboxAPI.Entry newEntry = client.putFile("/testing.jpg", inputStream,
file.length(), null, null);
System.out.println("The uploaded file's rev is: " + newEntry.rev);
} catch (DropboxUnlinkedException e) {
// User has unlinked, ask them to link again here.
System.out.println("User has unlinked.");
} catch (DropboxException e) {
System.out.println("Something went wrong while uploading.");
} catch (FileNotFoundException e) {
System.out.println("File not found.");
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {}
}
}
public void handleFileUpload(FileUploadEvent event) {
ExternalContext extContext = FacesContext.getCurrentInstance().getExternalContext();
File result = new File(extContext.getRealPath("//admin//images") + "//" + event.getFile().getFileName());
// File result = new File("D:\\Netbeans Project\\mcGrawLibPro\\mcGrawLibPro-war\\web\\item", event.getFile().getFileName());
File bg = new File(extContext.getRealPath("//admin//images")+"//macback.png");
try {
bg.renameTo(new File(extContext.getRealPath("//admin//images")+"//bg.png"));
File f1 = new File(extContext.getRealPath("//admin//images") + "//macback.png" );
result.renameTo(f1);
//System.out.println(f1);
System.out.println(result);
FileOutputStream fileOutputStream = new FileOutputStream(result);
byte[] buffer = new byte[BUFFER_SIZE];
int bulk;
InputStream inputStream = event.getFile().getInputstream();
while (true) {
bulk = inputStream.read(buffer);
if (bulk < 0) {
break;
}
fileOutputStream.write(buffer, 0, bulk);
fileOutputStream.flush();
}
fileOutputStream.close();
inputStream.close();
FacesMessage msg = new FacesMessage("OK",
event.getFile().getFileName() + " was upload.");
FacesContext.getCurrentInstance().addMessage(null, msg);
} catch (IOException e) {
e.printStackTrace();
FacesMessage error = new FacesMessage("Can't upload!");
FacesContext.getCurrentInstance().addMessage(null, error);
}
}
my problem is when i upload a picture type png such as aaa.png, it can upload on server but it not rename, after upload aaa.png and i re-upload this picture(aaa.png) it can change name but it have 2 file one is aaa.png and one is macback.png
What's wrong in my code?
Thank you !
Here's what I think you are trying to do:
When you upload a file, you want to call it macback.png, not its original file name.
When you upload a second file, you want to rename macback.png to bg.png first, then save the uploaded file as macback.png.
If that is the case, first you need to test for the existence of the macback.png file and rename it if it exists. Then you create a File object for the macback.png file and open a FileOutputStream to that file to write the uploaded file to.
Something like this:
public void handleFileUpload(FileUploadEvent event) {
ExternalContext extContext = FacesContext.getCurrentInstance().getExternalContext();
File result = new File(extContext.getRealPath("//admin//images") + "//macback.png");
if(result.exists()) {
result.renameTo(new File(extContext.getRealPath("//admin//images")+"//bg.png"));
}
try {
File targetFile = new File(extContext.getRealPath("//admin//images") + "//macback.png" );
FileOutputStream fileOutputStream = new FileOutputStream(targetFile);
byte[] buffer = new byte[BUFFER_SIZE];
int bulk;
InputStream inputStream = event.getFile().getInputstream();
while (true) {
bulk = inputStream.read(buffer);
if (bulk < 0) {
break;
}
fileOutputStream.write(buffer, 0, bulk);
fileOutputStream.flush();
}
fileOutputStream.close();
inputStream.close();
FacesMessage msg = new FacesMessage("OK",
event.getFile().getFileName() + " was upload.");
FacesContext.getCurrentInstance().addMessage(null, msg);
} catch (IOException e) {
e.printStackTrace();
FacesMessage error = new FacesMessage("Can't upload!");
FacesContext.getCurrentInstance().addMessage(null, error);
}
}
Ok, so let's see if I got it this time:
You want the first A.png to save as A.png.
The second time A.png is uploaded, you want the first A.png to be renamed to macback.png and the second A.png to be stored as A.png.
If that's the case, try this:
public void handleFileUpload(FileUploadEvent event) {
ExternalContext extContext = FacesContext.getCurrentInstance().getExternalContext();
File result = new File(extContext.getRealPath("//admin//images") + "//" + event.getFile().getFileName());
if(result.exists()) {
result.renameTo(new File(extContext.getRealPath("//admin//images")+"//mackback.png"));
}
try {
File targetFile = new File(extContext.getRealPath("//admin//images") + "//" + event.getFile().getFileName() );
FileOutputStream fileOutputStream = new FileOutputStream(targetFile);
byte[] buffer = new byte[BUFFER_SIZE];
int bulk;
InputStream inputStream = event.getFile().getInputstream();
while (true) {
bulk = inputStream.read(buffer);
if (bulk < 0) {
break;
}
fileOutputStream.write(buffer, 0, bulk);
fileOutputStream.flush();
}
fileOutputStream.close();
inputStream.close();
FacesMessage msg = new FacesMessage("OK",
event.getFile().getFileName() + " was upload.");
FacesContext.getCurrentInstance().addMessage(null, msg);
} catch (IOException e) {
e.printStackTrace();
FacesMessage error = new FacesMessage("Can't upload!");
FacesContext.getCurrentInstance().addMessage(null, error);
}
}
I believe the issue is you are trying to rename result to f1 too early. At the point where you are calling result.renameTo(f1) you have not yet created the file referenced by result so the rename has no effect. You cannot rename a file before it exists on disk.
Now, you don't really need to rename result. Since you have not created the file, you can simply use f1 as the argument to FileOutputStream instead of result.