I want to store the HashSet to the server directory.
But i'm now only been able to store it in .bin files.
But how do I print all the Key's in the HashSet to a .txt file?
static Set<String> MapLocation = new HashSet<String>();
try {
SLAPI.save(MapLocation, "MapLocation.bin");
} catch (Exception ex) {
}
public static void save(Object obj, String path) throws Exception {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(
path));
oos.writeObject(obj);
oos.flush();
oos.close();
}
// check IOException in method signature
BufferedWriter out = new BufferedWriter(new FileWriter(path));
Iterator it = MapLocation.iterator(); // why capital "M"?
while(it.hasNext()) {
out.write(it.next());
out.newLine();
}
out.close();
This will save the strings to a UTF-8 text file:
public static void save(Set<String> obj, String path) throws Exception {
PrintWriter pw = null;
try {
pw = new PrintWriter(
new OutputStreamWriter(new FileOutputStream(path), "UTF-8"));
for (String s : obj) {
pw.println(s);
}
pw.flush();
} finally {
pw.close();
}
}
Specifically choosing UTF-8 is desirable because otherwise it will use whatever setting the operating system uses as its default, which will give you compatibility headaches.
Something like this:
public static void toTextFile(String fileName, Set<String> set){
Charset charset = Charset.forName("UTF-8");
try (PrintWriter writer = new PrintWriter(Files.newBufferedWriter(fileName, charset))) {
for(String content: set){
writer.println(content);
}
} catch (IOException x) {
System.err.format("IOException: %s%n", x);
}
}
Note: This code is written using the try-with-resource construct introduced in Java 7. But the idea would remain the same for other versions as well.
Another solution that avoids a line break at the end of the file:
private static void store(Set<String> sourceSet, String targetFileName) throws IOException
{
StringBuilder stringBuilder = new StringBuilder();
for (String setElement : sourceSet)
{
stringBuilder.append(setElement);
stringBuilder.append(System.lineSeparator());
}
String setString = stringBuilder.toString().trim();
byte[] setBytes = setString.getBytes(StandardCharsets.UTF_8);
Files.write(Paths.get(targetFileName), setBytes);
}
Related
this question has probably been asked and answered 100 times but unfortunately I have not found anything suitable for my issue.
The following situation: I have the problem that when I read properties to change them and then write them again, all special characters are unicode escaped.
for example ":" becomes "\:" or
DescripciĆ³n becomes Descripci\u00F3n
Is there a way to change the store method so that the special characters are not escaped?
Thanks a lot
That's my code to write the properties:
private static void writeUpdatedPropertiesFile(Properties newProperties, File sourceAndDestinationFile) {
sourceAndDestinationFile.delete();
try (FileOutputStream out = new FileOutputStream(sourceAndDestinationFile)) {
newProperties.store(out, null);
}
catch (final IOException e) {
e.printStackTrace();
}
}
You can use store(Writer) instead of store(OutputStream). You can construct an OutputStreamWriter with any charset you wish:
try (Writer out = new BufferedWriter(
new OutputStreamWriter(
new FileOutputStream(sourceAndDestinationFile),
StandardCharsets.UTF_8))) {
newProperties.store(out, null);
} catch (IOException e) {
e.printStackTrace();
}
Of course, it is your responsibility to know that the file is a UTF-8 file, and to read it using load(Reader) instead of using an InputStream:
try (Reader in = new BufferedReader(
new InputStreamReader(
new FileInputStream(sourceAndDestinationFile),
StandardCharsets.UTF_8))) {
properties.load(in);
} catch (IOException e) {
// ...
}
I solved it with a custom writer method:
private static void writeProperties(Properties properties, File destinationFile) {
try (final BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(new FileOutputStream(destinationFile), "Cp1252"))) {
for (final Object o : properties.entrySet()) {
final String keyValue = o.toString();
writer.write(keyValue + "\r\n");
}
}
catch (final IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
I ran over some problem with PrintWriter. I wrote some code that simply takes some input from a file and outputs it to another one.
Though a file is created, the file remains empty. The wanted input can be easily printed out in the console, which means the FileInputStream is working correctly.
Why is PrintWriter not printing anything?
public static void writeInFile(File in, File out) throws FileNotFoundException {
PrintWriter outputStream = null
Scanner scanner = new Scanner(new FileInputStream(in));
outputStream = new PrintWriter(new FileOutputStream(out));
outputStream.print("test");
while(scanner.hasNext()) {
outputStream.print(scanner.nextLine() + "\n");
}
scanner.close();
}
Make sure you always close your OutputStreams:
while(scanner.hasNext()) {
String s = scanner.nextLine();
outputStream.print(s+"\n");
System.out.println("Test "+s); //d.h. das Problem liegt am outputstream
}
outputStream.close();
scanner.close();
Edit: When you close the outputStream it calls flush automatically, which writes the buffer to the file. Without closing it the buffer may never be emptied/written to the file, as was the case here.
Also see this answer.
When dealing with IO which requires cleanup, I prefer to use auto resource cleanup. This is all you need at the most basic level:
public static void writeInToOut(InputStream in, OutputStream out) {
try(PrintWriter outputStream = new PrintWriter(out);
Scanner scanner = new Scanner(in)) {
while(scanner.hasNext()) {
outputStream.print(scanner.nextLine()+"\n");
}
}
}
You can now overload this function in several ways:
public static void writeInToOut(File file, OutputStream out) {
try (InputStream in = new FileInputStream(file)) {
writeInToOut(in, out);
} catch (IOException e) {
Logger.getAnonymousLogger().log(Level.WARNING, "IOError", e);
}
}
public static void writeInToOut(File inFile, File outFile) {
try (InputStream in = new FileInputStream(inFile);
OutputStream out = new FileOutputStream(outFile)) {
writeInToOut(in, out);
} catch (IOException e) {
Logger.getAnonymousLogger().log(Level.WARNING, "IOError", e);
}
}
public static void writeStdInToFile(File file) {
try (OutputStream out = new FileOutputStream(file)) {
writeInToOut(System.in, out);
} catch (IOException e) {
Logger.getAnonymousLogger().log(Level.WARNING, "IOError", e);
}
}
I want to read object from a file and place data to a LinkedList and return the reference to it. But when I try this method it returns LinkedList that have no data.
private static LinkedList<Course> readFromFile(String fileName)
throws FileNotFoundException, IOException {
LinkedList<Course> tmp = new LinkedList<Course>();
reader = new ObjectInputStream(new FileInputStream(fileName));
try {
LinkedList<Course> readObject2 = (LinkedList<Course>) reader
.readObject();
LinkedList<Course> readObject = readObject2;
tmp = readObject;
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return tmp;
}
My writing method looks like this
private static boolean writeToFile(String fileName, LinkedList<Course> templist)
throws IOException {
LinkedList<Course> templist1 = new LinkedList<Course>();
if (createFile(fileName)) {
FileOutputStream outF = new FileOutputStream(fileName);
outO = new ObjectOutputStream(outF);
outO.writeObject(templist1);
//outO.flush();
return true;
}
else
return false;
}
Writing method looks like this
private static boolean writeToFile(String fileName, LinkedList<Course> templist) throws IOException {
LinkedList<Course> templist1 = new LinkedList<Course>();
if (createFile(fileName)) {
FileOutputStream outF = new FileOutputStream(fileName);
outO = new ObjectOutputStream(outF);
outO.writeObject(templist1);
//outO.flush();
return true;
}
else
return false;
}
The Course class is implementing java.io.Serializable ?
When you read objects from a file with ObjectInputStream it should be in the same order that you stored it with ObjectOutputStream before. And with the same objects types.
If you try to read:
(LinkedList<Course>) reader.readObject();
You must have store it like:
ObjectOutputStream writer = new ObjectOutputStream(
new FileOutputStream(fileName));
writer.writeObject(yourLinkedListToSave);
As your code looks:
private static boolean writeToFile(String fileName, LinkedList<Course> templist) throws IOException {
// Dont forget to initialize with your list else the list still empty
LinkedList<Course> templist1 = new LinkedList<Course>(templist);
if (createFile(fileName)) {
FileOutputStream outF = new FileOutputStream(fileName);
outO = new ObjectOutputStream(outF);
outO.writeObject(templist1);
//outO.flush();
return true;
}
else
return false;
}
Supose you have the following method:
public static void writeToBinary(Object obj, String filename)
{
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(new FileOutputStream(filename));
oos.writeObject(obj);
} catch (Exception e) {
e.printStackTrace();
} finally{
try{
if (oos != null) oos.close ();
}catch (Exception e){
e.printStackTrace();
}
}
}
As you can see, the method writes an object to a binary file.
But now you want to rewrite the same method to allow appending objects to the same file.
Ok, you look at the java documentation and you see that you have to add a parameter with value true to the FileOutputStream:
oos = new ObjectOutputStream(new FileOutputStream(filename, true));
You compile but, whoops!, it seems that it continues overriding the file.
Well, the problems begin. After searching in google you read that you have to use the SAME ObjectOutputStream to append objects to the same file. You want to have a function that every time you call it, it appends an object. I.e. :
writeToBinary("a", filename);
writeToBinary("b", filename);
But as I said before, you have to use the same ObjectOutputStream.
Solution 1:
ObjectOutputStream out = getOutputStream (filename);
writeToBinary("a", out);
writeToBinary("b", out);
writeToBinary("c", out);
out.close ();
This is very ugly because I want to hide the usage of streams.
Is there any other solution?
EDIT: The method is static. It is inside an utility class where all methods are static.
EDIT2: SOLVED! Appending to an ObjectOutputStream. See accepted answer to my question.
Thanks.
Solved.
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
public class Test{
private static String filename = "test";
public static void main(String[] args) {
writeToBinary (filename, "a", true);
writeToBinary (filename, "b", true);
writeToBinary (filename, "c", true);
readFromBinaryFile (filename);
}
public static void writeToBinary (String filename, Object obj, boolean append){
File file = new File (filename);
ObjectOutputStream out = null;
try{
if (!file.exists () || !append) out = new ObjectOutputStream (new FileOutputStream (filename));
else out = new AppendableObjectOutputStream (new FileOutputStream (filename, append));
out.writeObject(obj);
out.flush ();
}catch (Exception e){
e.printStackTrace ();
}finally{
try{
if (out != null) out.close ();
}catch (Exception e){
e.printStackTrace ();
}
}
}
public static void readFromBinaryFile (String filename){
File file = new File (filename);
if (file.exists ()){
ObjectInputStream ois = null;
try{
ois = new ObjectInputStream (new FileInputStream (filename));
while (true){
String s = (String)ois.readObject ();
System.out.println (s);
}
}catch (EOFException e){
}catch (Exception e){
e.printStackTrace ();
}finally{
try{
if (ois != null) ois.close();
}catch (IOException e){
e.printStackTrace ();
}
}
}
}
private static class AppendableObjectOutputStream extends ObjectOutputStream {
public AppendableObjectOutputStream(OutputStream out) throws IOException {
super(out);
}
#Override
protected void writeStreamHeader() throws IOException {}
}
}
oos = new ObjectOutputStream(new FileOutputStream(filename, true)); You
compile but, whoops!, it seems that it
continues overriding the file.
That does not make sense. The FileOutputStream is a streams that appends to the existing file, so it will not overwite the file. Check it.
The problem is that a stream cannot be closed and reopened to serialize several objects. Run the following and compare the resulting files to check it.
public class XX {
public static void writeToBinary(Object obj, String filename) throws Exception {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filename,true));
oos.writeObject(obj);
oos.close();
}
public static void writeToBinary2(Object obj1, Object obj2,String filename) throws Exception {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filename,true));
oos.writeObject(obj1);
oos.writeObject(obj2);
oos.close();
}
public static void main(String[] args) throws Exception {
String s1= "hi, just trying";
String s2= "bye bye cruel world";
String filename = "/temp/f.dat";
String filename2 = filename + ".2" ;
writeToBinary(s1, filename);
writeToBinary(s2, filename);
writeToBinary2(s1, s2,filename2);
ObjectInputStream fin = new ObjectInputStream(new FileInputStream(filename)); // oops... works with filename2
Object x1 = fin.readObject();
Object x2 = fin.readObject();
System.out.println(x1);
System.out.println(x2);
}
}
Write a helper class. In constructor it will instantiate an output stream for a particular file name. Then using some append() or writeToBinary() method it will append the data. on method close() there will be flush() and close() calls on the stream.
BinaryWriteHelper helper = new BinaryWriteHelper("test.dat");
helper.writeToBinary("1");
helper.writeToBinary(2);
helper.close();
in BinaryWriteHelper :
public BinaryWriteHelper(String filename) {
this.stream = new ObjectOutputStream(new FileOutputStream(filename));
}
public close() {
// the cleanup here
}
Try this approach:
Write the object to a ByteArrayOutputStream.
Append the the size and contents of the ByteArrayOutputStream to a RandomAccessFile.
To load an object from the file, read the bytes that represent an Object into a ByteArrayInputStream and initialize an ObjectInputStream on this. The size field that was prepends each object byte sequence will come handy here.
how can i
write data to file without erasing the old content
Use new FileOutputStream(file, true). This will open file in "append" mode which will append all data written to the stream to the end of that file.
You mean "how do you append to a file"? Look for an [append-version of a constructor][1] of your File writing class, e.g.:
public FileWriter(String fileName,
boolean append)
throws IOException
Use this constructor and pass true for the append parameter.
[1]: http://download.oracle.com/javase/6/docs/api/java/io/FileWriter.html#FileWriter(java.io.File, boolean)
if you used the new one in Java 7, you can use this way
try (BufferedWriter writer = Files.newBufferedWriter(outFile, StandardCharsets.UTF_8, StandardOpenOption.APPEND))
in this code i use append (true) but my old date erase and new data overwrite on it please give me solution on it
public class FileOperation {
private static FileReader fileReader;
private static FileWriter fileWriter;
private static BufferedReader bufferedReader;
private static BufferedWriter bufferedWriter;
private static PrintWriter writer;
public static File file = new File("C:\\StudentInfo\\com\\education\\students\\file\\managing\\v1_0\\Student.txt");
public FileOperation() throws IOException {
fileReader = new FileReader(file);
fileWriter = new FileWriter(file, true);
bufferedReader = new BufferedReader(fileReader);
bufferedWriter = new BufferedWriter(fileWriter);
// FileOperation fo =new FileOperation();
}
public boolean enrollSudnents(ArrayList<Student> studentList) {
try {
writer = new PrintWriter(file);
writer.print("");
bufferedWriter = new BufferedWriter(new FileWriter(file));
for (Student s : studentList) {
String nameNumberString = String.valueOf(s.getRoll() + "!" + s.getFirstName() + "!" + s.getLastName()
+ "!" + s.getClassName() + "!" + s.getAddress() + "\n");
bufferedWriter.write(nameNumberString);
}
return true;
} catch (Exception e) {
return false;
} finally {
try {
bufferedWriter.close();
fileWriter.close();
} catch (Exception e) {
// logger.info("Exception Found In Adding data");
}
}
}