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.
Related
I am trying to write data to a binary file and am having difficulty. When I run this method I don't get any output to the file. Also when it comes to writing my "Date" object, I can't seem to find a write method that takes it as a parameter. The object consists of an int month, day, and year. How can I write it into a binary file properly?
Also, does "File" work for binary as well? I have only previously used it for regular .txt files and I'm not sure if it can be used the same way in this situation. Thanks!
Here is my write method:
private void writeBinary(){
//String fileName = getUserInput();
String fileTest = "BinaryMonster.bin";
File file = new File(fileTest);
DataOutputStream out;
try{
out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file, true)));
if(!(file.exists())){
file.createNewFile();
System.out.println("New file created...");
}
for(int i = 0; i < monsterAttacks.size(); i++){
out.writeInt(monsterAttacks.get(i).getID());
out.write(monsterAttacks.get(i).getDate()); //getting error
out.writeUTF(monsterAttacks.get(i).getName() + monsterAttacks.get(i).getLocation() + monsterAttacks.get(i).getReporter());
}
} catch(IOException e) {
e.printStackTrace();
}
}
It is giving error because you are writing whole object of date into the file using DataOutputStream, which don't allow you to do that.
Write it in the form of String into the file. It will be better.
out.writeUTF(monsterAttacks.get(i).getDate().toString());
But if you want to save the whole object into the file, then you need to use ObjectOutputStream which write whole serialized objects into the file.
And it is better approach to flush and close the file.
out.flush();
out.close();
The problem is that when I read a string and then, try to write each characters in separate line, into a .txt file, although System.out.println will show correct characters, when I write them into a .txt file, for the 's it will write some weird characters instead. To illustrate, here is an example: suppose we have this line Second subject’s layout of same 100 pages. and we want to write it into a .txt file, using the following code:
public static void write(String Swrite) throws IOException {
if(!file.exists()){
file.createNewFile();
}
FileOutputStream fop=new FileOutputStream(file,true);
if(Swrite!=null)
for(final String s : Swrite.split(" ")){
fop.write(s.toLowerCase().getBytes());
fop.write(System.getProperty("line.separator").getBytes());
}
fop.flush();
fop.close();
}
the written file would look like this for the word, subject's: subject’s. I have no idea why this happens.
Try something like the following. It frees you from having to deal with character encoding.
PrintWriter pw = null;
try {
pw = new PrintWriter(file);
if (Swrite!=null)
for (String s : Swrite.split(" ")) {
pw.println(s);
}
}
}
finally {
if (pw != null) {
pw.close();
}
}
How about something like this:
// The file to read the input from and write the output to.
// Original content: Second subject’s layout of same 100 pages.
File file = new File("C:\\temp\\file.txt");
// The charset of the file, in our case UTF-8.
Charset utf8Charset = Charset.forName("UTF-8");
// Read all bytes from the file and create a string out of it (with the correct charset).
String inputString = new String(Files.readAllBytes(file.toPath()), utf8Charset);
// Create a list of all output lines
List<String> lines = new ArrayList<>();
// Add the original line and than an empty line for clarity sake.
lines.add(inputString);
lines.add("");
// Convert the input string to lowercase and iterate over it's char array.
// Than for each char create a string which is a new line.
for(char c : inputString.toLowerCase().toCharArray()){
lines.add(new String(new char[]{c}));
}
// Write all lines in the correct char encoding to the file
Files.write(file.toPath(), lines, utf8Charset);
It all has to do with the used charsets as commented above.
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.
public static void writeIntoFile() {
FileOutputStream fileOutputStream = null;
ObjectOutputStream objectOutputStream = null;
try {
fileOutputStream = new FileOutputStream("Employee.txt");
objectOutputStream = new ObjectOutputStream(fileOutputStream);
objectOutputStream.writeObject(list1);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fileOutputStream == null) {
System.out.println("file is not created");
}
if (objectOutputStream == null) {
System.out.println("cant able to write");
}
}
}
I want to using this function to writing in a file. it writes successfully but it display data in bytecode. how can I save it into string format?
Use a FileWriter wrapped inside a BufferedWriter to write character data to a File.
ObjectOutputStream is used for serialization and results in a binary encoded file. Its only useful if you only want to load the file through your program and do not wish to read its contents elsewhere like in an external editor.
You also need to iterate through your List and save the requisite properties of your underlying Object in a format you wish to parse your File later on in. For example, as CSV (comma separated values) every Employee object and its properties would be persisted as one single line in the output file.
BufferedWriter br = new BufferedWriter(new FileWriter("Employee.csv"));
for (Employee employee : list) {
br.write(employee.getFName() + ", " + employee.getLName());
br.newLine();
}
br.close();
in the function writeIntoFile is write a Serialization Object into file
you should use the object's toString() to write a String into file
you can change bytecode into string using one simple way.
pass the bytecode into string constructor
like this:
new String(bytecode object);
and then write string object into file.
This is basically what I am trying to do.
I wanna take a File
Turn it into a Byte Array
Turn it into a String
Store it in a MySQL Table
Retrieve the String
Turn it back into a Byte Array
Turn it back into a File
Now, I have some code for you, which I tried to comment as best as I could. My problem is, that the file I get at the end of this code, doesn't come out right. It's missing information. It's a text file, so I should be able to tell whether the file is complete or not.
As far as I can see, it looks like I only get the last part of the file, and not the entire file. I am pretty sure I messing something up badly somewhere in this conversion. If you got suggestions on how to do this conversion and retrieval more efficiently (Still keeping the Database and all that in mind), please let me know as well!
The code is listed below
import java.io.*;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;
public class main {
public static void main(String[] args) {
// The file we want to save.
File f = new File("build.xml");
try {
// Make it into a byte array first
FileInputStream fis = new FileInputStream(f);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
try {
for(int readNum; (readNum = fis.read(buf)) != -1;) {
bos.write(buf, 0, readNum);
System.out.println("read " + readNum + " bytes,");
}
StringBuilder s = new StringBuilder();
// Now we simulate making it into a String, for easier storage
// in a database.
for(byte b : buf) {
// for debugging
s.append(b).append(",");
System.out.print(b +",");
}
// Now we want to retrieve the file from the database as a string
File someFile = new File("build2.xml");
FileOutputStream fos = new FileOutputStream(someFile);
// We count how many bytes there are in this string.
// One byte per Token.
StringTokenizer st = new StringTokenizer(s.toString(),",");
buf = new byte[st.countTokens()];
int i = 0;
StringBuilder t = new StringBuilder();
// Now we parse out all Bytes from the string, and put them into
// the prepared byte array.
while(st.hasMoreTokens()) {
byte b = Byte.parseByte(st.nextToken());
System.out.print(b + ",");
buf[i] = b;
i++;
// for debugging
t.append(b).append(",");
}
// Here I print true if both strings are exactly the same
// which they should be, which means that the bytes are intact
// before and after conversion.
System.out.println("\n" +(t.toString().equals(s.toString()) ? true : false));
// Here we would make the physical file on the machine.
fos.write(buf);
fos.flush();
fos.close();
} catch (IOException ex) {
Logger.getLogger(main.class.getName()).log(Level.SEVERE, null, ex);
}
} catch (FileNotFoundException ex) {
Logger.getLogger(main.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
http://pastebin.com/699yuE8f
Your approach is totally ignoring encodings, which is not a good thing. Characters are not equal to or equivalent to bytes.
If you have to do it in the sequence you describe, then create the string by something like this:
String intermediateString = new String(theByteArray,
theSameEncodingTheFileWasCreatedWith);
Likewise, when you convert the string back into bytes, get the bytes like this:
byte[] bytesToSave = intermediateString.getBytes(theSameEncodingTheFileWasCreatedWith);
But besides any of that, what's the point of using the string at all? Why not just store the bytes right into the database?
You simply messed up the string creation, and you don't read the bos but the buf.
for(byte b : >>buf<<) {
// for debugging
s.append(b).append(",");
System.out.print(b +",");
}
Otherwise I am not convinced that it will work or it is a good solution. Why can't you just store it simply in the database?
The code you shared is IMHO more complicated as it had to be.
Why do you read your text on byte-level if you are only interested in it's String representation?
I would prefer to read the file using an InputStreamReader. That allows you to directly operate on characters.