I am writing a file in java with BufferedWriter. Here is my code -
public static void main(String[] args) {
try(BufferedWriter writer = Files.newBufferedWriter(filePath, Charset.forName("CP1252"))) {
while (thereIsContentToWrite){
writer.write(content);
}
}catch (CharacterCodingException ce){
//get content of writer's current buffer (java.io.BufferedWriter.cb)
}catch (IOException e) {
e.printStackTrace();
}
}
I want to report out the content of the current buffer of writer as it contains the "Unmappable character" as per cp1252.
Currently, we are trying to maintain another buffer to hold the content but I would like to know whether there is a better approach to achieve the same.
You can write a CustomBufferedWriter which is similar to BufferedWriter and add a getter for cb in your implementation.
If I understand correctly, you want to report the contents of the BufferedWriter buffer. You can do that, using the Reflection API.
The following code should retrieve the buffer contents:
// BufferedWriter buffer is the private field "cb"
Field bufferField = writer.getClass().getDeclaredField("cb");
// We make this field accessible so we can retrieve its contents
bufferField .setAccessible(true);
// We can now get the data
char[] buffer = (char[]) bufferField.get(writer);
Related
I have made reference from this question and achieved success in setting up encryption. I am trying to however utilize this encryption on a string of array to write into a file. This is how I am setting my method up but I end up writing only one of the string array into the file.
String[] str = new String ["X: Adam", "Y: Barry", "z: Oliver"];
File file = new File(Path + "/EncryptedFile.txt);
Calling method to write the string array into the file: Crypto.WriteEncrypteFile(str, file);
The method
Public void WriteEncrypteFile(String[] str, File file) {
try {
BufferedWriter w = new BufferedWriter(new FileWriter(file));
byte[] tmptxt = Array.toString(str).getbytes(Charset.forName(" UTF-8 "));
byte[] encTxt = cipher.doFinal(tmptxt);
w.write(string.valueOf(encTxt));
w.flush();
w.close();
} catch (Exception e){
e.printStackTrace();
}
My questions is how can I write an encrypted string from my array into the file. Any pointers?
You are just writing the String value of the array to the file (since you use Array.toString(str)). This will usually just be some representation of the reference. You have to either concatenate the values of the array or loop through it and encrypt/write every value individually.
Additionally, you shouldn't use a Writer to write content that does not consist of characters. Writers always try to encode the output which could potentially ruin your carefully set up bytes.
Just use a FileOutputStream and write the bytes with that:
try( FileOutputStream fos = new FileOutputStream(file) ) {
for(String s : str) {
byte[] tmptxt = s.getbytes(Charset.forName("UTF-8"));
byte[] encTxt = cipher.doFinal(tmptxt);
w.write(encTxt);
}
} catch(IOException e) {
// print error or whatever
}
For reading you do the same thing but with a FileInputStream instead.
You can use Arrays.toString(), but this way you will need to parse it to read it. Alternatively you can also write the byte[] directly in the file using an OutputStream. There's no need to convert to a string unless you want a human (e.g. yourself) to read it.
I have been looking for the past hour or so trying to find the reason for this, but have found nothing. It is a very small text file (only 4 characters at most), thus the reason I did not bother with a BufferedReader or BufferedWriter. The problem lies in the fact that while I have the writer put the variable into the file and even close the file, it does not actually keep the change in the file. I have tested this by checking the file immediately after running the method containing this code.
try {
int subtract = Integer.parseInt(secMessage[2]);
try {
String deaths = readFile("C:/Users/Samboni/Documents/Stuff For Streaming/deaths.txt", Charset.defaultCharset());
FileWriter write = new FileWriter("C:/Users/Samboni/Documents/Stuff For Streaming/deaths.txt");
int comb = Integer.parseInt(deaths) - subtract;
write.write(comb);
write.close();
sendMessage(channel, "Death count updated to " + comb);
} catch (IOException e) {
e.printStackTrace();
}
} catch (NumberFormatException e) {
e.printStackTrace();
sendMessage(channel, "Please use numbers to modify death count");
}
EDIT: Since it was asked, here is my readFile message:
static String readFile(String path, Charset encoding) throws IOException {
byte[] encoded = Files.readAllBytes(Paths.get(path));
return new String(encoded, encoding);
}
I have already tested it and it returns the contents without error.
EDIT2: Posting the readFile method made me think of something to try, so I removed the call to it (code above also updated) and tried it again. It now writes to the file, but does not write what I want. New question will be made for this.
FileWriter write = new FileWriter(readFile("C:/Users/Samboni/Documents/Stuff For Streaming/deaths.txt", Charset.defaultCharset()));
You're trying to write a file named after the contents of deaths.txt. It's possible that you intend to be writing to the file itself.
From http://docs.oracle.com/javase/7/docs/api/java/io/FileWriter.html
FileWriter(String fileName)
Constructs a FileWriter object given a file name.
FileWriter write = new FileWriter(readFile("C:/Users/Samboni/Documents/Stuff For Streaming/deaths.txt", Charset.defaultCharset()));
Currently you are using the contents of the file instead of the file name.
My data is stored in an ArrayList whose size increases during program execution.
I managed to save all the data whenever the size increases, but this brings me to overwrite the data already stored.
The solution is to go directly to the bottom line and insert the contents of the last cell of ArrayList. Unfortunately I do not know how to implement it.
Thank you for helping me to do this.
Below is the method I used.
private void SaveLocationData(){
try {
FileOutputStream output = openFileOutput("latlngpoints.txt",Context.MODE_PRIVATE);
DataOutputStream dout = new DataOutputStream(output);
dout.writeInt(LocationList.size());
for (Location location : LocationList) {
dout.writeUTF(location.getLatitude() + "," + location.getLongitude());
}
dout.flush(); // Flush stream ...
dout.close(); // ... and close.
} catch (IOException exc) {
exc.printStackTrace();
}
}
Use MODE_APPEND:
FileOutputStream output = openFileOutput("latlngpoints.txt",Context.MODE_APPEND);
From the doc:
File creation mode: for use with openFileOutput(String, int), if the
file already exists then write data to the end of the existing file
instead of erasing it.
You can try this too
FileWriter fstream = new FileWriter("x.txt",true); //this will allow to append
BufferedWriter fbw = new BufferedWriter(fstream);
fbw.write("append txt...");
fbw.newLine();
fbw.close();
I have this piece of code, just to try to write it to a file. But when I compile it, it doesn't display any errors, but text in my file is unreadable, some Unicode codes etc... I use eclipse IDE. What could be the reason for this?
public static void main(String[] args) {
String s = "Hello world!";
int i = 143141141;
try
{
//create new file with an ObjectOutputStream
FileOutputStream out = new FileOutputStream("test.txt");
ObjectOutputStream oout = new ObjectOutputStream(out);
//write something in a file
oout.writeObject(s);
oout.writeObject(i);
//close the stream
oout.close();
//create an ObjectInputStream for the file we created before
ObjectInputStream ois = new ObjectInputStream(
new FileInputStream("test.txt"));
//read and print what we wrote before
System.out.println("" + (String) ois.readObject());
System.out.println("" + ois.readObject());
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
Since you are using ObjectOutputStream and ObjectInputStream , it will write in Object code , which is not readable , and as well when u read from file , it will come up as an Object so again as an Object ,
Use BufferedReader or Writer to write String into file , which can be read
FileReader f=new FileReader(new File("test.txt"));
BufferedReader f1=new BufferedReader(f)
;
With an ObjectOutputStream, you're using Serialization to write your objects to a file. Serialization is using an encoding system, and you use correctly an ObjectInputStream in your program to decode these objects. But you won't be able to read the information in the file created by the Serialization process.
You should use PrintWriter to write text files, ObjectOutputStream writes binary data.
Java ObjectOuputStream writes objects in a binary non human readable format which can be read only with ObjectInputStream.
Your code is working fine for me. If I understand it correctly when look at the contents of file by opening it in editor (say notepad or eclipse) you see characters stored as binary content in it. As you are using ObjectInputStream and ObjectOutputStream the behavior is correct.
You are not writing values of your String and Integer objects but their object representations in binary format. That is called object-serialization. That is some how encoded to represent all the information associate with the object not only its value That is only displayed when decoded in the same way as we encoded them. So, normal text editor cannot display the information as you expected.
If you want to save the string representation only, use the classes such as PrintWriter.
I tried your code. It's working perfectly for me. See the attached image.
Try cleaning your workspace. If it doesn't work, try creating a new Java project and copy the same code posted here and try. It should work.
You're making the folly of writing the output string through an ObjectOutputStream which serializes the String and Integer objects in your code and saves the Object state along with the value of the object. This is the reason why you see encoded text when you open the file. The following excerpt sums up the values which are stored when an Object is serialized:
The default serialization mechanism for an object writes the class of the object, the class signature, and the values of all non-transient and non-static fields. References to other objects (except in transient or static fields) cause those objects to be written also. Multiple references to a single object are encoded using a reference sharing mechanism so that graphs of objects can be restored to the same shape as when the original was written.(ObjectOutputStream)
The writeObject method is responsible for writing the state of the object for its particular class so that the corresponding readObject method can restore it.
Primitive data, excluding serializable fields and externalizable data, is written to the ObjectOutputStream in block-data records. A block data record is composed of a header and data. The block data header consists of a marker and the number of bytes to follow the header. (ObjectOutputStream javadoc)
The possible problem with your code is you are not flushing the output data. So that it might not get written to the output file.
Try the below code.
public static void main(String[] args) {
String s = "Hello world!";
int i = 143141141;
try
{
//create new file with an ObjectOutputStream
FileOutputStream out = new FileOutputStream("test.txt");
ObjectOutputStream oout = new ObjectOutputStream(out);
//write something in a file
oout.writeObject(s);
oout.flush();
oout.writeObject(i);
oout.flush();
//close the stream
out.close();
oout.close();
//create an ObjectInputStream for the file we created before
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("test.txt"));
//read and print what we wrote before
System.out.println("" + (String) ois.readObject());
System.out.println("" + ois.readObject());
ois.close();
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
And also if you want to read your written objects into the file then you can't because they are written as serialized objects. For textual operation with files you can consider BufferedReader or PrintWriter. see the following code.
public class WriteToFileExample {
public static void main(String[] args) {
try {
String content = "This is the content to write into file";
File file = new File("c:\\desktop\\filename.txt");
// if file doesnt exists, then create it
if (!file.exists()) {
file.createNewFile();
}
FileWriter fw = new FileWriter(file.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw);
bw.write(content);
bw.close();
System.out.println("Done");
} catch (IOException e) {
e.printStackTrace();
}
}
}
After this you can open your text file and can see the written content in the human readable form and it is good practice to not to give "txt" formats when you are writing objects to the file. It's misleading.
Hope this helps.
I'm having memory problem as working with very large dataset and getting memory leaks with char[] and Strings, don't know why! So I am thinking of writing some processed data in a file and not store in memory. So, I want to write texts from an arrayList in a file using a loop. First the program will check if the specific file already exist in the current working directory and if not then create a file with the specific name and start writing texts from the arrayList line by line using a loop; and if the file is already exist then open the file and append the 1st array value after the last line(in a new line) of the file and start writing other array values in a loop line by line.
Can any body suggest me how can I do this in Java? I'm not that good in Java so please provide some sample code if possible.
Thanks!
I'm not sure what parts of the process you are unsure of, so I'll start at the beginning.
The Serializable interface lets you write an object to a file. Any object that implemsents Serializable can be passed to an ObjectOutputStream and written to a file.
ObjectOutputStream accepts a FileOutputStream as argument, which can append to a file.
ObjectOutputstream outputStream = new ObjectOutputStream(new FileOutputStream("filename", true));
outputStream.writeObject(anObject);
There is some exception handling to take care of, but these are the basics. Note that anObject should implement Serializable.
Reading the file is very similar, except it uses the Input version of the classes I mentioned.
Try this
ArrayList<String> StringarrayList = new ArrayList<String>();
FileWriter writer = new FileWriter("output.txt", true);
for(String str: StringarrayList ) {
writer.write(str + "\n");
}
writer.close();
// in main
List<String> SarrayList = new ArrayList<String>();
.....
fill it with content
enter content to SarrayList here.....
write to file
appendToFile (SarrayList);
.....
public void appendToFile (List<String> SarrayList) {
BufferedWriter bw = null;
boolean myappend = true;
try {
bw = new BufferedWriter(new FileWriter("myContent.txt", myappend));
for(String line: SarrayList ) {
bw.write(line);
bw.newLine();
}
bw.flush();
} catch (IOException ioe) {
ioe.printStackTrace();
} finally {
if (bw != null) try {
bw.close();
} catch (IOException ioe2) {
// ignore it or write notice
}
}
}