Unable to convert binary file properly - java

I have to read a file called test.p2b with the following content:
I tried reading it like this:
static void branjeIzDatoteke(String location){
byte[] allBytes = new byte[10000];
try {
InputStream input = new FileInputStream(location);
int byteRead;
int j=0;
while ((byteRead = input.read())!=-1){
allBytes[j] = (byte)input.read();
}
String str = new String(allBytes,"UTF-8");
for (int i=0;i<=str.length()-8;i+=8){
//int charCode = Integer.parseInt(str.substring(i,i+8),2);
//System.out.println((char)charCode);
int drek = (int)str.charAt(i);
System.out.println(Integer.toBinaryString(drek));
}
} catch (IOException ex) {
Logger.getLogger(Slika.class.getName()).log(Level.SEVERE, null, ex);
}
}
I tried just printing out the string (when I created String str = new String(allBytes,"UTF-8");), but all I get is a square at the beginning and then 70+ blank lines with no text.
Then I tried the int charCode = Integer.parseInt(str.substring(i,i+8),2); and printing out each individual character, but then I got a NumberFormatException.
I even tried just converting
Finally I tried the Integer.toBinaryString I have at the end but in this case I get 1s and 0s. That's not what I want, I need to read the actual text but no method seems to work.
I've actually read a binary file before using the method I already tried:
int charCode = Integer.parseInt(str.substring(i,i+8),2);
System.out.println((char)charCode);
but like I said, I get a NumberFormatException.
I don't understand why these methods won't work.

If you want to read all the bytes you can use the java.nio.file.Files utility class:
Path path = Paths.get("test.p2b");
byte[] allBytes = Files.readAllBytes(path);
String str = new String(allBytes, "UTF-8");
System.out.print(str);
You iteration over str content might not work. Certain UTF characters are expressed as surrogate pairs, a code points that can span more than one char (as explained here). Since you are using UTF you should be using String#codePoinst() method to iterate over the code points instead of the characters.

Related

Correctly displaying text from a file in Java

I am currently trying to read multiple files (UTF-8) within a directory and store each element in that text file into an array.
I am able to get the text to print to console however it shows some funny characters I can't seem to rid myself off (See image - what is should look like is displayed on the right).
Currently, I have a method that builds an array with all file names in that directory then using a for loop I send each of these file names to a read method which puts it into a string.
The below method writes these file names to an array.
public static ArrayList<String> readModelFilesInModelDir() {
File folder = new File("Models/");
File[] listOfFiles = folder.listFiles();
String random = "";
assert listOfFiles != null;
ArrayList<String> listOfModelFiles = new ArrayList<>();
for (int i = 0; i < listOfFiles.length; i++) {
if (listOfFiles[i].isFile()) {
//System.out.println("File " + listOfFiles[i].getName());
listOfModelFiles.add(listOfFiles[i].getName());
} else if (listOfFiles[i].isDirectory()) {
System.out.println("Directory " + listOfFiles[i].getName());
}
}
System.out.println(listOfModelFiles);
return listOfModelFiles;
The below for loop then sends these file names to the read method.
ArrayList<String> modelFiles = readModelFilesInModelDir();
for (int i = 0; i < modelFiles.size(); i++) {
String thisString = readModelFileIntoArray(modelFiles.get(i));
System.out.println(thisString);
}
The below method then reads the string into an array, which is outputting what the images show.
public static String readModelFileIntoArray(String modelFilePath) {
StringBuilder fileHasBeenRead = new StringBuilder();
try {
Reader reader = new InputStreamReader(new FileInputStream(("Models/" + modelFilePath)), StandardCharsets.UTF_8);
String s;
BufferedReader bufferedReader = new BufferedReader(reader);
while ((s = bufferedReader.readLine()) != null) {
fileHasBeenRead.append(s + "\n");
}
reader.close();
} catch (Exception e) {
System.out.print(e);
}
return fileHasBeenRead.toString().trim();
}
Finally, how would I fix this output issue as well as store each of these files that have been read into a seperate array that I can use elsewhere? Thanks!
I agree with Johnny Mopp, your file is encoded in UTF-16, not in UTF-8. The two �� at the beginning of your output looks like a byte order mark (BOM). In UTF-16, each character is coded on two bytes. Since your text only contains characters in the ASCII range, it means that each first byte is always 0x00. This is why you're seeing all these ▯: they correspond to the non-printable character 0x00. I would even say that since the two characters following �� are ▯ and a in this order, your file is using big-endian UTF-16.
Instead of UTF-8, use StandardCharsets.UTF_16. It will also take the BOM into account and use the appropriate endianness.
It's much easier (and usually better) to use existing libraries for common stuff. There is FileUtils from apache commons-io, that provides this functionality out of the box, reducing your file reading code to a one liner
String thisString = FileUtils.readFileToString("Models/" + modelFilePath, StandardCharsets.UTF_8);
... or whatever charset your file is using...

How to piece together String using file reader and char array

Wrote a file in another class and now I'm trying to piece together the file into a JLabel, so I need to convert the name in the file into a string. Using FileReader and a char array to separate each character into an array to be put together in the JLabel.
I'm getting this error on NamePieces[x] = (char)nr;:
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 0
at clients.initialize(clients.java:197)
at clients.<init>(clients.java:72)
This is the code that I want to read the file:
try(FileReader nameReader = new FileReader(NamePath)) {
int nr = nameReader.read();
int x = 0;
while(nr != -1) {
namePieces[x] = (char)nr;
nr = nameReader.read();
x++;
}
}
catch (FileNotFoundException e) {}
catch (IOException e1) {}
String name = String.valueOf(namePieces[0]) + namePieces[1];
Doesn't work
Most likely, your problem occurs because namePieces is not initialized. As was already mentioned in the comments, you should not use char[] as a container for your characters (because in real world you won't know the length of the files' contents every time, so you will probably need to resize your container), it is way more better to use StringBuilder, provided by Java standard library. It will protect you from getting out of bounds.
StringBuilder namePieces = new StringBuilder();
File file = new File(filePath);
BufferedReader reader = new BufferedReader(
new InputStreamReader(new FileInputStream(file),
Charset.forName("UTF-8")));
int c;
while((c = reader.read()) != -1) {
namePieces.append((char) c);
}
String nameString = namePieces.toString(); // Use this string as a complete array of needed characters
As you see I changed an approach by using not only StringBuilder, but also BufferedReader. However, for your task you can leave FileReader as it is. Just consider appending characters to builder.
If your file just contains a String there is a straightforward way to read it:
public String readMyFile( String fileName) throws IOException {
Path path = Paths.get(fileName);
return Files.readAllLines(path).get(0);
}

outputstream writer java for integers

I am quite new in java, I need to save xml to csv using java, but problem is I cannot use CSVWriter because in xml there are also UTF8 encoded data.
Therefore I found out it is possible to use outputstreamwriter, which can be encoded in UTF8.
For string everything is ok, but for integer I cannot get correct number.
Sample code:
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.*;
public class UTF8WriterDemo {
public static void main(String[] args) {
Writer out = null;
try {
out = new BufferedWriter(
new OutputStreamWriter(new FileOutputStream("c://java2//file.csv"), "windows-1250"));
//for (int i=0; i<4; i++ ) {
String text = "This tečt will be added to File !!";
int hu = 4;
out.write('\ufeff');
out.write(text+ '\n');
out.write(hu+ '\n');
//}
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
I get picture instead of a number.
I suppose it's because:
An OutputStreamWriter is a bridge from character streams to byte streams: Characters written to it are encoded into bytes using a specified charset. The charset that it uses may be specified by name or may be given explicitly, or the platform's default charset may be accepted.
And that's why it's not displayed correctly.
Therefore I would like to ask, is there any option for integers to be displayed using outputstreamwriter?
Or if not, how can I convert xml data into csv using java for UTF8 encoded characters?
Thank you
Java has a difference between using double quotes and single quotes.
"foo" is a String.
'f' is a char (or Character)
'foo' will throw an Exception, because you can only have 1 character in a char.
'\n' is also 1 character, specifically the newline character. Adding a number and a character will use the number as an ASCII value and use the corresponding character, then combine both characters into a String (or array of characters, ie. char[]).
Using double quotes should fix your issue.
import java.io.*;
public class UTF8WriterDemo {
public static void main(String[] args) {
Writer out = null;
try {
out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("file.csv"), "windows-1250"));
//for (int i = 0; i < 4; i++) {
String text = "This text will be added to File !!";
int hu = 4;
String text2 = new String("" + hu);
out.write('\ufeff');
out.write(text + '\n');
out.write(text2 + '\n');
// }
out.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println("The process is completed.");
}
}
}
actually I need to rewrite this construction:
FileWriter fileWriter = new
FileWriter("C:\\java\\test\\EEexample3.csv");
CSVWriter csvWriter = new CSVWriter(fileWriter);
csvWriter.writeNext(new String[] {
..
..
..
..
}
..code.. code..
String homeCurrencyPriceString = iit.getHomeCurrency().getPrice()!=null?iit.getHomeCurrency().getPrice().toString():"";
String headerDateString = invoiceHeaderType.getDateTax()!=null?invoiceHeaderType.getDateTax().toString():"";
String invoiceTypeString = invoiceHeaderType.getInvoiceType()!=null?invoiceHeaderType.getInvoiceType().value():"";
String headeraccountno= invoiceHeaderType.getAccount().getAccountNo()!=null?invoiceHeaderType.getAccount().getAccountNo().toString():"";
String headertext = invoiceHeaderType.getText()!=null?invoiceHeaderType.getText():"";
String invoiceitemtext= iit.getText()!=null?iit.getText():"";
String headericdph = invoiceHeaderType.getPartnerIdentity().getAddress().getIcDph()!=null?invoiceHeaderType.getPartnerIdentity().getAddress().getIcDph():"";
String symVar = invoiceHeaderType.getSymVar()!=null?invoiceHeaderType.getSymVar():"";
csvWriter.writeNext(new String[] {
invoiceHeaderType.getPartnerIdentity().getAddress().getIco(), headericdph, invoiceHeaderType.getPartnerIdentity().getAddress().getCompany(),symVar, invoiceHeaderType.getId().toString(), iit.getId().toString(), homeCurrencyPriceString, detailcentreString,headercentreString, headerDateString, invoiceTypeString,headeraccountno, headertext,invoiceitemtext
});
where objects are filled by xml
to outputstreamwriter construction.
So first I am trying outputstream as simple code, to be sure it`s working , next when it works, I wanted to rewrite the whole code.
Using CSVwriter everything works smoothly, just now there were added texts encoded in UTF8/windows1250 :( Therefore I need to fix the construction of code.
Even number objects like price are converted using .toString(), so maybe it works without int.
I hope writer of outputstreamwriter is able to do what is necessary.
I am going to try.

Convert string from file to ASCII and binary

Say I open a text file like this:
public static void main(String[] args) throws IOException {
String file_name = "file.txt";
try {
Read file = new ReadFile(file_name);
String[] Lines = file.openFile();
for (int i = 0; i < es.length; i++) {
System.out.println(Lines[i]);
}
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
Now, I want to change the result to binary (for further conversion into AMI coding), and I suppose that firstly I should turn it to ASCII (though I'm also not 100% certain if that's absolutely necessary), but I'm not sure if I should better change it to chars, or perhaps is there an easier way?
Please, mind that I'm just a beginner.
Do you happen to know for sure that the files will be ASCII encoded? Assuming it is, you can just use the getBytes() function of string:
byte[] lineDefault = line.getBytes();
There is a second option for .getBytes() as well if you don't want to use the default encoding. I often am using:
byte[] lineUtf8 = line.getBytes("UTF-8");
which gives byte sequences which are equivalent to ASCII for characters whose hex values are less than 0x80.

Converting a set of characters into a different string array using java

I am trying to read a data from a file. I have following code.
public void ReadFile()
{
File sdcard = android.os.Environment.getExternalStorageDirectory();
File directory = new File(sdcard.getAbsolutePath()+ "/MyDirectory");
File file = new File(directory,"textfile1.txt");
try (FileInputStream fis = new FileInputStream(file)) {
char stringComma = new Character(',');
System.out.println("Total file size to read (in bytes) : "+ fis.available());
int content;
while ((content = fis.read()) != -1) {
// convert to char and display it
Log.d(TAG, "reading a file");
System.out.print((char) content);
}
} catch (IOException e) {
e.printStackTrace();
}
}
I have file format as follows [textfile1.txt]
[12],84359768069 //some numbers
[34],56845745740
[44],36344679992
[99],46378467467
When i am reading this file each character will read at a time. I want to split this and store in different string arrays like
str1 = [12]
str2 = 84359768069
How i can achieve this?
You're currently reading a byte at a time, because you're using InputStream. That's the first thing to fix - you should be using a Reader for text data. The best approach is to wrap your InputStream in an InputStreamReader.
Next, it sounds like you want to read a line at a time rather than just a character at a time. The easiest way of doing that is to use a BufferedReader wrapping an InputStreamReader.
(If you were using Java 7+, all of this could be achieved very nicely using Files.newBufferedReader - you just need to supply the Path and the Charset. Until Android supports that, you'll need to just do the wrapping manually. It's not too painful though.)
One you're reading a line at a time, you then need to split the line by comma - look at using String.split for this. I would then suggest you create a class to store these two separate values. So each line will be transformed into an instance of your class.
Finally, create a List<YourCustomClass> and add to it as you read the file.
That's given an overview of how to achieve each step - hopefully enough detail to enable you to get going, but not spoon-feeding you enough to hamper you actually learning from the experience.
A simple solution would be to parse the readed characters:
public void ReadFile()
{
File sdcard = android.os.Environment.getExternalStorageDirectory();
File directory = new File(sdcard.getAbsolutePath()+ "/MyDirectory");
File file = new File(directory,"textfile1.txt");
try (FileInputStream fis = new FileInputStream(file)) {
char stringComma = new Character(',');
System.out.println("Total file size to read (in bytes) : "+ fis.available());
int content;
String str1="";
String str2 = "";
boolean commaFound=false;
while ((content = fis.read()) != -1) {
// convert to char and display it
Log.d(TAG, "reading a file");
if ((char)content==',')
{
commaFound = true;
}
else if ((char)content=="\n")
{
System.out.printlnt("str1="+str1+"\nstr2="+str2);
commaFound = false;
str1 = "";
str2 = "";
}
else
{
if (commaFound)
{
str2 += (char)content;
}
else
{
str1 += (char)content;
}
}
System.out.print((char) content);
}
} catch (IOException e) {
e.printStackTrace();
}
}

Categories