Java InputReader. Detect if file being read is binary? - java

I had posted a question in regards to this code. I found that JTextArea does not support the binary type data that is loaded.
So my new question is how can I go about detecting the 'bad' file and canceling the file I/O and telling the user that they need to select a new file?
class Open extends SwingWorker<Void, String>
{
File file;
JTextArea jta;
Open(File file, JTextArea jta)
{
this.file = file;
this.jta = jta;
}
#Override
protected Void doInBackground() throws Exception
{
BufferedReader br = null;
try
{
br = new BufferedReader(new FileReader(file));
String line = br.readLine();
while(line != null)
{
publish(line);
line = br.readLine();
}
}
finally
{
try
{
br.close();
} catch (IOException e) { }
}
return null;
}
#Override
protected void process(List<String> chunks)
{
for(String s : chunks)
jta.append(s + "\n");
}
}

You could cover the most by sniffing the mime type based on the file extension or, even better, the actual file content. You can do that with help of among others jMimeMagic (Maven coords here). If the mime type does not start with "text", then it's certainly not a text file.
String mimeType = Magic.getMagicMatch(file, false).getMimeType();
boolean text = mimeType.startsWith("text");

I found that MIME types can really help with this!
JAF

For those who read this and are curious as to what I have done to fix the File reading problem.... I have instead implemented a FileReader and have experienced no problems on Windows. I have however noticed on Linux that there are some problems which tends to lead to a crash. Also I noticed when running through an IDE such as Netbeans I receive various runtime errors when trying to load a binary file and massive slow-down; but when I execute the .jar as an executable and not from the IDE it works fine.
Here is relevant code that I have had no problem with (even when loading binary file types such as .mp3, .exe, etc.)
/*...*/
#Override
protected Void doInBackground() throws Exception {
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(file));
int ch = br.read();
while(ch != -1) {
publish(ch);
ch = br.read();
}
}
finally {
try {
br.close();
} catch (IOException e) {}
}
System.gc();
return null;
}
/*...*/

Related

Java print writer seems to detect file, but it does not write

I am using Netbeans on OS X and cannot seem to write text to a text file that I have in a package named "assets".
Below is the way I tried to accomplish writing to the text file and so far my method of doing this is not working.
The way I tried to approach this problem was converting a string to url, then converting the url to a uri. Then I used the uri for the new file parameter. After I tried to write a string using the class print writer.
public class Experiment {
File createFile(String path) {
java.net.URL url = getClass().getResource(path);
URI uri;
try {
uri = url.toURI();
}
catch (URISyntaxException e) {
uri = null;
}
if ((url != null) && (uri != null)) {
System.out.println("file loading sucess");
return new File(uri);
}
else {
System.out.println("Error file has not been loaded");
return null;
}
}
File file = createFile("/assets/myfile.txt");
public static void main(String[] args) {
Experiment testrun = new Experiment();
try {
PrintWriter writer = new PrintWriter(new FileWriter(testrun.file));
writer.println("it works");
writer.flush();
writer.close();
System.out.println("string was written");
}
catch (IOException e) {
System.out.println("there was an error while writing");
}
}
}
The output given from my try catch statements say that the file write code was executed.
file loading sucess
string was written
BUILD SUCCESSFUL (total time: 2 seconds)
I have also tried using absolute string paths for making a new file, but with null results. I am running out of ideas and hoping for some guidance or solution from somebody.

Open files using root android

In java, after getting root permissions, how can I open files with it? Can I open them with File class or do I have to use a command?
You will have to use the su command.
I suggest you have a look at how to use su
Sample code to read a file ( I haven't tested it but it should give you an idea ):
public static void runAsRoot(String[] cmds){
try {
Process p = Runtime.getRuntime().exec("su");
BufferedReader reader = new BufferedReader(p.getInputStream());
StringBuilder out = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
out.append(line); // add everything to StringBuilder
// here you can have your logic of comparison.
if(line.toString().equals(".")) {
// do something
}
}
} catch(IOException e) {
e.printStackTrace();
} catch(InterruptedException e) {
e.printStackTrace();
}

Batch process large file split by line endings using FTP streaming in Mule

I'm trying to read in a large file, 100K+ rows, split the file and process the rows. I've set the FTP connector to stream as the file is too large to read into memory but the payload is InputStream which cannot be read into the batch process.
I have a custom java component which converts the InputStream to a String but I want to be able to return the value in batches (as building the string will ultimately lead to Out of Memory errors anyway) but if I set a counter then the the java component stops reading the InputStream.
After this I use a splitter to turn the payload into a Iterable object so the batch process can execute.
Is there a way to return the value from the custom java component and continue processing the file to return batches of 500? Or is there a way to make the batch process read InputStream datatypes?
I can't find anything online
<flow name="bulk-flow">
<ftp:inbound-endpoint host="${ftp.host}" port="${ftp.port}" path="${ftp.path}" user="${ftp.user}" password="${ftp.pass}" connector-ref="ftpConnector" responseTimeout="10000" doc:name="FTP" pollingFrequency=1000"></ftp:inbound-endpoint>
<batch:execute name="batch" doc:name="batch"></batch:execute>
</flow>
<batch:job name="batch">
<batch:input>
<custom-transformer class="InputStreamToString" doc:name="Java"></custom-transformer>
<splitter expression="#[payload.split('\n')]" doc:name="Splitter"></splitter>
</batch:input>
<batch:process-records>
and the custom java class
public class InputStreamToString extends AbstractMessageTransformer{
#Override
public String transformMessage(final MuleMessage muleMessage, String arg1)
throws TransformerException {
String result = "";
try {
if (muleMessage.getPayload() != null && muleMessage.getPayload() instanceof InputStream) {
InputStream is = (InputStream) muleMessage.getPayload();
result = getStringFromInputStream(is);
}
} catch (Exception e) {
throw new TransformerException(new EscapeUnicodeTransformer(), e);
}
return result;
}
// convert InputStream to String
private static String getStringFromInputStream(InputStream is) {
BufferedReader br = null;
StringBuilder sb = new StringBuilder();
int count = 0;
String line;
try {
br = new BufferedReader(new InputStreamReader(is));
while ((line = br.readLine()) != null && count < 500) {
sb.append(line);
sb.append("\n");
count++;
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return sb.toString();
}
Thanks a lot for any ideas!

Reading a file from a Res folder

I have put a file "template.html" inside RAW folder and I want to read it into a InputStream. But it is returning me null. Can't understand what is wrong in the below code
e.g. fileName passed as parameter is "res/raw/testtemplate.html"
public String getFile(String fileName) {
InputStream input = this.getClass().getClassLoader().getResourceAsStream(fileName);
return getStringFromInputStream(input);
}
Also, there might be a better solution by putting these files in a particular subfolder and putting it inside Asset folder but then I believe I would need to pass context in AssetManager. I don't understand that solution, sorry I am new to android development. Can someone shed some light regarding how this approach can be achieved.
EDIT
I have started implementing this solution with Assets. Below method is supposed to return a string containing the entire text of the file stored as template.html.
getFile("template.html") // I am sending extension this time
Problem getting error getAssets() is undefined.
public String getFile(String fileName) {
BufferedReader reader = null;
StringBuilder sb = new StringBuilder();
String line;
try {
reader = new BufferedReader(new InputStreamReader(getAssets().open(fileName)));
while ((line = reader.readLine()) != null) {
sb.append(line);
}
}
catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return sb.toString();
}
use this
new BufferedInputStream(getResources().openRawResource(filepath));
this will return a buffered input stream
The file name should be without extension :
InputStream ins = getResources().openRawResource(
getResources().getIdentifier("raw/FILENAME_WITHOUT_EXTENSION",
"raw", getPackageName()));
For this purposes uses assets folder:
assets/
This is empty. You can use it to store raw asset files. Files that you save here are compiled into an .apk file as-is, and the original filename is preserved. You can navigate this directory in the same way as a typical file system using URIs and read files as a stream of bytes using the AssetManager. For example, this is a good location for textures and game data.
So, you could easy get access at assets with context: context.getAssets()
BufferedReader reader = null;
try {
reader = new BufferedReader(
new InputStreamReader(context.getAssets().open("filename.txt")));
}
} catch (IOException e) {
//log the exception
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
//log the exception
}
}
}

TextViews with utf-8 and special characters

StackOverflowers!
I load some text from a webpage. Everything works fine, and shows up in the TextViews. But, when the blogs on the webpage have some words with special characters like an: é or something. My Textview show characters like these: Á©..
Can anybody tell what I need to import, call or something like that to show everything tidy?
Thanks,
UPDATE 1 + 2:
TextView intro_text = (TextView) item_view.findViewById(R.id.item_intro);
intro_text.setText(Html.fromHtml(current_post.get_intro()));
current_post.get_intro() is the adres where the loaded text is. :-) Because I use a listview with many rows..
EDIT:
public class connectTask extends AsyncTask<String, String, String> {
#SuppressWarnings({ "deprecation" })
#Override
protected String doInBackground(String... message) {
Log.v("Correct Load", "Starting ");
URL u;
InputStream is = null;
DataInputStream dis;
String s;
try {
Log.v("Connecting...");
u = new URL("http://.......");
is = u.openStream();
dis = new DataInputStream(new BufferedInputStream(is));
Log.v("Connected");
try {
while ((s = dis.readLine()) != null) {
if (s.contains("post_wrapper")) {
for (int i = 0; i < j; i++) {
while ((s = dis.readLine()) != null) {
if (s.contains("post_intro")) {
break;
}
}
if (s != null) {
s = dis.readLine();
Log.v("Intro", s); intro[i] = s.substring(s.indexOf("<p>") + 3, s.indexOf("</p>"));
Log.e("Intro", "Found intro:" + intro[i]);
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
} catch (MalformedURLException mue) {
System.out.println("Ouch - a MalformedURLException happened.");
mue.printStackTrace();
System.exit(1);
} catch (IOException ioe) {
System.out.println("Oops- an IOException happened.");
ioe.printStackTrace();
System.exit(1);
} finally {
try {
if (is != null)
is.close();
} catch (IOException {
}
}
return null;
}
This is the read/received part.
Replace
DataInputStream dis = new DataInputStream(new BufferedInputStream(is));
With
BufferedReader dis = new BufferedReader(new InputStreamReader(is, "UTF-8"));
Because DataInputStream.readLine() is deprecated and is discouraged for the following reason:
This method cannot be trusted to convert bytes to characters correctly.
BufferedReader also has a readLinemethod, so the rest of your code should be pretty much unchanged.
Also, whenever you use #SuppressWarnings({ "deprecation" }) I strongly suggest that you be extra careful and make sure you can use the deprecated method despite the warning.
tricky but worked for me: use Html.fromHtml() twice , I mean:
text.setText(Html.fromHtml(Html.fromHtml(your_html_text).toString()));
EDIT .
Your problem is not in this TextView because you are getting broken encoding even in your logcat,
so you should know when exactly , the encoding is broken ; this get_intro() is returning a bad string, so you should show us , what is this get_intro() doing ? how is it taking the string ? from what ? you should share the code of this get_intro() else nobody can help you...

Categories