I'm having a software who is doing a http GET request and then I am receiving an HttpEntity response.
This is fine to me. The problem is that I want to use read this response 2 times and I dont know which way is the best.
If I convert the entity to a string, then when I try to access again the entity, Im getting an exception that the entity has been consumed.
If I try to use the getContent method to use the InputStream I dont find a way to reread the inputStream 2 times as i need.
Can someone tell me how I can save the httpEntity result as a way I can reuse it twice ?? Shoud I create a file ? How I do that ? What about performance to write a file each time I do a GET ? How to delete that file on each call ? Where to save the file ?
If you have any other ideas, thanks for the help.
I will appreciate code examples.
I finally found how to convert a stream to a string so I did the following thing :
//Get the answer from http request
if(httpResponse!=null)
entity = httpResponse.getEntity();
else
entity = null;
//Display the answer in the UI
String result;
if (entity != null) {
//First, Open a file for writing
FileOutputStream theXMLFile=null;
try{
theXMLFile=openFileOutput("HttpResponse.dat", MODE_PRIVATE);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.e("ResultService Exception :", e.getMessage());
}
try {
if(theXMLFile!=null) {
//Save the stream to a file to be able to re read it later.
entity.writeTo(theXMLFile);
//Entity is consumed now and cannot be reuse ! Lets free it.
entity=null;
//Now, lets read this file !
FileInputStream theXMLStream=null;
try {
//Open the file for reading and convert to a string
theXMLStream = openFileInput("HttpResponse.dat");
result=com.yourutilsfunctionspackage.ServiceHelper.convertStreamToString(theXMLStream);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.e("ResultService Exception :", e.getMessage());
result=null;
}
theXMLStream.close();
theXMLStream=null;
//Use the string for display
if(result!=null)
infoTxt.setText(getText(R.string.AnswerTitle) + " = " +result);
try {
//Reopen the file because you cannot use a FileInputStream twice.
theXMLStream = openFileInput("HttpResponse.dat");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.e("ResultService Exception :", e.getMessage());
}
//Re use the stream as you want for decoding xml
if(theXMLStream!=null){
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder=null;
try {
builder = factory.newDocumentBuilder();
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(builder!=null)
{
Document dom=null;
try {
dom = builder.parse(theXMLStream);
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(dom!=null){
Element racine = dom.getDocumentElement();
NodeList nodeLst=racine.getElementsByTagName("response");
Node fstNode = nodeLst.item(0);
if(fstNode!=null){
Element fstElmnt = (Element) fstNode;
String CallingService=fstElmnt.getAttribute("service");
etc....
//Function taken from internet http://www.kodejava.org/examples/266.html
public static String convertStreamToString(InputStream is) throws IOException {
/*
* To convert the InputStream to String we use the
* Reader.read(char[] buffer) method. We iterate until the
* Reader return -1 which means there's no more data to
* read. We use the StringWriter class to produce the string.
*/
if (is != null) {
Writer writer = new StringWriter();
char[] buffer = new char[1024];
try {
Reader reader = new BufferedReader(
new InputStreamReader(is, "UTF-8"));
int n;
while ((n = reader.read(buffer)) != -1) {
writer.write(buffer, 0, n);
}
} finally {
is.close();
}
return writer.toString();
} else {
return null;
}
}
Related
I'm participating in an online Android course and have (so far) gotten no response on their forum to this issue. I'm using Android Studio on Windows 8.1.
I have the following function to read a file and load an adapter:
private void loadItems() {
BufferedReader reader = null;
try {
FileInputStream fis = openFileInput(FILE_NAME);
reader = new BufferedReader(new InputStreamReader(fis));
String title = null;
String priority = null;
String status = null;
Date date = null;
while (null != (title = reader.readLine())) {
priority = reader.readLine();
status = reader.readLine();
date = ToDoItem.FORMAT.parse(reader.readLine());
mAdapter.add(new ToDoItem(title, Priority.valueOf(priority),
Status.valueOf(status), date));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
} finally {
if (null != reader) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
My questions are:
I don't find the file named by the constant FILE_NAME anywhere on my hard drive. If the file doesn't exist shouldn't openFileInput() throw FileNotFoundException?
Why does InputStreamReader not throw an error?
Via the debugger, I've watched as The logic guarding entry into the WHILE construct happily allows a null value in the title variable to enter the loop. Am I missing something here?
Thanks in advance for any light anyone can shed!!
Markb
I am facing one problem in StringBuffer concatination for appending large characters of String from JSONArray.
My data is huge and it is coming in log after iteration of 205 indexes of Array properly
but when I am appending each row String in StringBuffer or StringBuilder from JSONArray, so it is taking on 4063 characters only not appending all characters present in JSON Array but iteration doesn't break and goes till complete 204 rows.
String outputFinal = null;
try {
StringBuilder cryptedString = new StringBuilder(1000000);
JSONObject object = new JSONObject(response);
JSONArray serverCustArr = object.getJSONArray("ServerData");
Log.d("TAG", "SurverCust Arr "+serverCustArr.length());
for (int i = 0; i < serverCustArr.length(); i++) {
String loclCryptStr = serverCustArr.getString(i);
Log.d("TAG", "Loop Count : "+i);
cryptedString.append(loclCryptStr);
}
Log.d("TAG", "Output :"+cryptedString.toString());
CryptLib _crypt = new CryptLib();
String key = this.preference.getEncryptionKey();
String iv = this.preference.getEncryptionIV();
outputFinal = _crypt.decrypt(cryptedString.toString(), key,iv); //decrypt
System.out.println("decrypted text=" + outputFinal);
} catch (Exception e) {
e.printStackTrace();
}
My JSONArray contacts 119797 characters in 205 and after iteration for appending in StringBuffer, I have to decrypt it with library that takes string for decryption. But StringBuffer is not having complete data of 119797 characters.
And Exception is because string is not complete, I am enclosing files on link below for reference and also using cross platform CryptLib uses AES 256 for encryption easily find on Github
3 Files With Original and Logged text
Dont use StringBuffer , instead use StringBuilder ..here's the detailed Explaination
http://stackoverflow.com/questions/11908665/max-size-for-string-buffer
Hope this helps. :)
EDIT
this is the code that i used to read whole string ...
public void parseLongString(String sourceFile, String path) {
String sourceString = "";
try {
BufferedReader br = new BufferedReader(new FileReader(sourceFile));
// use this for getting Keys Listing as Input
StringBuilder sb = new StringBuilder();
String line = br.readLine();
while (line != null) {
sb.append(line);
line = br.readLine();
}
br.close();
sourceString = sb.toString();
sourceString = sourceString.toUpperCase();
System.out.println(sourceString.length());
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
File file = new File(path);
FileWriter fileWriter = null;
BufferedWriter bufferFileWriter = null;
try {
fileWriter = new FileWriter(file, true);
bufferFileWriter = new BufferedWriter(fileWriter);
} catch (IOException e1) {
System.out.println(" IOException");
e1.printStackTrace();
}
try {
fileWriter.append(sourceString);
bufferFileWriter.close();
fileWriter.close();
} catch (IOException e) {
System.out.println("IOException");
e.printStackTrace();
}
}
and this is outPut file where i am just converting it to uppercase .
https://www.dropbox.com/s/yecq0wfeao672hu/RealTextCypher%20copy_replaced.txt?dl=0
hope this helps!
EDIT 2
If u are still looking for something ..you can also try STRINGWRITER
syntax would be
StringWriter writer = new StringWriter();
try {
IOUtils.copy(request.getInputStream(), writer, "UTF-8");
} catch (IOException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
String theString = writer.toString();
I have a android application, where i extract data from the multiple urls and save then as arraylist of string. It works fine, but for fetching data from 13 urls, it takes close to 15-20 sec. Where as fetching the data from same set of urls take 3-4 sec in same app built using phonegap. Here is the code below.
#Override
protected String doInBackground(String... params) {
client = new DefaultHttpClient();
for(int i=0;i<url.size();i++)
{
get = new HttpGet(url.get(i));
try {
response = client.execute(get);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
entity = response.getEntity();
InputStream is = null;
try {
is = entity.getContent();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
BufferedReader reader = new BufferedReader(
new InputStreamReader(is));
StringBuffer buffer = new StringBuffer();
String line = null;
do {
try {
line = reader.readLine();
} catch (IOException e) {
e.printStackTrace();
}
buffer.append(line);
} while (line != null);
String str = buffer.toString();
param.add(str);
}
return null;
}
Could anyone please suggest how i can speed this execution and reduce the extraction time.
You could try starting a separate thread for each iteration from the for loop.
Smth like this :
for(int i = 0; i < url.size(); i++){
//start thread that gets data from url and adds it to the list
}
I want to read in the data from a csv-file and store it into a database. This is how I saved the csv-file (this works without errors - just to show where and how the file is stored which I plan to read with CSVreader):
synchronized public void readFromUrl(String url, String outputFile, Context context) throws FileNotFoundException {
URL downloadLink = null;
try {
downloadLink = new URL(url);
} catch (MalformedURLException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
BufferedReader in = null;
try {
in = new BufferedReader(
new InputStreamReader(downloadLink.openStream(), "UTF8"));
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
FileOutputStream fstream = context.openFileOutput(outputFile,Context.MODE_PRIVATE);
Writer out = new OutputStreamWriter(fstream);
Log.d(TAG, "BufferedReader "+in);
String inputLine = null;
try {
while ((inputLine = in.readLine()) != null){
out.write(inputLine+"\n");
//logger.debug("DOWNLOADED: "+inputLine);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
fstream.close();
out.close();
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
My code so far for reading the csv file:
public void readInCSVFile(String filename, Context context) throws IOException {
IDbHelper dbHelper = new DbHelper(); ;
CSVReader products = null;
products = new CSVReader(new InputStreamReader(context.getAssets().open(filename)));
I get a NoClassDefFoundError exception.
I have the opencsv.jar in the Referenced libraries of my android project.
Thanks in advance for your help.
Is your project in the Eclipse IDE? If yes, then have a look whether the lib (opencsv.jar) is set in the "project properties->Java Build Path->Libraries" and that it is checked in the tab: "Order and Export" too. Under "Order and Export" move the lib to the top of the list.
Then clean and rebuild.
PS: If this does not help, then please provide the complete stacktrace of the error.
I just wanna create a text file into phone memory and have to read its content to display.Now i created a text file.But its not present in the path data/data/package-name/file name.txt & it didn't display the content on emulator.
My code is..
public class PhonememAct extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView tv=(TextView)findViewById(R.id.tv);
FileOutputStream fos = null;
try {
fos = openFileOutput("Test.txt", Context.MODE_PRIVATE);
} catch (FileNotFoundException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
try {
fos.write("Hai..".getBytes());
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
FileInputStream fis = null;
try {
fis = openFileInput("Test.txt");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int c;
try {
while((c=fis.read())!=-1)
{
tv.setText(c);
setContentView(tv);
//k += (char)c;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Thanks in adv.
You don't need to use input/output streams if you are simply trying to write/read text.
Use FileWriter to write text to a file and BufferedReader to read text from a file - it's much simpler. This works perfectly...
try {
File myDir = new File(getFilesDir().getAbsolutePath());
String s = "";
FileWriter fw = new FileWriter(myDir + "/Test.txt");
fw.write("Hello World");
fw.close();
BufferedReader br = new BufferedReader(new FileReader(myDir + "/Test.txt"));
s = br.readLine();
// Set TextView text here using tv.setText(s);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//Find the directory for the SD Card using the API
//*Don't* hardcode "/sdcard"
File sdcard = Environment.getExternalStorageDirectory();
//Get the text file
File file = new File(sdcard,"file.txt");
//Read text from file
StringBuilder text = new StringBuilder();
try {
BufferedReader br = new BufferedReader(new FileReader(file));
String line;
while ((line = br.readLine()) != null) {
text.append(line);
text.append('\n');
}
}
catch (IOException e) {
//You'll need to add proper error handling here
}
//Find the view by its id
TextView tv = (TextView)findViewById(R.id.text_view);
//Set the text
tv.setText(text);
//To read file from internal phone memory
//get your application context:
Context context = getApplicationContext();
filePath = context.getFilesDir().getAbsolutePath();
File file = new File(filePath, fileName);
StringBuilder text = new StringBuilder();
try {
BufferedReader br = new BufferedReader(new FileReader(file));
while ((line = br.readLine()) != null) {
text.append(line);
text.append('\n');
}
}
catch (IOException e) {
}
return text.toString(); //the output text from file.
This may not be an answer to your question.
I think, you need to use the try-catch correctly.
Imagine openFileInput() call fails, and next you are calling fos.write() and fos.close() on a null object.
Same thing is seen later in fis.read() and fis.close().
You need to include openFileInput(), fos.write() and fos.close() in one single try-catch block. Similar change is required for 'fis' as well.
Try this first!
You could try it with a stream.
public static void persistAll(Context ctx, List<myObject> myObjects) {
// save data to file
FileOutputStream out = null;
try {
out = ctx.openFileOutput("file.obj",
Context.MODE_PRIVATE);
ObjectOutputStream objOut = new ObjectOutputStream(out);
objOut.writeObject(myObjects);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
It is working fine for me like this. Saving as text shouldn't be that different, but I don't have a Java IDE to test here at work.
Hope this helps!