How to create JSON file from java without duplicating element? - java

I'm trying to make a simple dictionary program based on server-client socket communication. I'm trying to save user word and meaning input as a JSON file (which is dictionary data to search later on) but when I do add query it ends up with having duplicated JSON objects
for example, if I add happy and then weather and hello, the result written in JSON file is
like below
{"hello":"greeting"}{"happy":"joy","hello":"greeting"}
{"happy":"joy","weather":"cold","hello":"greeting"}`
instead of getting
{"hello":"greeting"}{"happy":"joy"}{"weather":"cold"} like I wanted
how can I fix this problem?
my code for that function is
case "add":{
FileWriter dictionaryWriter = new FileWriter("dictionary.json",true);
//split command again into 2 part now using delimiter ","
String break2[] = msgBreak[1].split(",");
String word = break2[0];
String meaning = break2[1];
dictionary.put(word, meaning);
System.out.println("Writing... " + word+":"+meaning);
dictionaryWriter.write(dictionary.toString());
//flush remain byte
dictionaryWriter.flush();
//close writer
dictionaryWriter.close();
break;}
this function is in while(true) loop with other dictionary functions
I tried to remove the appending file part, but when I remove the (,true) part the duplication error stopped but whenever I get a new connection, new dictionary file is created instead of having all data saved.
If anyone can help me solve this problem, I would appreciate it a lot!
Thanks you in advance.

You can try to create a new dictionary every time instead of using the existing one
Map<String, String> dictionary = new HashMap<>();
dictionary.put(word, meaning);
...

Related

easiest way to read a java file - is there a simpler auternative to JSON

I am writing a small java method that needs to read test data from a file on my win10 laptop.
The test data has not been formed yet but it will be text based.
I need to write a method that reads the data and analyses it character by character.
My questions are:
what is the simplest format to create and read the file....I was looking at JSON, something that does not look particularly complex but is it the best for a very simple application?
My second question (and I am a novice). If the file is in a text file on my laptop.....how do I tell my java code where to find it....how do I ask java to navigate the win10 operating system?
You can also map the text file into java objects (It depends on your text file).
For example, we have a text file that contains person name and family line by line like:
Foo,bar
John,doe
So for parse above text file and map it into a java object we can :
1- Create a Person Object
2- Read and parse the file (line by line)
Create Person Class
public class Person {
private String name;
private String family;
//setters and getters
}
Read The File and Parse line by line
public static void main(String[] args) throws IOException {
//Read file
//Parse line by line
//Map into person object
List<Person> personList = Files
.lines(Paths
.get("D:\\Project\\Code\\src\\main\\resources\\person.txt"))
.map(line -> {
//Get lines of test and split by ","
//It split words of the line and push them into an array of string. Like "John,Doe" -> [John,Doe]
List<String> nameAndFamily = Splitter.on(",").trimResults().omitEmptyStrings().splitToList(line);
//Create a new Person and get above words
Person person = new Person();
person.setName(nameAndFamily.get(0));
person.setFamily(nameAndFamily.get(1));
return person;
}
).collect(Collectors.toList());
//Process the person list
personList.forEach(person -> {
//You can whatever you want to the each person
//Print
System.out.println(person.getName());
System.out.println(person.getFamily());
});
}
Regarding your first question, I can't say much, without knowing anything about the data you like to write/read.
For your second question, you would normally do something like this:
String pathToFile = "C:/Users/SomeUser/Documents/testdata.txt";
InputStream in = new FileInputStream(pathToFile);
As your data gains more complexity you should probably think about using a defined format, if that is possible, something like JSON, YAML or similar for example.
Hope this helps a bit. Good luck with your project.
As for the format the text file needs to take, you should elaborate a bit on the kind of data. So I can't say much there.
But to navigate the file system, you just need to write the path a bit different:
The drive letter is a single character at the beginning of the path i.e. no colon ":"
replace the backslash with a slash
then you should be set.
So for example...
C:\users\johndoe\documents\projectfiles\mydatafile.txt
becomes
c/users/johndoe/documents/projectfiles/mydatafile.txt
With this path, you can use all the IO classes for file manipulation.

Java - method to lookup a specific ID from txt file and return that line details

I am writing a method to lookup a specific ID that is stored within a txt file.
These details are assigned to an arrayList titled list, if the lookup string matches the data stored in list then it reads the id,firstname,surname (IE the whole line of the txt file) and then creates an instance of another class profile.
I then want to add this lookup data to a new arrayList titled lookup then to output it. I have the below method however, it does not work and just jumps to my else clause.
Could anyone tell me where i'm going wrong and how to fix would be appreciated. Thanks.
Could you instead use a TupleMap for the same effect?
// create our map Map peopleByForename
= new HashMap>();
// populate it peopleByForename.put("Bob", new Tuple2(new Person("Bob
Smith",
new Person("Bob Jones"));
// read from it Tuple bobs = peopleByForename["Bob"];
Person bob1 = bobs.Item1; Person bob2 = bobs.Item2;
Then an example of reading the key:value from the txt file can be found here : Java read txt file to hashmap, split by ":" using Buffered Reader.
If you are using Java8, you can use Lambda to help you. Just replace this line:
if(list.contains(IDlookup))
to this one:
boolean containsId = list.stream().anyMatch((Profile p) -> p.getId().equals(IDlookup));
if (containsId)

Saving variable state in between sessions?

So I'm in the process of developing a Java IRC bot as a bit of a side project for a friend of mine, and while development is going well, I'm a little unsure as how to save the current state of certain variables in between sessions. It doesn't have a GUI, so I didn't think that it would be too complex, but my searching efforts have been futile thus far.
Thanks.
It will depend on the sort of variables you want to keep, but all methods will require you to write some sort data to a file.
If you only need to keep a handful of variables, you could consider implementing a .config file that could be a simple delimited text file.
If it's an entire object that you want to keep track of, say, a player in an irc game, one option you have is to parse the object into JSON, and save it to a textfile, for reading later. You can use Gson for this
example for a 'player' object:
public String savePlayer(String playerName){
Gson gsonPretty = new GsonBuilder().setPrettyPrinting().create();
String playerFile = System.getProperty("user.dir")+"\\players\\"+playerName;
String jsonplayers = gsonPretty.toJson(players.get(playerName));
try{
FileWriter writer = new FileWriter(playerFile+".json");
writer.write(jsonplayers);
writer.close();
return "Player file saved successfully!";
}catch(Exception e){
e.printStackTrace();
}
return "Something went wrong";
}
you can then create a load method that either has the file name hard coded, or a string input to determine which file to load, and use something like:
playerFromJson = gson.fromJson(jsonString, Player.class);
to use that object in the code

writeDelimitedTo/parseDelimitedFrom seem to be losing data

I am trying to use protocol buffer to record a little market data. Each time I get a quote notification from the market, I take this quote and convert it into a protocol buffers object. Then I call "writeDelimitedTo"
Example of my recorder:
try {
writeLock.lock();
LimitOrder serializableQuote = ...
LimitOrderTransport gpbQuoteRaw = serializableQuote.serialize();
LimitOrderTransport gpbQuote = LimitOrderTransport.newBuilder(gpbQuoteRaw).build();
gpbQuote.writeDelimitedTo(fileStream);
csvWriter1.println(gpbQuote.getIdNumber() + DELIMITER+ gpbQuote.getSymbol() + ...);
} finally {
writeLock.unlock();
}
The reason for the locking is because quotes coming from different markets are handled by different threads, so I was trying to simplify and "serialize" the logging to the file.
Code that Reads the resulting file:
FileInputStream stream = new FileInputStream(pathToFile);
PrintWriter writer = new PrintWriter("quoteStream6-compare.csv", "UTF-8");
while(LimitOrderTransport.newBuilder().mergeDelimitedFrom(stream)) {
LimitOrderTransport gpbQuote= LimitOrderTransport.parseDelimitedFrom(stream);
csvWriter2.println(gpbQuote.getIdNumber()+DELIMITER+ gpbQuote.getSymbol() ...);
}
When I run the recorder, I get a binary file that seems to grow in size. When I use my reader to read from the file I also appear to get a large number of quotes. They are all different and appear correct.
Here's the issue: Many of the quotes appear to be "missing" - Not present when my reader reads from the file.
I tried an experiment with csvWriter1 and csvWriter2. In my writer, I write out a csv file then in my reader I write a second cvs file using the my protobufs file as a source.
The theory is that they should match up. They don't match up. The original csv file contains many more quotes in it than the csv that I generate by reading my protobufs recorded data.
What gives? Am I not using writeDelimitedTo/parseDelimitedFrom correctly?
Thanks!
Your problem is here:
while(LimitOrderTransport.newBuilder().mergeDelimitedFrom(stream)) {
LimitOrderTransport gpbQuote= LimitOrderTransport.parseDelimitedFrom(stream);
The first line constructs a new LimitOrderTransport.Builder and uses it to parse a message from the stream. Then that builder is discarded.
The second line parses a new message from the same stream, into a new builder.
So you are discarding every other message.
Do this instead:
while (true) {
LimitOrderTransport gpbQuote = LimitOrderTransport.parseDelimitedFrom(stream);
if (gpbQuote == null) break; // EOF

Java - create dynamic variable table that I can easily call back variables

I am a newbie programmer, very newbie..
I am trying to write a program to test our website and am using Java and Selenium.
The issue is I want to create a "table" or a "reference" that will allow me to store variables that can easily be called back and used in different calls.
I tried to use a HashMap but found it was no good because when I rerun my testing code there is a new hashmap each time. I want something that can store the values and remember them the next time I run the code.
I looked at creating a mysql table but I can't figure out how to recall the variables out of the table once they have been created.
I hope this makes some sense. :0) Pls check out below if an example would be more useful
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Here is an example of the hashmap that I was using:
HashMap idTable = new HashMap();
idTable.put("GroupName", new String("Group " +
Long.toHexString(Double.doubleToLongBits(Math.random()))));
element = driver.findElement(By.id("name"));
element.sendKeys((String)idTable.get("GroupName"));
FYI: The reason this doesn't work for me is that I want to be able to wrap it in an "if" statement; to tell the computer that if the variable called "GroupName" already exists then don't do it again.. however every time I run the script I make a call to the function [HashMap idTable = new HashMap();] and I don't know how to NOT make that call because the HashMap isn't saved anywhere.. it is created new each time.
Thanks,
Orli
not sure where to add this: but following the first suggestion here is what I did.
HashMap idTable;
try{
ObjectInputStream is = new ObjectInputStream(
new FileInputStream("C:\Documents and Settings\My Documents\Selenium local\hashmap.dat"));
idTable = (HashMap) is.readObject();
}
catch(Exception e){
idTable = new HashMap();
}
AND then:
try{
ObjectOutputStream os = new ObjectOutputStream (
new FileOutputStream("C:\Documents and Settings\My Documents\Selenium local\hashmap.dat"));
os.writeObject(idTable);
os.close();
}
catch (Exception e){
}
It works. :0) Thanks for the help!
Use an instance of Properties for simple string key/value pairs. It is a Map, like HashMap but has load and store methods for reading/writing its contents to a file. This should be more than adequate for simple testing usage.
It is commonly used for loading configuration files.
You must store them somewhere not in the code, as the code goes bye-bye whenever the JVM shuts down. Two good options to do this are
Using SQL database, research this more via google if you want
Via files, simply writing your HashMap database to a file at the end of your program (Do Runtime.addShutdownHook, and pass it a thread whcih stores your hashmap to the file), and have it read from the file at the begining of the code (if the file is nonexistant, make a new one, and store an empty hashmap to it)

Categories

Resources