I need to read a .json file and change a field in runtime.
The problem is when I try to read it:
JSONObject jOb=null;
try {
jOb = new JSONObject(filePath);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(jOb.toString());
try {
jOb.put("responseType", "TESTicles");
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(""+jOb);
I get the following error: "A JSONObject text must begin with '{' at 1 [character 2 line 1]"
I think the problem might be the BOM marker because my file starts with '{'
Here's a sample (the beginning of my json file):
{
"base":{
"sites":{
"local":{
"name":"siteA",
"datasource":{
...
I need to remove the BOM marker in order to read the file but how can I do it without reading the file?
I've read:
This, this and many other stuff about it, but I can't seem to find any solution to my problem. What can I do?
On the assumption that you are using the library defined at json.org, what your code does is treat the file name as a JSON string and try to interpret it as a JSON object.
Reading the docs, you'll need to open the file as an input stream, pass it as a parameter in a JSONTokener constructor which you pass as a parameter to your JSONObject constructor, something like:
InputStream foo = new FileInputStream(filePath);
JSONTokener t = new JSONTokener(foo);
JSONObject obj = new JSONObject(t);
Note: the above not tested or even compiled.
Related
I'm scanning single letters and numbers. All the numbers should be parsed into numbers[]. But it's always catching the exception. For Example: result is "3" but I can't parse it for some reason. I also tried to check if it's actually "3" with an if statement but I also got a false returned. Can someone explain me why it isn't working?
File imageFile = new File("C:\\Users\\Nils\\IdeaProjects\\untitled8\\Images\\Cutted\\"+i+m+".png");
ITesseract instance = new Tesseract(); // JNA Interface Mapping
// ITesseract instance = new Tesseract1(); // JNA Direct Mapping
instance.setDatapath("C:/Users/Nils/Desktop/blum/Tess4J/tessdata"); // path to tessdata directory
try {
String result = instance.doOCR(imageFile);
try {
resultI=Integer.parseInt(result);
numbers[0] = resultI;
}catch (NumberFormatException e){
numbers[0]=0;
}
} catch (TesseractException e) {
System.err.println(e.getMessage());
}
Ok I figured it out.
if(result.length()>1)
result=result.substring(0,1);
Delets everything that caused errors but keeps the number I want to separate.
I'm having a problem in reading the "Email" field from a JSON file, using Java. When I try to read it, it only reads the first one, even if I put more than one, I tried different things but nothing seems to go. Any way to solve it?
Here is the code:
This is the sign in method, where I write every data about the customer on the JSON file
JSONObject customer = new JSONObject();
JSONArray list = new JSONArray();
customer.put("Email", emailCliente.getText());
customer.put("Tipo", "Cliente");
customer.put("Name", nomeCliente.getText());
customer.put("Surname", cognomeCliente.getText());
customer.put("BirthDate", dataNascitaCliente.getText());
customer.put("Address", indirizzoCliente.getText());
customer.put("Phone", telefonoCliente.getText());
customer.put("Password", pswCliente.getText());
list.add(customer);
try {
FileOutputStream file = new FileOutputStream("Db.json", true);
ObjectOutputStream fileWriter = new ObjectOutputStream(file);
fileWriter.writeObject(list);
fileWriter.flush();
fileWriter.close();
}
This is the code for reading from JSON file:
public class Read implements Serializable{
public static void main(String[] args) throws IOException {
try{
FileInputStream reader = new FileInputStream("Db.json");
ObjectInputStream ois = new ObjectInputStream(reader);
Object customer = (Object) ois.readObject();
JSONArray tmp = (JSONArray) (customer);
for(Object obj : tmp) {
JSONObject tmpObj = (JSONObject) obj;
System.out.println(tmpObj.get("Email"));
}
ois.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
} }
You're using the org.json library to create and read JSON data.
Don't. That library is deplorably bad.
I know json.org lists it.
An excellent choice is jackson, or perhaps gson if you want an alternative. As #Raúl Garcia mentioned in a comment, here is a good baeldung tutorial on jackson.
NB: DataInputStream and DataOutputStream are for java's serialization mechanism, which isn't JSON and you don't want those in any case, so, throw out your 'read' code and start from scratch, by following the tutorial. Also, your exception code is problematic; exceptions contain 4 bits of info (type, message, trace, and cause); you're throwing out 3 of the 4 useful bits of info then blindly continuing, which likely produces more clutter in your logs, making it extremely difficult to try to figure out what is going wrong. Stop doing this; just 'throws' such exceptions onwards. If you really, really can't, fix your IDE to generate catch (Foo e) {throw new RuntimeException(e);} as a default catch block. NEVER e.printStackTrace();.
You could read it a single line like so when you use unify-jdocs:
Document d = new JDocument(s); // where s is a JSON string
String s = d.getString("$.Email");
unify-jdocs is a library I have created to work with JSON documents. It provides a whole lot of other features as well. Check it out on https://github.com/americanexpress/unify-jdocs
I am reading datas from a csv file and set all datas into an object.At a particular point i am getting a numberformat exception (only after reading some datas)because some datas are not numbers(That is an error inside file some charecter datas in place of numerical datas,not able to use string concept because of some integration issues with main program).At that point i need to skip that line and need to move to the nextline.Can anyone please help.Any help will be highly appreciable.
reader = new CSVReader(new FileReader(parentPath+File.separator+file),',','"');
while ((nextLine = reader.readNext()) != null &&nextLine.length!=0 ) {
encap.setPrice((nextLine[5]));
String mrp=encap.getPrice().split("[,]")[0];
try {
encap.setProduct_price(Double.parseDouble(mrp));
} catch (NumberFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Note:I need to skip and read next line onwards when ever numberformat exception occurs for a particular line.(value is getting correctly but my program stops whenever a numberformat exception occurs.......
encap is the object of my class....
Expand the scope of your try catch. Brute force, put try just below while and include ALL code in that while block inside that try block.
It looks like your try..catch is already in the right place. Just make a new encap for each record and it should behave as you want:
List<Encap> encaps = new ArrayList<Encap>(); // <- create list of results
reader = new CSVReader(new FileReader(parentPath+File.separator+file),',','"');
while ((nextLine = reader.readNext()) != null &&nextLine.length!=0 ) {
Encap encap = new Encap(); // <- create a new instance for this line
encap.setPrice(nextLine[5]);
String mrp=encap.getPrice().split("[,]")[0];
try {
encap.setProduct_price(Double.parseDouble(mrp));
encaps.add(encap); // <- add this result to the list only if parsed ok
} catch (NumberFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
I wonder if anyone knows why I may be getting a java.io.FileNotFoundException when I'm trying to find a file that I know exists in the directory.
I think the following have something to do with it, please let me know if I'm correct or if there's something else:
I downgraded my JVM from 1.7 to 1.6
The file name contains two question marks, so the file is called filename_?)?.data
While I was using JVM 1.7, the program was able to find the file and open it. However, after downgrading to 1.6, it looks like it can't find this particular file. So I'm thinking maybe JVM 1.6 can't read files w/ question marks in them.
Also, I double/triple checked and the file does exist in the directory my program is looking in (its able to find other files in there as well).
Here's my code below:
public Object readFromFile(String fileName) {
// Check for null
if (fileName == null || fileName.equals("")) return null;
Object obj = null;
ObjectInputStream input = null;
// Open file into (input)
try {
input = new ObjectInputStream(new FileInputStream(fileName + ".data"));
} catch (IOException e) {
e.printStackTrace();
}
// Read content of file into (obj)
try {
obj = input.readObject();
input.close();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return obj;
}
probably you need to encode your filename when it is using special chars
Try this
String fileNameNew= java.net.URLEncoder.encode(fileName);
if (fileNameNew == null || fileNameNew.equals("")) return null;
Object obj = null;
ObjectInputStream input = null;
...
and you might check here: How to determine if a String contains invalid encoded characters
I'm currently building an application where the user will generate data over time and, should he/she has an internet connection, transmit it to the web. However, if he doesn't have web access, I need to store this data in the phone until the user recovers his access, when I'll need to recover this data to be transmitted. However, I'm facing lots of troubles to do this, as per below.
Note: before anything, I'm using a local java-created file because I know no other way to save/restore this data on the device. If you happen to know any other way to store/access this data from within the device please feel free to comment here.
Just for reference,
phantoms is an ArrayList containing objects with the data I need to
store,
Arquivador is the class that I'm using to make my data persistent and to recover it,
Funcionario is the class with the data generated by the program (just a few strings and numbers)
I am able to write a file to the file system through the code below, on my Activity:
try {
arq = new Arquivador();
arq.addFirstObjectInFile(
openFileOutput("dados.jlog", MODE_WORLD_WRITEABLE),
phantoms.get(0));
phantoms.remove(phantoms.get(0));
for (Funcionario func : phantoms) {
arq.addObjectInFile(openFileOutput("dados.jlog", MODE_APPEND),
func);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
}
Here is the code inside Arquivador that adds the data to a file:
public void addObjectInFile(FileOutputStream arquivo,
Object objetoAAdicionar) {
try {
ObjectOutputStream aoos = new ObjectOutputStream(arquivo);
aoos.writeObject(objetoAAdicionar);
aoos.close();
} catch (IOException ioe) {
Log.d(TAG_NAME, "Erro no Appendable OOS.");
}
}
public void addFirstObjectInFile(FileOutputStream arquivo,
Object objetoAAdicionar) {
try {
AppendableObjectOutputStream aoos = new AppendableObjectOutputStream(
arquivo);
aoos.writeObject(objetoAAdicionar);
aoos.close();
} catch (IOException ioe) {
Log.d(TAG_NAME, "Erro no Appendable OOS.");
}
}
You will notice that I'm adding data to persistence in 2 steps, the first Object and the rest of them. This was an idea I saw on this post, here in StackOverflow, to allow appending data to a Java generated file. I have no problem with this code, it works perfectly.
Later on, back on my Activity, the internet connection is detected and I try to recover the file saved on the disk:
phantoms = new ArrayList<Funcionario>();
Object obj = arq.readObjectFromFile(openFileInput("dados.jlog"));
Funcionario func = null;
if (obj instanceof Funcionario) {
func = (Funcionario) obj;
}
while (func != null) {
phantoms.add(func);
arq.removeObjectFromFile(openFileInput("dados.jlog"), func,
getApplicationContext());
func = (Funcionario) arq
.readObjectFromFile(openFileInput("dados.jlog"));
}
The original idea was to read 1 object at a time, then attempt to transmit it and, if successful, erase the object from the file (so it didn't get retransmitted). However, I was having too many error messages with this. Instead, I decided to load all the objects at once, one by one, to see where my problem was more clearly.
Back to the Arquivador class:
public Object readObjectFromFile(FileInputStream arquivo) {
Object retorno = null;
if (arquivo.equals(null)) {
Log.e(TAG_NAME, "FIS is null!");
}
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(arquivo);
retorno = ois.readObject();
} catch (IOException ioex) {
} catch (ClassNotFoundException e) {
} finally {
try {
if (ois != null) ois.close();
} catch (IOException e) {
}
}
return retorno;
}
public void removeObjectFromFile(FileInputStream arqPrincipal,
Object objetoARemover, Context contexto) {
try {
// Construct the new file that will later be renamed to the original
// filename.
ObjectOutputStream oos = new ObjectOutputStream(
contexto.openFileOutput("dados.jlog.temp",
contexto.MODE_APPEND));
ObjectInputStream ois = new ObjectInputStream(arqPrincipal);
Object obj = null;
// Read from the original file and write to the new
// unless content matches data to be removed.
try {
while ((obj = ois.readObject()) != null) {
if (!(objetoARemover.equals(obj))) {
oos.writeObject(obj);
oos.flush();
}
}
} catch (EOFException eof) {
} finally {
oos.close();
ois.close();
// Delete the original file
File aDeletar = contexto.getFileStreamPath("dados.jlog");
File aRenomear = contexto.getFileStreamPath("dados.jlog.tmp");
if (!aDeletar.delete()) {
return;
} else {
// Rename the new file to the filename the original file
// had.
if (!aRenomear.renameTo(aDeletar)) Log.d(TAG_NAME,
"Error renaming file");
else Log.d(TAG_NAME, "Renaming successful");
}
}
} catch (FileNotFoundException ex) {
ex.printStackTrace();
Log.d(TAG_NAME, "Arquivo não encontrado");
} catch (IOException ex) {
ex.printStackTrace();
Log.d(TAG_NAME, "Erro de entrada/saída");
} catch (ClassNotFoundException e) {
Log.d(TAG_NAME, "Classe Não Encontrada.");
}
}
The method readObjectFromFile() seems to work just fine. I can even convert the read Object to Funcionario class and read its data.
My problems appear when I use removeObjectFromFile(). The idea is to create a temporary file to store objects from "dados.jlog" file other than the one that has been already loaded in the main program, then once this temp file is created the file "dados.jlog" should be deleted and the temporary file should be renamed to replace it.
The first thing I found out to be strange here is that the ois.readobject() keeps throwing an EOFException. While this makes sense, the tutorial I read on the internet doesn't mention this error. In fact, their code indicates that when the readObject() method reaches the EOF, it would return a reference to null, but instead this class throws this EOFException. I handled this exception in the code - though I'm not sure if this would be the right way to do it.
Another thing I find strange is the fact that this code fails to recognize the object that it should NOT copy. When I compare the object read from the file to the one received as argument, no matter what I try ( == , equals(), etc) they seem different objects to the compiler. Funcionario class is serializable has a serialversionUID, so the object read from the file should be identical to the one I stored. Worse than this, these 2 Objects being compared are read from the same file. They should be identical, right?
After creating the temporary file, I try to delete the original file and rename the temporary file. Though this seems to be working, once the removeObjectFromFile() ends the first time, the program is unable to read the data from the file "dados.jlog" again. I can't read the remaining data from the file and the program enters on an endless loop - since the 1st object is never removed from the list in the file.
Please enlighten me with this matter.
Personally I'd use an SQLLite database. Store each object in a row in the database. Once you've successfully transmitted you can remove the row from the database.
You can even reuse most of your code that you've already done. The easiest way to get there from where you are is to use a separate file for each object and store only the filename of the object in the database. You can then iterate over the rows in the database. Each time you transmit an object to your server simply delete that row from the database (and remove the file from the filesystem!). No rows in the database means no objects remain to be transmitted.