How to get back Map from .txt file use Properties? - java

This is code to write hashtable to .txt file !
public static void save(String filename, Map<String, String> hashtable) throws IOException {
Properties prop = new Properties();
prop.putAll(hashtable);
FileOutputStream fos = new FileOutputStream(filename);
try {
prop.store(fos, prop);
} finally {
fos.close();
}
}
How we getback the hashtable from that file ?
Thanks

In the very same ugly manner:
#SuppressWarnings("unchecked")
public static Map<String, String> load(String filename) throws IOException {
Properties prop = new Properties();
FileInputStream fis = new FileInputStream(filename);
try {
prop.load(fis);
} finally {
fis.close();
}
return (Map) prop;
}

Use Properties.load()
code example:
public static Properties load(String filename) {
FileReader reader = new FileReader(filename);
Properties props = new Properties(); // The variable name must be used as props all along or must be properties
try{
props.load(reader);
} finally {
reader.close();
}
return props;
}
Edit:
If you want a map back, use something like this. (The toString is to avoid a cast - you can cast to String if you would prefer)
public static Map<String, String> load(String filename) {
FileReader reader = new FileReader(filename);
Properties props = new Properties();
try {
props.load(reader);
} finally {
reader.close();
}
Map<String, String> myMap = new HashMap<String, String>();
for (Object key : props.keySet()) {
myMap.put(key.toString(), props.get(key).toString());
}
return myMap;
}

Related

Saving / Loading HashMap<String, Integer> into file.txt

I would love to know how can I save and load my HashMap from a file called data.txt , I'm already using a method to save and load the HashMap from a config.yml (which i will show you below).
Here is my HashMap
HashMap<String, Integer> points = new HashMap<String, Integer>();
This is my saving method for the HashMap from the config.yml
public void savePoints(){
for (Entry<String, Integer> pointstostore : points.entrySet()) {
getConfig().set(pointstostore.getKey(), pointstostore.getValue());
}
saveConfig();
}
This is my loading method for the HashMap from the config.yml
public void loadPoints(){
for (String str : getConfig().getKeys(true)) {
int p = getConfig().getInt(str);
points.put(str, p);
}
}
The config.yml is structured like that in a yaml format
playername: points
playername2: points
...
Is there any way for me to create a new file called data.txt from which I can save and load the HashMap points for every player and request from each player the amount of points they have and the file to have the following or a similar format
players:
points:
playername: points
playername2: points
...
Do it by using a Properties.
To write:
Properties p = new Properties();
p.putAll(points):
try (FileOutputStream fos = new FileOutputStream("file.txt");) {
p.store(fos, null);
}
To read:
Properties p = new Properties();
try (FileInputStream fos = new FileInputStream("file.txt");) {
p.load(fos);
points = new Hasmap<>(p);
}
To make a new .yml file you do:
public class Main {
private File datafile;
private FileConfiguration data;
public void onEnable() {
datafile = new File(getDataFolder(), "data.yml");
data = YamlConfiguration.loadConfiguration(datafile);
saveDataYml();
}
public static void saveDataYml() {
try{
data.save(datafile);
}catch(Exception e){
e.printStackTrace();
}
}
public static FileConfiguration getDataYml() {
return data;
}
}

Deserialization of hashmap in java

I am serializing a hash map in my Java code and write it to a file. While deserializing, the file contains more than one values, but it returns only top most key and value pair. Can anyone tell me why? Here is my Java code for deserialization:
public static void main(String[] args) throws IOException, ClassNotFoundException {
HashMap<String, String> data = new HashMap<Integer, String>();
ObjectInputStream in = new ObjectInputStream(new FileInputStream("F:\\f.txt"));
data = (HashMap<String, String>) in.readObject();
for (Map.Entry entry : data.entrySet()) {
System.out.println("key" + entry.getKey());
System.out.println("value" + entry.getValue());
}
}
Here is my serialization code
public class SerializeObject implements Serializable {
public static void main(String[] args) throws IOException, ClassNotFoundException
{
HashMap<String,String> map = new HashMap<String,String>();
map.put("Monday","first");
map.put("Tuesday","Second");
map.put("Wednesday","Third");
FileOutputStream fout=new FileOutputStream("F:\\f.txt",true);
ObjectOutputStream out=new ObjectOutputStream(fout);
out.writeObject(map);
out.flush();
}
}
After deserializing it returns only Monday and first
You should close your streams. out.flush() might not be enough to ensure that all remaining data is written to disk. An easy way to ensure that is to use try-with-resource statements:
public static void main(String[] args) throws IOException, ClassNotFoundException
{
HashMap<String,String> map = new HashMap<String,String>();
map.put("Monday","first");
map.put("Tuesday","Second");
map.put("Wednesday","Third");
try (
FileOutputStream fout=new FileOutputStream("F:\\f.txt",true);
ObjectOutputStream out=new ObjectOutputStream(fout); )
{
out.writeObject(map);
}
}

How to return multple files from ZipInputStream

I'm downloading a zip file from an ftp server. The zip file contains a couple csv files. I'm trying to extract both csv files so that I can pass them into Opencsv, but I seem to be having some issues. I'm assuming there must be a better way to handle this than the way I'm doing it below. How do you return my csv files so that they are available in a list for my csv reader?
My code
ftp.retrieveFile(file, output);
InputStream inputStream = new ByteArrayInputStream(output.toByteArray());
Map<String, InputStream> inputStreams = new HashMap<>();
if (importTask.isZipfile()) {
inputStreams.put("products", importUtils.getZipData(new ZipInputStream(inputStream), importTask.getFilename()));
if(importTask.getCustomerFilename() != null) {
inputStream = new ByteArrayInputStream(output.toByteArray());
inputStreams.put("customers", importUtils.getZipData(new ZipInputStream(inputStream), importTask.getCustomerFilename()));
}
} else {
inputStreams.put("products", inputStream);
}
ftp.logout();
ftp.disconnect();
return inputStreams;
Zip
public InputStream getZipData(ZipInputStream zip, String filename) throws FileNotFoundException, IOException {
for (ZipEntry e; (e = zip.getNextEntry()) != null;) {
if (e.getName().equals(filename)) {
return zip;
}
}
throw new FileNotFoundException("zip://" + filename);
}
If you use Java 7+ you have an easier solution than that; you can just use the zip filesystem provider.
Here is some sample code; note that you need to .close() the generated InputStreams and FileSystems:
public static void getFsFromZipFile(final Path zipFile)
throws IOException
{
final URI uri = URI.create("jar:" + zipFile.toUri());
final Map<String, ?> env = Collections.singletonMap("readonly", "true");
return FileSystems.newFileSystem(uri, env);
}
public static getInputStreamFromZip(final FileSystem zipfs, final String name)
throws IOException
{
return Files.newInputStream(zipfs.getPath(name));
}
This is not how I'd recommend you do it however. What I'd recommend is this:
final Map<String, Path> getFilesFromZip(final Path zipFile, final String... names)
throws IOException
{
Path tmpfile;
final URI uri = URI.create("jar:" + zipFile.toUri());
final Map<String, ?> env = Collections.singletonMap("readonly", "true);
final Map<String, Path> ret = new HashMap<>();
try (
final FileSystem zipfs = FileSystems.newFileSystem(uri, env);
) {
for (final String name: names) {
tmpfile = Files.createTempFile("tmp", ".csv");
Files.copy(zipfs.getPath(name), tmpfile);
ret.put(name, tmpfile);
}
return ret;
}
}

How to load Properties only once in java?

I have loaded property file in java.
public String getproperties(String property)
InputStream inputStream = new ClassPathResource("test.properties").getInputStream();
Properties testProperties = new Properties();
testProperties.load(inputStream);
inputStream.close();
return testProperties.getProperty(propertyType);
}
Its loaded successfully.The problem is every time property file loaded instead of loading only once.
How to achieve this?
Store the Properties object as a field outside the method, initially null, and only create it on first call:
private Properties testProperties = null;
public String getproperties(String property)
if (testProperties == null) {
InputStream inputStream = new ClassPathResource("test.properties").getInputStream();
testProperties = new Properties();
testProperties.load(inputStream);
inputStream.close();
}
return testProperties.getProperty(propertyType);
}
You can easily cache the properties by doing something like this:
class PropertyContainer {
private static Properties properties;
public static synchronized Properties getProperties() {
if (properties != null) { return properties; }
InputStream inputStream = new ClassPathResource("test.properties").getInputStream();
properties = new Properties();
properties.load(inputStream);
inputStream.close();
}
}
Your old getproperties method would then be something like this:
return PropertyContainer.getProperties().getProperty(propertyType);
This of course assumes that you only need one property file.
I usually wrap this into a private method, storing the object into a private field:
private Properties _testProperties;
private Properties properties() {
if (_testProperties == null) {
InputStream inputStream = new ClassPathResource("test.properties").getInputStream();
_testProperties = new Properties();
inputStream.close();
_testProperties.load(inputStream);
}
return _testProperties ;
}
public String getproperties(String property) {
return properties().getProperty(property);
}
Just create class field Properties properties:)
And save once loaded values there.

loading the properties file

I wanted to read some properties file.
For that I created a small program which reads, writes and also updates this properties file.
Now some people are saying the properties file should be read only once, that means when the class is loaded it should read once, not multiple times for each key.
So I have to read the properties file inside a static block.
Now my doubt if I make any new entry to the properties file, will it be loaded the new entry ?
Please suggest me which is the correct way to design the loading of properties file.
public class Parser {
private String path;
private static Properties prop = new Properties();
public Parser(String path) throws IOException{
this.path = path;
load();
}
public Model readPropertiesFile(){
Model model = new Model();
model.setName(prop.getProperty("name"));
return model ;
}
public void createOrUpdatePropertiesFile(Model model){
prop.setProperty("name", model.getName());
}
public void setPath(String path){
this.path = path;
}
public String getPath(){
return path ;
}
public void load() throws IOException{
File file = new File(path);
if(!file.exists()){
file.createNewFile();
System.out.println("File created..");
}
prop.load(new FileInputStream(file));
}
You can try this ways;
Load properties file from classpath
public static Properties load(String propsName) throws Exception {
Properties props = new Properties();
URL url = ClassLoader.getSystemResource(propsName);
props.load(url.openStream());
return props;
}
Load a properties file
public static Properties load(File propsFile) throws IOException {
Properties props = new Properties();
FileInputStream fis = new FileInputStream(propsFile);
props.load(fis);
fis.close();
return props;
}

Categories