I'm reading a response from an HttpURLConnection object to a String like so:
HttpURLConnection conn = ...;
BufferedReader rd = new BufferedReader(new InputStreamReader(
conn.getInputStream());
StringBuilder sb = ...;
String line = "";
while ((line = rd.readLine()) != null) {
sb.append(line);
}
String asString = sb.toString();
If I want to read instead to a byte array first, then convert that byte array to a String, what's the right way to do it?
InputStream is = conn.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream(16384);
byte[] buf = new byte[512];
while (true) {
int len = in.read(buf);
if (len == -1) {
break;
}
baos.write(buf, 0, len);
}
byte[] out = baos.toByteArray();
// as a string:
String asString = new String(out);
but I'm not specifying the character in either case - are the two String outputs at the end of the examples equivalent?
Thanks
Related
I'm doing a ZipInputStream request on a UTF-8 encoded zip file.
I get the data through OK, but special German characters are coming out wrong.
Using this page ( http://kellykjones.tripod.com/webtools/ascii_utf8_table.html ) I can see that my code is printing out the two individual chars from the UTF8 encoding column.
i.e. ä is UTF 0xC3,0xA4, and I am getting ä printed out (which are the 0xC3 and 0xA4 chars). Does anyone have any tips?
private InputStream downloadCsv(final String countryCode) {
final String url = baseUrl + countryCode.toUpperCase() + ".zip";
final String fileName = countryCode.toUpperCase() + ".txt";
BufferedInputStream in = null;
ZipInputStream zIn = null;
try {
in = new BufferedInputStream(new URL(url).openStream());
zIn = new ZipInputStream(in, Charset.forName("UTF-8"));
ZipEntry zipEntry;
while ((zipEntry = zIn.getNextEntry()) != null) {
if (zipEntry.getName().equals(fileName)) {
StringBuilder sb = new StringBuilder();
int c;
while((c = zIn.read()) != -1) {
sb.append((char)c);
System.out.println((char)c + " : " + c);
}
return new ByteArrayInputStream(sb.toString().getBytes());
}
}
...
more code
...
For the record, I fixed this using #saka1029s advice, using an InputStreamReader, and would mark it as the accepted answer if I could!
I can't promise my code is the cleanest, but it works now:
BufferedInputStream in = null;
ZipInputStream zIn = null;
InputStreamReader zInReader = null;
try {
in = new BufferedInputStream(new URL(url).openStream());
zIn = new ZipInputStream(in);
ZipEntry zipEntry;
while ((zipEntry = zIn.getNextEntry()) != null) {
if (zipEntry.getName().equals(fileName)) {
StringBuilder sb = new StringBuilder();
zInReader = new InputStreamReader(zIn);
int c;
while((c = zInReader.read()) != -1) {
sb.append((char)c);
}
return new ByteArrayInputStream(sb.toString().getBytes());
}
}
I'm sending 2 String values into an OutputStream from the Client.java as follows :
outputStream.write(username.getText().getBytes());
outputStream.write(password.getText().getBytes());
In the Server.java, i'm trying to get each value separated, when i read the inputStream :
inputStream = s.getInputStream();
byte[]username = new byte[20];
inputStream.read(username);
String user = new String(username);
System.out.println("username = "+user);
i get logically : usernamepassword as the console output.
what i want to do is :
String usr = new String(user);
String pass = new String(password);
Is there a better way to do it than adding some delimiter in the outputStream String ?
You need to delimit the two string values so the reader knows where one string ends and the next string begins. What that delimiter actually consists of is up to you to decide based on your particular needs.
You could write out a string's byte length using a fixed-width integer before then writing out the actual bytes. The reader can then read the length first before then reading the specified number of bytes that follow:
DataOutputStream dos = new DataOutputStream(outputStream);
byte[] bytes;
int len;
bytes = username.getText().getBytes(StandardCharsets.UTF_8);
len = bytes.length;
dos.writeInt(len);
dos.write(bytes, 0, len);
bytes = password.getText().getBytes(StandardCharsets.UTF_8);
len = bytes.length;
dos.writeInt(len);
dos.write(bytes, 0, len);
inputStream = s.getInputStream();
DataInputStream dis = new DataInputStream(inputStream);
byte[] bytes;
int len;
len = dis.readInt();
bytes = new byte[len];
dis.readFully(bytes);
String username = new String(bytes, StandardCharsets.UTF_8);
len = dis.readInt();
bytes = new byte[len];
dis.readFully(bytes);
String password = new String(bytes, StandardCharsets.UTF_8);
Alternatively, DataOutputStream and DataInputStream can write/read String values directly, handling the above logic internally for you (using a short instead of an int for the length value):
DataOutputStream dos = new DataOutputStream(outputStream);
dos.writeUTF(username.getText());
dos.writeUTF(password.getText());
inputStream = s.getInputStream();
DataInputStream dis = new DataInputStream(inputStream);
String username = dis.readUTF();
String password = dis.readUTF();
you could write out a unique character sequence that will never appear in the string values themselves, such as a line break or control character (even a null terminator). The reader can then read bytes until it encounters that sequence:
OutputStreamWriter writer = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8);
String s;
s = username.getText();
writer.write(s, 0, s.length());
writer.write(10);
s = password.getText();
writer.write(s, 0, s.length());
writer.write(10);
inputStream = s.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
String username = reader.readLine();
String password = reader.readLine();
Alternatively:
OutputStreamWriter writer = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8);
String s;
s = username.getText();
writer.write(s, 0, s.length());
writer.write(0);
s = password.getText();
writer.write(s, 0, s.length());
writer.write(0);
inputStream = s.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
StringBuilder sb = new StringBuilder();
int ch;
do
{
ch = reader.read();
if (ch <= 0) break;
sb.append((char)ch);
}
while (true);
String username = sb.toString();
sb.setLength(0);
do
{
ch = reader.read();
if (ch <= 0) break;
sb.append((char)ch);
}
while (true);
String password = sb.toString();
I would go for DataOutputStream for writing and the DataInputStream for reading. With those, you can write an integer value before each String to know the length of the text, something like this:
DataOutputStream dos = new DataOutputStream(outputStream);
dos.writeInt(username.getText().length());
dos.write(username.getText().getBytes());
dos.writeInt(password.getText().length());
dos.write(password.getText().getBytes());
And then, on the server side:
DataInputStream dis = new DataInputStream(inputStream);
int length = 0; // will be used to store the length of each text
length = bytesRead = dis.readInt(); // Read the length of the first text
byte[] usernameBuffer = new byte[length];
dis.read(usernameBuffer);
String username = new String(usernameBuffer);
// Now reading the other text
length = dis.readInt(); // Read the length of the second text
byte[] passwordBuffer = new byte[length];
dis.read(passwordBuffer);
String password = new String(passwordBuffer);
I am compressing a string in PHP 5.4.4-14+deb7u7 using
$cdat = gzcompress($dat, 9);
http://php.net/manual/en/function.gzcompress.php
Then in android/java I want to decompress it, from here:
Android: decompress string that was compressed with PHP gzcompress()
I am using:
public static String unzipString(String zippedText) {
String unzipped = null;
try {
byte[] zbytes = zippedText.getBytes("ISO-8859-1");
// Add extra byte to array when Inflater is set to true
byte[] input = new byte[zbytes.length + 1];
System.arraycopy(zbytes, 0, input, 0, zbytes.length);
input[zbytes.length] = 0;
ByteArrayInputStream bin = new ByteArrayInputStream(input);
InflaterInputStream in = new InflaterInputStream(bin);
ByteArrayOutputStream bout = new ByteArrayOutputStream(512);
int b;
while ((b = in.read()) != -1) {
bout.write(b);
}
bout.close();
unzipped = bout.toString();
} catch (IOException e) {
}
return unzipped;
}
But when I tried it, it decompressed into an empty string, when the downloaded compressed string in android was really long.
The downloaded string was like
x�͜{o�8�a`�= �!�����[��K!(6c�E�$��]�)�HF��F\!����ə���L�LNnH]Lj٬T��M���f�'�u#�*_�7'�S^�w��*kڼn�Yޚ�I��e$.1C��~�ݟ��F�A�_Mv_�R͋��ܴ�Z^L���sU?A���?��ZVmֽ6��>�B��C�M�*����^�sٸ�j����������?�"_�j�ܣY�E���h0�g��w[=&�D �oht=>�l�?��Po";`.�e�E�E��[���������sq��0���i]��������zUL�O{П��ժ�k��b�.&7��-d1_��ۣ�狝�y���=F��K!�rC�{�$����c�&9ޣH���n�x�
Does anyone know what the problem is?
Thanks.
public static Pair<String,Integer> GetHTTPResponse(String url, List<NameValuePair> urlparameters) {
String responseVal = null;
int responseCode = 0;
try {
HttpParams httpParameters = new BasicHttpParams();
int timeoutConnection = TIMEOUT_SECONDS * 1000;
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
int timeoutSocket = TIMEOUT_SECONDS * 1000;
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
HttpClient client = new DefaultHttpClient(httpParameters);
HttpPost httppost = new HttpPost(url);
httppost.setEntity(new UrlEncodedFormEntity(urlparameters));
HttpResponse response = client.execute(httppost);
responseCode = response.getStatusLine().getStatusCode();
BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
responseVal = Common.GetStringFromBufferedReader(rd);
Log.d("SERVER", responseVal);
}
catch (Exception e) {
responseCode = 0;
}
if (responseVal != null) {
responseVal = Common.unzipString(responseVal);
}
return new Pair<String, Integer>(responseVal, responseCode);
}
You can't use
BufferedReader rd =
new BufferedReader(new InputStreamReader(
response.getEntity().getContent()));
responseVal = Common.GetStringFromBufferedReader(rd);
As InputStreamReader's Javadoc notes,
An InputStreamReader is a bridge from byte streams to character streams: It reads bytes and decodes them into characters using a specified charset.
Instead, you could use HttpEntity.writeTo(OutputStream) and a ByteArrayOutputStream like
ByteArrayOutputStream baos = new ByteArrayOutputStream();
response.getEntity().writeTo(baos);
byte[] content = baos.toByteArray();
Then you can directly pass the content to your function in that byte[], and never silently swallow an Exception.
public static String unzipString(byte[] zbytes) {
String charsetName = "ISO-8859-1";
String unzipped = null;
try {
// Add extra byte to array when Inflater is set to true
byte[] input = new byte[zbytes.length + 1];
System.arraycopy(zbytes, 0, input, 0, zbytes.length);
input[zbytes.length] = 0;
ByteArrayInputStream bin = new ByteArrayInputStream(input);
InflaterInputStream in = new InflaterInputStream(bin);
ByteArrayOutputStream bout = new ByteArrayOutputStream(512);
int b;
while ((b = in.read()) != -1) {
bout.write(b);
}
bout.close();
unzipped = bout.toString(charsetName);
} catch (IOException e) {
e.printStackTrace();
}
return unzipped;
}
I'm trying to read a website but strangely it returns only part of it. It just ends in the middle of section.
I tried using the setChunkedStreamingMode method but it didn't change anything.
HttpURLConnection connection = ((HttpURLConnection) new URL(url).openConnection());
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setInstanceFollowRedirects(false);
connection.setRequestMethod("POST");
// I write some data...
String content = readInputStream(connection.getInputStream());
ReadInputStream method:
private static String readInputStream(InputStream in) throws IOException {
int len = 0;
byte[] buffer = new byte[10000];
ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
while((len = in.read(buffer)) != -1) {
byteArray.write(buffer,0, len);
}
in.close();
return new String(byteArray.toByteArray());
}
Is there some sort of limit of data?
there is no problem with HttpUrlConnection
try this:
StringBuilder stringBuilder = new StringBuilder();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
stringBuilder.append(line);
}
inputStream.close();
In my java project, I'm passing FileInputStream to a function,
I need to convert (typecast FileInputStream to string),
How to do it.??
public static void checkfor(FileInputStream fis) {
String a=new String;
a=fis //how to do convert fileInputStream into string
print string here
}
You can't directly convert it to string. You should implement something like this
Add this code to your method
//Commented this out because this is not the efficient way to achieve that
//StringBuilder builder = new StringBuilder();
//int ch;
//while((ch = fis.read()) != -1){
// builder.append((char)ch);
//}
//
//System.out.println(builder.toString());
Use Aubin's solution:
public static String getFileContent(
FileInputStream fis,
String encoding ) throws IOException
{
try( BufferedReader br =
new BufferedReader( new InputStreamReader(fis, encoding )))
{
StringBuilder sb = new StringBuilder();
String line;
while(( line = br.readLine()) != null ) {
sb.append( line );
sb.append( '\n' );
}
return sb.toString();
}
}
public static String getFileContent(
FileInputStream fis,
String encoding ) throws IOException
{
try( BufferedReader br =
new BufferedReader( new InputStreamReader(fis, encoding )))
{
StringBuilder sb = new StringBuilder();
String line;
while(( line = br.readLine()) != null ) {
sb.append( line );
sb.append( '\n' );
}
return sb.toString();
}
}
Using Apache commons IOUtils function
import org.apache.commons.io.IOUtils;
InputStream inStream = new FileInputStream("filename.txt");
String body = IOUtils.toString(inStream, StandardCharsets.UTF_8.name());
Don't make the mistake of relying upon or needlessly converting/losing endline characters. Do it character by character. Don't forget to use the proper character encoding to interpres the stream.
public String getFileContent( FileInputStream fis ) {
StringBuilder sb = new StringBuilder();
Reader r = new InputStreamReader(fis, "UTF-8"); //or whatever encoding
int ch = r.read();
while(ch >= 0) {
sb.append(ch);
ch = r.read();
}
return sb.toString();
}
If you want to make this a little more efficient, you can use arrays of characters instead, but to be honest, looping over the characters can be still quite fast.
public String getFileContent( FileInputStream fis ) {
StringBuilder sb = new StringBuilder();
Reader r = new InputStreamReader(fis, "UTF-8"); //or whatever encoding
char[] buf = new char[1024];
int amt = r.read(buf);
while(amt > 0) {
sb.append(buf, 0, amt);
amt = r.read(buf);
}
return sb.toString();
}
From an answer I edited here:
static String convertStreamToString(java.io.InputStream is) {
if (is == null) {
return "";
}
java.util.Scanner s = new java.util.Scanner(is);
s.useDelimiter("\\A");
String streamString = s.hasNext() ? s.next() : "";
s.close();
return streamString;
}
This avoids all errors and works well.
Use following code ---->
try {
FileInputStream fis=new FileInputStream("filename.txt");
int i=0;
while((i = fis.read()) !=-1 ) { // to reach until the laste bytecode -1
System.out.print((char)i); /* For converting each bytecode into character */
}
fis.close();
} catch(Exception ex) {
System.out.println(ex);
}