Java write exe file - java

is it possible to write/create an exe file in Java?
I can successfully read it but writing the exact same data that has been read to a new file seems to create some trouble because Windows tell's me it's not supported for my pc anymore.
This is the code I'm using to read the file where path is a String given with the actual path (it's in the .jar itself that's why I'm using ResourceAsStream()):
try {
InputStream inputStream = FileIO.class.getResourceAsStream(path);
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
ArrayList<String> _final = new ArrayList<String>();
String line;
while ((line = reader.readLine()) != null) {
_final.add(line);
}
inputStream.close();
return _final.toArray(new String[_final.size()]);
}catch(Exception e) {
return null;
}
This is the code I'm using to write the file:
public static void writeFileArray(String path, String[] data) {
String filename = path;
try{
FileWriter fileWriter = new FileWriter(filename);
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
for(String d : data) {
bufferedWriter.write(d + "\n");
}
bufferedWriter.close();
}
catch(IOException ex){
System.out.println("FileIO failed to write file, IO exception");
}
}
So it doesn't give me any error's or something and the file size of the original .exe and the 'transferred' .exe stays the same, but it doesn't work anymore. Am I just doing it wrong? Did I forget something? Can u even do this with Java?
Btw I'm not that experienced with reading/writing files..
Thanks for considering my request.

I'm going to guess that you're using a Reader when you should be using a raw input stream. Use BufferedInputStream instead of BufferedReader.
BufferedInputStream in = new BufferedInputStream( inputStream );
The problem is that Reader interprets the binary as your local character set instead of the data you want.
Edit: if you need a bigger hint start with this. I just noticed you're using a BufferedWriter too, that won't work either.
try {
InputStream inputStream = FileIO.class.getResourceAsStream(path);
BufferedInputStream in = new BufferedInputStream( inputStream );
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] bytes = new byte[ 1024 ];
for( int length; ( length = ins.read( bytes ) ) != -1; )
bos.write( bytes, 0, length );
}
inputStream.close();
return bos;

When you are using Java 7 or newer, you should copy a resource to a file using
public static void copyResourceToFile(String resourcePath, String filePath) {
try(InputStream inputStream = FileIO.class.getResourceAsStream(resourcePath)) {
Files.copy(inputStream, Paths.get(filePath));
}
catch(IOException ex){
System.out.println("Copying failed. "+ex.getMessage());
}
}
This construct ensures correct closing of the resources even in the exceptional case and the JRE method ensures correct and efficient copying of the data.
It accepts additional options, e.g. to specify that the target file should be overwritten in case it already exists, you would use
public static void copyResourceToFile(String resourcePath, String filePath) {
try(InputStream inputStream = FileIO.class.getResourceAsStream(resourcePath)) {
Files.copy(inputStream, Paths.get(filePath), StandardCopyOption.REPLACE_EXISTING);
}
catch(IOException ex){
System.out.println("Copying failed. "+ex.getMessage());
}
}

You are using InputStreams for strings, .exe files are bytes!
Try using a ByteArrayInputStream and ByteArrayOutputStream.
Edit: completing with markspace's answer:
new BufferedInputStream(new ByteArrayInputStream( ... ) )

Related

Inline input stream processing in Java

I need some help on below problem. I am working on a project where I need to deal with files.
I get the handle of input stream from the user from which before writing it to disk I need to perform certain steps.
calculate the file digest
check for only 1 zip file present, unzip the data if zipped
dos 2 unix conversion
record length validation
and encrypt and save the file to disk
Also need to break the flow if there is any exception in the process
I tried to use piped output and input stream, but the constraint is Java recommends it to run in 2 separate threads. Once I read from input stream I am not able to use it from other processing steps. Files can be very big so cannot cache all the data in buffer.
Please provide your suggestions or is there any third party lib I can use for same.
The biggest issue is that you'll need to peek ahead in the provided InputStream to decide if you received a zipfile or not.
private boolean isZipped(InputStream is) throws IOException {
try {
return new ZipInputStream(is).getNextEntry() != null;
} catch (final ZipException ze) {
return false;
}
}
After this you need to reset the inputstream to the initial position before setting up a DigestInputStream.
Then read a ZipInputstream or the DigestInputstream directly.
After you've done your processing, read the DigestInputStream to the end so you can obtain the digest.
Below code has been validated through a wrapping "CountingInputstream" that keeps track of the total number of bytes read from the provided FileInputStream.
final FileInputStream fis = new FileInputStream(filename);
final CountingInputStream countIs = new CountingInputStream(fis);
final boolean isZipped = isZipped(countIs);
// make sure we reset the inputstream before calculating the digest
fis.getChannel().position(0);
final DigestInputStream dis = new DigestInputStream(countIs, MessageDigest.getInstance("SHA-256"));
// decide which inputStream to use
InputStream is = null;
ZipInputStream zis = null;
if (isZipped) {
zis = new ZipInputStream(dis);
zis.getNextEntry();
is = zis;
} else {
is = dis;
}
final File tmpFile = File.createTempFile("Encrypted_", ".tmp");
final OutputStream os = new CipherOutputStream(new FileOutputStream(tmpFile), obtainCipher());
try {
readValidateAndWriteRecords(is, os);
failIf2ndZipEntryExists(zis);
} catch (final Exception e) {
os.close();
tmpFile.delete();
throw e;
}
System.out.println("Digest: " + obtainDigest(dis));
dis.close();
System.out.println("\nValidating bytes read and calculated digest");
final DigestInputStream dis2 = new DigestInputStream(new CountingInputStream(new FileInputStream(filename)), MessageDigest.getInstance("SHA-256"));
System.out.println("Digest: " + obtainDigest(dis2));
dis2.close();
Not really relevant, but these are the helper methods:
private String obtainDigest(DigestInputStream dis) throws IOException {
final byte[] buff = new byte[1024];
while (dis.read(buff) > 0) {
dis.read(buff);
}
return DatatypeConverter.printBase64Binary(dis.getMessageDigest().digest());
}
private void readValidateAndWriteRecords(InputStream is, final OutputStream os) throws IOException {
final BufferedReader br = new BufferedReader(new InputStreamReader(is));
// do2unix is done automatically by readline
for (String line = br.readLine(); line != null; line = br.readLine()) {
// record length validation
if (line.length() < 1) {
throw new RuntimeException("RecordLengthValidationFailed");
}
os.write((line + "\n").getBytes());
}
}
private void failIf2ndZipEntryExists(ZipInputStream zis) throws IOException {
if (zis != null && zis.getNextEntry() != null) {
throw new RuntimeException("Zip File contains multiple entries");
}
}
==> output:
Digest: jIisvDleAttKiPkyU/hDvbzzottAMn6n7inh4RKxPOc=
CountingInputStream closed. Total number of bytes read: 1100
Validating bytes read and calculated digest
Digest: jIisvDleAttKiPkyU/hDvbzzottAMn6n7inh4RKxPOc=
CountingInputStream closed. Total number of bytes read: 1072
Fun question, I may have gone overboard with my answer :)

Java IO Error when writing but not when reading

So the problem is I try to read the configuration file that is packed inside the .jar which works fine but then when it comes to writing to the file the file can not be found yet they are using the same
getClass().getResource(Path);
it only seems to work with the input stream.
Here is all the code of my IO class.
package com;
public class IO {
public boolean CheckStream () {
String LineRead;
try {
InputStream IS = getClass().getResourceAsStream("Config.txt");
InputStreamReader ISR = new InputStreamReader (IS,Charset.forName("UTf-8"));
BufferedReader BR = new BufferedReader(ISR);
if ((LineRead = BR.readLine()) != null) {
BR.close();
return true;
}
IS.close();
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
public void Write (String Path, String [] ThingsToWrite) throws FileNotFoundException {
OutputStream Out = new FileOutputStream (getClass().getResource(Path).getPath());
PrintStream PS = new PrintStream (Out);
for (int i = 0; i < ThingsToWrite.length; i ++) {
PS.print(ThingsToWrite[i]);
}
PS.close();
}
}
Any Help is greatly appreciated thanks.
You can't just write to a file within a jar file - it's not a file in the regular sense.
While you could unpack the whole jar file, write the new content, then pack it up again, it would be better to redesign so that you don't need to update the jar file.
For example, you might have a regular local file which is used if it's present, but then fall back to reading from the jar file otherwise. Then you only need to write to the local file.

Java zip character encoding

I'm using the following method to compress a file into a zip file:
import java.util.zip.CRC32;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public static void doZip(final File inputfis, final File outputfis) throws IOException {
FileInputStream fis = null;
FileOutputStream fos = null;
final CRC32 crc = new CRC32();
crc.reset();
try {
fis = new FileInputStream(inputfis);
fos = new FileOutputStream(outputfis);
final ZipOutputStream zos = new ZipOutputStream(fos);
zos.setLevel(6);
final ZipEntry ze = new ZipEntry(inputfis.getName());
zos.putNextEntry(ze);
final int BUFSIZ = 8192;
final byte inbuf[] = new byte[BUFSIZ];
int n;
while ((n = fis.read(inbuf)) != -1) {
zos.write(inbuf, 0, n);
crc.update(inbuf);
}
ze.setCrc(crc.getValue());
zos.finish();
zos.close();
} catch (final IOException e) {
throw e;
} finally {
if (fis != null) {
fis.close();
}
if (fos != null) {
fos.close();
}
}
}
My problem is that i have flat text files with the content N°TICKET for example, the zipped result gives some weired characters when uncompressed N° TICKET. Also characters such as é and à are not supported.
I guess it's due to the character encoding, but I don't know how to set it in my zip method to ISO-8859-1 ?
(I'm running on windows 7, java 6)
You are using streams which write exactly the bytes that they are given. Writers interpret character data and convert it to the corresponding bytes and Readers do the opposite. Java (at least in version 6) doesn't provide an easy way to to mix and match operations on zipped data and for writing characters.
This way will work though. It is, however, a little clunky.
File inputFile = new File("utf-8-data.txt");
File outputFile = new File("latin-1-data.zip");
ZipEntry entry = new ZipEntry("latin-1-data.txt");
BufferedReader reader = new BufferedReader(new FileReader(inputFile));
ZipOutputStream zipStream = new ZipOutputStream(new FileOutputStream(outputFile));
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(zipStream, Charset.forName("ISO-8859-1"))
);
zipStream.putNextEntry(entry);
// this is the important part:
// all character data is written via the writer and not the zip output stream
String line = null;
while ((line = reader.readLine()) != null) {
writer.append(line).append('\n');
}
writer.flush(); // i've used a buffered writer, so make sure to flush to the
// underlying zip output stream
zipStream.closeEntry();
zipStream.finish();
reader.close();
writer.close();
Afaik this is not available in Java 6.
But I do believe that http://commons.apache.org/compress/ can provide a solution.
Switching to Java 7 provides a new constructor that that encoding as an additional parameter.
https://blogs.oracle.com/xuemingshen/entry/non_utf_8_encoding_in
zipStream = new ZipInputStream(
new BufferedInputStream(new FileInputStream(archiveFile), BUFFER_SIZE),
Charset.forName("ISO-8859-1")
try to use org.apache.commons.compress.archivers.zip.ZipFile; not java's own library so you can give encoding like that:
import org.apache.commons.compress.archivers.zip.ZipFile;
ZipFile zipFile = new ZipFile(filepath,encoding);

Android RandomAccessFile usage from resource

How can I access an Android resource using RandomAccessFile in Java?
Here is how I would like this to work (but it doesn't):
String fileIn = resources.getResourceName(resourceID);
Log.e("fileIn", fileIn);
//BufferedReader buffer = new BufferedReader(new InputStreamReader(fileIn));
RandomAccessFile buffer = null;
try {
buffer = new RandomAccessFile(fileIn, "r");
} catch (FileNotFoundException e) {
Log.e("err", ""+e);
}
Log output:
fileIn(6062): ls3d.gold.paper:raw/wwe_obj
The following exception appears in my console:
11-26 15:06:35.027: ERROR/err(6062): java.io.FileNotFoundException: /ls3d.gold.paper:raw/wwe_obj (No such file or directory)
Like you, my situation is much easier if I can use an instance of RandomAccessFile. The solution I finally arrived at is to simply copy the resource into a file in cache, then open that file with RandomAccessFile:
/**
* Copies raw resource to a cache file.
* #return File reference to cache file.
* #throws IOException
*/
private File createCacheFile(Context context, int resourceId, String filename)
throws IOException {
File cacheFile = new File(context.getCacheDir(), filename);
if (cacheFile.createNewFile() == false) {
cacheFile.delete();
cacheFile.createNewFile();
}
// from: InputStream to: FileOutputStream.
InputStream inputStream = context.getResources().openRawResource(resourceId);
FileOutputStream fileOutputStream = new FileOutputStream(cacheFile);
int count;
byte[] buffer = new byte[1024 * 512];
while ((count = inputStream.read(buffer)) != -1) {
fileOutputStream.write(buffer, 0, count);
}
fileOutputStream.close();
inputStream.close();
return cacheFile;
}
You would use this method thusly:
File cacheFile = createCacheFile(context, resourceId, "delete-me-please");
RandomAccessFile randomAccessFile = new RandomAccessFile(cacheFile, "r");
// Insert useful things that people want.
randomAccessFile.close();
cacheFile.delete();
Its a FileNotFound exception. That means that you do not specify well the file that you want to open at String fileIn = resources.getResourceName(resourceID);
The problem is that Android can return to you only the InputStream of the raw file or a FileDescriptor but both are not enough for the RandomAccessFile constructor.
There is an open source library called Unified I/O that you can use to achieve that you want, but I think that it will just make your project 'heavier'. Perhaps you should thought if you can avoid the RandomAccessFile somehow.
I'm using this code:
public static String readContentFromResourceFile(Context context, int resourceId)
throws IOException {
StringBuffer sb = new StringBuffer();
final String NEW_LINE = System.getProperty("line.separator");
InputStream is = context.getResources().openRawResource(resourceId);
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String readLine = null;
try {
while ((readLine = br.readLine()) != null) {
sb.append(readLine);
sb.append(NEW_LINE);
}
} catch (IOException e) {
throw e;
} finally {
br.close();
is.close();
}
return sb.toString();
}

How can I read a .txt file into a single Java string while maintaining line breaks?

Virtually every code example out there reads a TXT file line-by-line and stores it in a String array. I do not want line-by-line processing because I think it's an unnecessary waste of resources for my requirements: All I want to do is quickly and efficiently dump the .txt contents into a single String. The method below does the job, however with one drawback:
private static String readFileAsString(String filePath) throws java.io.IOException{
byte[] buffer = new byte[(int) new File(filePath).length()];
BufferedInputStream f = null;
try {
f = new BufferedInputStream(new FileInputStream(filePath));
f.read(buffer);
if (f != null) try { f.close(); } catch (IOException ignored) { }
} catch (IOException ignored) { System.out.println("File not found or invalid path.");}
return new String(buffer);
}
... the drawback is that the line breaks are converted into long spaces e.g. " ".
I want the line breaks to be converted from \n or \r to <br> (HTML tag) instead.
Thank you in advance.
What about using a Scanner and adding the linefeeds yourself:
sc = new java.util.Scanner ("sample.txt")
while (sc.hasNext ()) {
buf.append (sc.nextLine ());
buf.append ("<br />");
}
I don't see where you get your long spaces from.
You can read directly into the buffer and then create a String from the buffer:
File f = new File(filePath);
FileInputStream fin = new FileInputStream(f);
byte[] buffer = new byte[(int) f.length()];
new DataInputStream(fin).readFully(buffer);
fin.close();
String s = new String(buffer, "UTF-8");
You could add this code:
return new String(buffer).replaceAll("(\r\n|\r|\n|\n\r)", "<br>");
Is this what you are looking for?
The code will read the file contents as they appear in the file - including line breaks.
If you want to change the breaks into something else like displaying in html etc, you will either need to post process it or do it by reading the file line by line. Since you do not want the latter, you can replace your return by following which should do the conversion -
return (new String(buffer)).replaceAll("\r[\n]?", "<br>");
StringBuilder sb = new StringBuilder();
try {
InputStream is = getAssets().open("myfile.txt");
byte[] bytes = new byte[1024];
int numRead = 0;
try {
while((numRead = is.read(bytes)) != -1)
sb.append(new String(bytes, 0, numRead));
}
catch(IOException e) {
}
is.close();
}
catch(IOException e) {
}
your resulting String: String result = sb.toString();
then replace whatever you want in this result.
I agree with the general approach by #Sanket Patel, but using Commons I/O you would likely want File Utils.
So your code word look like:
String myString = FileUtils.readFileToString(new File(filePath));
There is also another version to specify an alternate character encoding.
You should try org.apache.commons.io.IOUtils.toString(InputStream is) to get file content as String. There you can pass InputStream object which you will get from
getAssets().open("xml2json.txt") *<<- belongs to Android, which returns InputStream*
in your Activity. To get String use this :
String xml = IOUtils.toString((getAssets().open("xml2json.txt")));
So,
String xml = IOUtils.toString(*pass_your_InputStream_object_here*);

Categories