I've written a encode/decode file in Java like below
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Base64;
public class Test {
public static void encodeFile(String inputfile, String outputfile) throws IOException {
byte[] input_file = Files.readAllBytes(Paths.get(inputfile));
byte[] encodedBytes = Base64.getEncoder().encode(input_file);
String encodedString = new String(encodedBytes);
File ff = new File(outputfile);
FileOutputStream fileOut = new FileOutputStream(ff);
OutputStreamWriter outStream = new OutputStreamWriter(fileOut);
outStream.write(encodedString);
outStream.flush();
}
public static void decodeFile(String encodedfilecontent, String decodedfile) throws IOException {
byte[] decoded = Base64.getDecoder().decode(encodedfilecontent);
String decodedString = new String(decoded);
File ff = new File(decodedfile);
FileOutputStream fileOut = new FileOutputStream(ff);
OutputStreamWriter outStream = new OutputStreamWriter(fileOut);
outStream.write(decodedString);
outStream.flush();
}
public static void main(String[] args) throws IOException {
String inputfile = "C:\\Users\\John\\Desktop\\Files.zip";
String outputfile = "C:\\Users\\John\\Desktop\\encoded.txt";
encodeFile(inputfile, outputfile);
String encodedfilecontent = new String(Files.readAllBytes(Paths.get(outputfile)));
String decodedfile = "C:\\Users\\John\\Desktop\\DecodedFiles.zip";
decodeFile(encodedfilecontent, decodedfile);
}
}
The above code has 2 methods:
1- To encode file to Base64 and write it in a text file
2- To decode the text file and write it back into a new file
All the input/output files are in desktop
I've test this and this encode and decode methods only work if inputfile is simple text file. If the input file is an image or a zip file like this example, the decoded file will be broken. Can you explain why it is broken like this?
Is there anyway to universally encode any type of file to Base64 and decode it back? If yes can you tweak the above code to do that?
You are not closing the files. Also there is the mentioned problem when you use text (String/Reader/Writer) for binary data: corrupt data, slower, double memory, platform dependent when not specifying the encoding.
The optimal solution is not to take the bytes in memory, additionally making a 8/5 larger byte array with base 64.
Use try-with-resources to automatically close the files, even on an exception (like illegal Base 64 chars).
public static void encodeFile(String inputFile, String outputFile)
throws IOException {
Path inPath = Paths.get(inputFile);
Path outPath = Paths.get(outputFile);
try (OutputStream out = Base64.getEncoder().wrap(Files.newOutputStream(outPath))) {
Files.copy(inPath, out);
}
}
public static void decodeFile(String encodedfilecontent, String decodedfile)
throws IOException {
Path inPath = Paths.get(encodedfilecontent);
Path outPath = Paths.get(decodedfile);
try (InputStream in = Base64.getDecoder().wrap(Files.newInputStream(inPath))) {
Files.copy(in, outPath);
}
}
In your decodeFile method you should not convert the byte[] into a String. This will use the default platform character encoding and some bytes may not make sense in that encoding. Instead, you should write the byte array in the output file directly.
Related
String Template="<P>sooper</p>
String InputFolder="D:\\project"
String title="name"
FileWriter myWriter = null;
File htmlContent = new File(InputFolder + File.separator + title+ ".html");
myWriter = new FileWriter(htmlContent);
myWriter.write(Template);
myWriter.close();
This works fine
but when I replace the title with any string which contains special characters the html file is not being created
I was expecting a html file would be created with the name name?.html
You problem is that you try to create a path (under Windows or Linux) with special characters which is not valid for path for your OS. You have to encode the path to the correct one with replasing non ascii symbols to its printable alternative.
public static void main(String... args) throws IOException {
String template = "<p>sooper</p>";
String parent = "d:/project";
String title = "n ame";
File file = new File(parent, encode(title + ".html"));
if (!file.exists()) {
file.getParentFile().mkdirs();
file.createNewFile();
}
try (FileWriter out = new FileWriter(file, true)) {
out.write(template);
}
}
private static String encode(String str) throws UnsupportedEncodingException {
return URLEncoder.encode(str, StandardCharsets.UTF_8.toString());
}
Maybe because there are spaces in your HTML file name. Can you try with Bharatiya_Janta_Party.html or Bharatiya-Janta-Party.html
Please do inform what results did you get.
I have an interface with this strings and bytes array
public interface EmailAttachment {
String getFileName();
String getFileVersion();
byte[] getContent();
String getType();
}
i want to put all of this in a file, in my class Service how could i called?:
#Override
public Boolean sendEmail(EmailAttachment attachment) {
File file = new File( "HERE,I want to bring everything");
uploadFile(file);
}
If i use attachment.getFileName(),attachment.getFileVersion(),attachment.getContent(),attachment.getType()
it brings me an error because the file needs a path
try this out create a File object with the file name and pass it on to FileOutputStream.
OutputStream accepts byte array to store it in file, once uploading done close the stream.
String FILENAME = "";
File file = new File(FILENAME);
OutputStream os = new FileOutputStream(file);
// here you can write bytes to file using FileOutputStream
os.write(bytes);
// Close the file
os.close();
byte[] test = getByteArry(excelfikepath)
I have one method where it returns the bytearray of the excel .xlsx file. To read this file i need to write these byte array using FileOutputStream on one server and from there i am calling another method which will read and process that excel from the server.
There is some limitation because of which i cant read excel file directly i have to put it onto another server and process.
Just wanted to know is there any way by which i can make use of this byte array and read excel file IN MEMORY instead of writing it on server.
This will help to get byte array out of an excel file.
public static byte[] getFileByteArr(String fileName) throws InvalidFormatException, IOException {
try (OPCPackage opcPackage = OPCPackage.open(new File(fileName))) {
try (XSSFWorkbook workbook = (XSSFWorkbook) WorkbookFactory.create(opcPackage)) {
try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
workbook.write(bos);
return bos.toByteArray();
}
}
}
}
I'm trying to change the encoding of txt files using FileUtils, but after the execution of the function, I check the encoding of the file using NotePad++ , but there is no change in the encoding of the file.
import java.io.File;
import java.io.IOException;
import org.apache.commons.io.FileUtils;
public class FileManager {
public void changeFileCharset(File file) throws IOException{
String content = FileUtils.readFileToString(file, "ISO-8859-1");
FileUtils.write(file, content, "UTF-8");
}
public static void main(String[] args) throws IOException {
FileManager fileManager = new FileManager();
fileManager.changeFileCharset(new File("unknown_words.txt"));
}
}
I also tried this function using the BufferedReader and BufferedWriter, but I get nothing .
public static void transform(File source, String srcEncoding, File target, String tgtEncoding) throws IOException {
try (
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(source), srcEncoding));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(target), tgtEncoding)); ) {
char[] buffer = new char[16384];
int read;
while ((read = br.read(buffer)) != -1)
bw.write(buffer, 0, read);
}
}
public static void main(String[] args) throws IOException {
FileManager manager = new FileManager();
File file = new File("test.txt");
File file1 = new File("test1.txt");
manager.transform(file, "UTF-8", file1, "ISO-8859-1");
}
Here is two pictures thats shows the encoding of the source file and the target file:
Is the charset check method using NotePad++ is bad, or what?
Any ideas?
Encoding is not "encryption" (as you call it). Also, it is not always easy for Notepad++ to determine what encoding a file uses. For example, if all the contents are pure ASCII characters, then there is no difference between UTF-8 and ISO-8859-1 encoded files.
You should add some text containing words with French accents. Then look at the files after telling Notepad++ to read them as UTF-8 and ANSI, and see which encoding results in readable text.
I've launched an app that saves its state with serialized object myfirstpath.UserState.
Now for I want to change the path of this object to mycleanpath.UserState (same object, only the path changes). This will work for new users installing the app for the first time but for users updating the app, they will lose their state.
Is there a way to load the serialized obect myfirstpath.UserState into mycleanpath.UserState ? (without keeping myfirstpath.UserState in my source code of course).
I wrote a little piece of code to search/replace the old path/new path in the file containing the serialized data. I convert the file before I load it, this way I can move the serialized class to the new path without keeping copy of this class at the old path. This is how you you use it :
File baseDirectory = applicationContext.getFilesDir();
File file = new File( baseDirectory, "settings.data" );
if (file.exists()) {
//We have to convert it to newsettings.Data
byte[] convertedBytes = common.utils.SerializeTools.changePathInSerializedFile(file, "old.path.data", "new.path.data");
//Write converted file
File newFile = new File( baseDirectory, "newsettings.data" );
FileOutputStream fos = new FileOutputStream(newFile);
fos.write(convertedBytes);
fos.close();
//Remove old file
file.delete();
}
And this is the code of SerializeTools.java. I've learned the java Serialize format in this great blog post http://www.javaworld.com/community/node/2915 .
package common.utils;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class SerializeTools {
static public byte[] changePathInSerializedFile(File f, String fromPath, String toPath) throws IOException {
byte[] buffer = new byte[(int)f.length()];
FileInputStream in = new FileInputStream(f);
in.read(buffer);
in.close();
return SerializeTools.changePathInSerializedData(buffer,fromPath,toPath);
}
static public byte[] changePathInSerializedData(byte[] buffer, String fromPath, String toPath) throws IOException {
byte[] search = fromPath.getBytes("UTF-8");
byte[] replace = toPath.getBytes("UTF-8");
ByteArrayOutputStream f = new ByteArrayOutputStream();
for (int i=0;i<buffer.length;i++) {
//Search 2 bytes ahead to let us modify the 2 bytes length of the class name (see Serialize format http://www.javaworld.com/community/node/2915 )
boolean found=false;
int searchMaxIndex=i+search.length+2;
if (searchMaxIndex<=buffer.length) {
found=true;
for (int j=i+2;j<searchMaxIndex;j++) {
if (search[j-i-2]!=buffer[j]) {
found=false;
break;
}
}
}
if (found) {
int high=((int)(buffer[i])&0xff);
int low=((int)(buffer[i+1])&0xff);
int classNameLength=(high<<8)+low;
classNameLength+=replace.length-search.length;
//Write new length
f.write((classNameLength>>8)&0xff);
f.write((classNameLength)&0xff);
//Write replacement path
f.write(replace);
i=searchMaxIndex-1;
} else {
f.write(buffer[i]);
}
}
f.flush();
f.close();
return f.toByteArray();
}
}
You must implement the method readResolve, mentioned at Serializable Javadoc, in your myfirstpath.UserState class. This readResolve must return the mycleanpath.UserState object.