I have a text file which contains the "Captured Network Packets' Headers" as hexadecimal values like this...
FC-C8-97-62-88-5F-74-DE-2B-C8-C7-E5-08-00-45-00-00-28-4E-C4-40-00-80-06-BD-65-C0-A8-01-03-AD-C2-7F-38-C9-96-01-BB-F8-01-7F-5F-B6-8A-15-22-50-10-40-42-72-8C-00-00.
I need to convert them to decimal values... I did little as here..
InputStream input = new FileInputStream("data.txt");
OutputStream output = new FileOutputStream ("converteddata.txt");
int data = input.read();
while (data != -1)
{
char ch = (char) data;
output.write(ch);
data=input.read();
}
input.close();
output.close();
Now, my problem is... how to get each hexadecimal string which would have '2' characters..? (such as "AD" or 5F etc. in order to convert them in to decimal values).
I know that C++ has a function "fgetc()" No..? I need similar solution. Anybody can suggest a good way..? (Sorry, I'm a beginner for Java but know c++ much better)
Thanks in advance.
Try Long.parseLong("<hex string>", 16); to convert a hexadecimal string to a long value.
Try this:
String strHex = "FC-C8-97-62-88-5F-74-DE-2B-C8-C7-E5-08-00-45-00-00-28-4E-C4-40-00-80-06-BD-65-C0-A8-01-03-AD-C2-7F-38-C9-96-01-BB-F8-01-7F-5F-B6-8A-15-22-50-10-40-42-72-8C-00-00";
String[] hexParts = strHex.split("-");
for (String myStr : hexParts) {
// System.out.println(toHex(myStr));
System.out.println(toDecimal(myStr));
}
// getting For Decimal values from Hex string
public int toDecimal(String str){
return Integer.parseInt(str.trim(), 16 );
}
// getting For Hex values
public String toHex(String arg) {
return String.format("%x", new BigInteger(1, arg.getBytes(/*YOUR_CHARSET?*/)));
}
Here is a sample code. Please optimize for real time uses.
public static void main(String[] args) throws IOException {
OutputStream output = new FileOutputStream ("converteddata.txt");
BufferedReader br = new BufferedReader(new FileReader(new File("data.txt")));
String r = null;
while((r=br.readLine())!=null) {
String [] str = r.split("-");
for (String string : str) {
Long l = Long.parseLong(string.trim(), 16);
output.write(String.valueOf(l).getBytes());
output.write("\n".getBytes());
}
}
br.close();
output.close();
}
Related
I can see emojis if I enter unicode directly and convert it to String with a method like:
int intUnicode = 0x1F601;
public String getEmojiByUnicode(int unicode) {
return new String(Character.toChars(unicode));
}
But I just can't wrap my head around how to convert when the unicode value is a String like:
String strUnicode = "0xf601";
How to covert it to an Integer like I did it directly. When I try to use Integer.parseInt(strUnicode) compiler throws an error every time.
InputStream is = assetManager.open("emoji_unicode.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
if (is != null){
try {
while ((data = reader.readLine()) != null){
sbuffer.append(data + "\n");
String j = sbuffer.toString().trim();
int k = Integer.parseInt(j,16);
String l = getEmojiByUnicode(k);
emoArray.add(l);
}
btn.setText(emoArray.get(5));
is.close();
}catch (IOException e){
e.printStackTrace();
}
}
It's not very hard, I know I'm very close but still it won't get to me. Any help would be very appreciated.
Regard
You're attempting to parse a hex string (unicode "encodings" are hexadecimal numbers), and Integer.parseInt() has some odd limits for doing so. Take a look at this answer:
Parsing a Hexadecimal String to an Integer throws a NumberFormatException?
I'm trying to figure out a way to print out specific Strings from a .txt file.
Here is my method:
public static void writeBirdtype() {
In innSkjerm = new In(); // Reading from terminal
In fil = new In("fugler.txt"); // Reading from file
System.out.println("Write out all the observations of a birdtype: ");
String ord = innSkjerm.readLine();
System.out.println("All the observations you asked for:");
while (fil.hasNext()) {
String linje = fil.inWord();
System.out.println(linje);
} // end of while-statement
} // end of writeBirdType() method
The problem is this code prints out all the Strings from a .txt file, which is not what i'm trying to accomplish. Can anyone see what I am missing here? Thank you.
This is an example of how to read something (string in this case) from a file
private String readFileAsString(String filePath) throws IOException {
StringBuffer fileData = new StringBuffer();
BufferedReader reader = new BufferedReader(
new FileReader(filePath));
char[] buf = new char[1024];
int numRead=0;
while((numRead=reader.read(buf)) != -1){
String readData = String.valueOf(buf, 0, numRead);
fileData.append(readData);
}
reader.close();
return fileData.toString();
}
//rest implementation
edit: this solution will be better for you as it will be easier to understand
You can modify it in a way to read whatever you want. This should do you for now.
I'm trying to convert my StringReader back to a regular String, as shown:
String string = reader.toString();
But when I try to read this string out, like this:
System.out.println("string: "+string);
All I get is a pointer value, like this:
java.io.StringReader#2c552c55
Am I doing something wrong in reading the string back?
import org.apache.commons.io.IOUtils;
String string = IOUtils.toString(reader);
The StringReader's toString method does not return the StringReader internal buffers.
You'll need to read from the StringReader to get this.
I recommend using the overload of read which accepts a character array. Bulk reads are faster than single character reads.
ie.
//use string builder to avoid unnecessary string creation.
StringBuilder builder = new StringBuilder();
int charsRead = -1;
char[] chars = new char[100];
do{
charsRead = reader.read(chars,0,chars.length);
//if we have valid chars, append them to end of string.
if(charsRead>0)
builder.append(chars,0,charsRead);
}while(charsRead>0);
String stringReadFromReader = builder.toString();
System.out.println("String read = "+stringReadFromReader);
If you prefer not to use external libraries:
Scanner scanner = new Scanner(reader).useDelimiter("\\A");
String str = scanner.hasNext() ? scanner.next() : "";
The reason for the hasNext() check is that next() explodes with a NoSuchElementException if the reader wraps a blank (zero-length) string.
Or using CharStreams from Googles Guava library:
CharStreams.toString(stringReader);
reader.toString(); will give you the results of calling the generic toString() method from Object class.
You can use the read() method:
int i;
do {
i = reader.read();
char c = (char) i;
// do whatever you want with the char here...
} while (i != -1);
Calling toString() method will give the object of StringReader class. If yo want it's content then you need to call the read method on StringReader like this:
public class StringReaderExample {
public static void main(String[] args) {
String s = "Hello World";
// create a new StringReader
StringReader sr = new StringReader(s);
try {
// read the first five chars
for (int i = 0; i < 5; i++) {
char c = (char) sr.read();
System.out.print("" + c);
}
// close the stream
sr.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
For tutorials you can use this link.
Another native (Java 8+) solution could be to pass the StringReader object to a BufferedReader and stream trough the lines:
try (BufferedReader br = new BufferedReader(stringReader)) {
br.lines().forEach(System.out::println);
}
You're printing out the toString() of the actual StringReader object, NOT the contents of the String that the StringReader is reading.
You need to use the read() and/or the read(char[] cbuf, int off, int len) methods to read the actual chars in the String.
If you use the method toString() in a StringReader object you will print the memory position of the object. You have yo use one of this method:
read()
Reads a single character.
read(char[] cbuf, int off, int len)
Reads characters into a portion of an array.
Here an example:
String s = "Hello World";
// create a new StringReader
StringReader sr = new StringReader(s);
try {
// read the first five chars
for (int i = 0; i < s.length(); i++) {
char c = (char) sr.read();
System.out.print("" + c);
}
// close the stream
sr.close();
} catch (IOException ex) {
ex.printStackTrace();
}
As per https://www.tutorialspoint.com/java/io/stringwriter_tostring.htm
StringReader sr = new StringReader("hello");
StringWriter sw = new StringWriter();
sr.transferTo(sw);
System.out.println(sw.toString());
Given the following code:
String tmp = new String("\\u0068\\u0065\\u006c\\u006c\\u006f\\u000a");
String result = convertToEffectiveString(tmp); // result contain now "hello\n"
Does the JDK already provide some classes for doing this ?
Is there a libray that does this ? (preferably under maven)
I have tried with ByteArrayOutputStream with no success.
This works, but only with ASCII. If you use unicode characters outside of the ASCCI range, then you will have problems (as each character is being stuffed into a byte, instead of a full word that is allowed by UTF-8). You can do the typecast below because you know that the UTF-8 will not overflow one byte if you guaranteed that the input is basically ASCII (as you mention in your comments).
package sample;
import java.io.UnsupportedEncodingException;
public class UnicodeSample {
public static final int HEXADECIMAL = 16;
public static void main(String[] args) {
try {
String str = "\\u0068\\u0065\\u006c\\u006c\\u006f\\u000a";
String arr[] = str.replaceAll("\\\\u"," ").trim().split(" ");
byte[] utf8 = new byte[arr.length];
int index=0;
for (String ch : arr) {
utf8[index++] = (byte)Integer.parseInt(ch,HEXADECIMAL);
}
String newStr = new String(utf8, "UTF-8");
System.out.println(newStr);
}
catch (UnsupportedEncodingException e) {
// handle the UTF-8 conversion exception
}
}
}
Here is another solution that fixes the issue of only working with ASCII characters. This will work with any unicode characters in the UTF-8 range instead of ASCII only in the first 8-bits of the range. Thanks to deceze for the questions. You made me think more about the problem and solution.
package sample;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
public class UnicodeSample {
public static final int HEXADECIMAL = 16;
public static void main(String[] args) {
try {
String str = "\\u0068\\u0065\\u006c\\u006c\\u006f\\u000a\\u3fff\\uf34c";
ArrayList<Byte> arrList = new ArrayList<Byte>();
String codes[] = str.replaceAll("\\\\u"," ").trim().split(" ");
for (String c : codes) {
int code = Integer.parseInt(c,HEXADECIMAL);
byte[] bytes = intToByteArray(code);
for (byte b : bytes) {
if (b != 0) arrList.add(b);
}
}
byte[] utf8 = new byte[arrList.size()];
for (int i=0; i<arrList.size(); i++) utf8[i] = arrList.get(i);
str = new String(utf8, "UTF-8");
System.out.println(str);
}
catch (UnsupportedEncodingException e) {
// handle the exception when
}
}
// Takes a 4 byte integer and and extracts each byte
public static final byte[] intToByteArray(int value) {
return new byte[] {
(byte) (value >>> 24),
(byte) (value >>> 16),
(byte) (value >>> 8),
(byte) (value)
};
}
}
Firstly, are you just trying to parse a string literal, or is tmp going to be some user-entered data?
If this is going to be a string literal (i.e. hard-coded string), it can be encoded using Unicode escapes. In your case, this just means using single backslashes instead of double backslashes:
String result = "\u0068\u0065\u006c\u006c\u006f\u000a";
If, however, you need to use Java's string parsing rules to parse user input, a good starting point might be Apache Commons Lang's StringEscapeUtils.unescapeJava() method.
I'm sure there must be a better way, but using just the JDK:
public static String handleEscapes(final String s)
{
final java.util.Properties props = new java.util.Properties();
props.setProperty("foo", s);
final java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
try
{
props.store(baos, null);
final String tmp = baos.toString().replace("\\\\", "\\");
props.load(new java.io.StringReader(tmp));
}
catch(final java.io.IOException ioe) // shouldn't happen
{ throw new RuntimeException(ioe); }
return props.getProperty("foo");
}
uses java.util.Properties.load(java.io.Reader) to process the backslash-escapes (after first using java.util.Properties.store(java.io.OutputStream, java.lang.String) to backslash-escape anything that would cause problems in a properties-file, and then using replace("\\\\", "\\") to reverse the backslash-escaping of the original backslashes).
(Disclaimer: even though I tested all the cases I could think of, there are still probably some that I didn't think of.)
I have read a file into a String. The file contains various names, one name per line. Now the problem is that I want those names in a String array.
For that I have written the following code:
String [] names = fileString.split("\n"); // fileString is the string representation of the file
But I am not getting the desired results and the array obtained after splitting the string is of length 1. It means that the "fileString" doesn't have "\n" character but the file has this "\n" character.
So How to get around this problem?
What about using Apache Commons (Commons IO and Commons Lang)?
String[] lines = StringUtils.split(FileUtils.readFileToString(new File("...")), '\n');
The problem is not with how you're splitting the string; that bit is correct.
You have to review how you are reading the file to the string. You need something like this:
private String readFileAsString(String filePath) throws IOException {
StringBuffer fileData = new StringBuffer();
BufferedReader reader = new BufferedReader(
new FileReader(filePath));
char[] buf = new char[1024];
int numRead=0;
while((numRead=reader.read(buf)) != -1){
String readData = String.valueOf(buf, 0, numRead);
fileData.append(readData);
}
reader.close();
return fileData.toString();
}
Particularly i love this one using the java.nio.file package also described here.
You can optionally include the Charset as a second argument in the String constructor.
String content = new String(Files.readAllBytes(Paths.get("/path/to/file")));
Cool huhhh!
As suggested by Garrett Rowe and Stan James you can use java.util.Scanner:
try (Scanner s = new Scanner(file).useDelimiter("\\Z")) {
String contents = s.next();
}
or
try (Scanner s = new Scanner(file).useDelimiter("\\n")) {
while(s.hasNext()) {
String line = s.next();
}
}
This code does not have external dependencies.
WARNING: you should specify the charset encoding as the second parameter of the Scanner's constructor. In this example I am using the platform's default, but this is most certainly wrong.
Here is an example of how to use java.util.Scanner with correct resource and error handling:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
import java.util.Iterator;
class TestScanner {
public static void main(String[] args)
throws FileNotFoundException {
File file = new File(args[0]);
System.out.println(getFileContents(file));
processFileLines(file, new LineProcessor() {
#Override
public void process(int lineNumber, String lineContents) {
System.out.println(lineNumber + ": " + lineContents);
}
});
}
static String getFileContents(File file)
throws FileNotFoundException {
try (Scanner s = new Scanner(file).useDelimiter("\\Z")) {
return s.next();
}
}
static void processFileLines(File file, LineProcessor lineProcessor)
throws FileNotFoundException {
try (Scanner s = new Scanner(file).useDelimiter("\\n")) {
for (int lineNumber = 1; s.hasNext(); ++lineNumber) {
lineProcessor.process(lineNumber, s.next());
}
}
}
static interface LineProcessor {
void process(int lineNumber, String lineContents);
}
}
You could read your file into a List instead of a String and then convert to an array:
//Setup a BufferedReader here
List<String> list = new ArrayList<String>();
String line = reader.readLine();
while (line != null) {
list.add(line);
line = reader.readLine();
}
String[] arr = list.toArray(new String[0]);
There is no built-in method in Java which can read an entire file. So you have the following options:
Use a non-standard library method, such as Apache Commons, see the code example in romaintaz's answer.
Loop around some read method (e.g. FileInputStream.read, which reads bytes, or FileReader.read, which reads chars; both read to a preallocated array). Both classes use system calls, so you'll have to speed them up with bufering (BufferedInputStream or BufferedReader) if you are reading just a small amount of data (say, less than 4096 bytes) at a time.
Loop around BufferedReader.readLine. There has a fundamental problem that it discards the information whether there was a '\n' at the end of the file -- so e.g. it is unable to distinguish an empty file from a file containing just a newline.
I'd use this code:
// charsetName can be null to use the default charset.
public static String readFileAsString(String fileName, String charsetName)
throws java.io.IOException {
java.io.InputStream is = new java.io.FileInputStream(fileName);
try {
final int bufsize = 4096;
int available = is.available();
byte[] data = new byte[available < bufsize ? bufsize : available];
int used = 0;
while (true) {
if (data.length - used < bufsize) {
byte[] newData = new byte[data.length << 1];
System.arraycopy(data, 0, newData, 0, used);
data = newData;
}
int got = is.read(data, used, data.length - used);
if (got <= 0) break;
used += got;
}
return charsetName != null ? new String(data, 0, used, charsetName)
: new String(data, 0, used);
} finally {
is.close();
}
}
The code above has the following advantages:
It's correct: it reads the whole file, not discarding any byte.
It lets you specify the character set (encoding) the file uses.
It's fast (no matter how many newlines the file contains).
It doesn't waste memory (no matter how many newlines the file contains).
FileReader fr=new FileReader(filename);
BufferedReader br=new BufferedReader(fr);
String strline;
String arr[]=new String[10];//10 is the no. of strings
while((strline=br.readLine())!=null)
{
arr[i++]=strline;
}
The simplest solution for reading a text file line by line and putting the results into an array of strings without using third party libraries would be this:
ArrayList<String> names = new ArrayList<String>();
Scanner scanner = new Scanner(new File("names.txt"));
while(scanner.hasNextLine()) {
names.add(scanner.nextLine());
}
scanner.close();
String[] namesArr = (String[]) names.toArray();
I always use this way:
String content = "";
String line;
BufferedReader reader = new BufferedReader(new FileReader(...));
while ((line = reader.readLine()) != null)
{
content += "\n" + line;
}
// Cut of the first newline;
content = content.substring(1);
// Close the reader
reader.close();
You can also use java.nio.file.Files to read an entire file into a String List then you can convert it to an array etc. Assuming a String variable named filePath, the following 2 lines will do that:
List<String> strList = Files.readAllLines(Paths.get(filePath), Charset.defaultCharset());
String[] strarray = strList.toArray(new String[0]);
A simpler (without loops), but less correct way, is to read everything to a byte array:
FileInputStream is = new FileInputStream(file);
byte[] b = new byte[(int) file.length()];
is.read(b, 0, (int) file.length());
String contents = new String(b);
Also note that this has serious performance issues.
If you have only InputStream, you can use InputStreamReader.
SmbFileInputStream in = new SmbFileInputStream("smb://host/dir/file.ext");
InputStreamReader r=new InputStreamReader(in);
char buf[] = new char[5000];
int count=r.read(buf);
String s=String.valueOf(buf, 0, count);
You can add cycle and StringBuffer if needed.
You can try Cactoos:
import org.cactoos.io.TextOf;
import java.io.File;
new TextOf(new File("a.txt")).asString().split("\n")
Fixed Version of #Anoyz's answer:
import java.io.FileInputStream;
import java.io.File;
public class App {
public static void main(String[] args) throws Exception {
File f = new File("file.txt");
long fileSize = f.length();
String file = "test.txt";
FileInputStream is = new FileInputStream("file.txt");
byte[] b = new byte[(int) f.length()];
is.read(b, 0, (int) f.length());
String contents = new String(b);
}
}