Storing the o/p of Runtime.getRuntime().exec(command); - java

I am new to java..... I have 3 files in the zip folder, which I m extracting it using
String command = "cmd /c start cmd.exe /K \"jar -xvf record.zip\"";
Process ps= Runtime.getRuntime().exec(command);
I need to store all the three files present in record.zip into a String after extracting
these files using jar -xvf
BufferedReader br=new BufferedReader(new InputStreamReader(ps.getInputStream()));
String temp = br.readLine();
while( temp != null ) { //!temp.equals(null)) {
output.write(temp);
temp = br.readLine();
}
output.close();
I tried this code but it doesn't fetch me the desired result....
Thanks in advance....

You can use the functionality already in the JDK to read from zip files, for example this will print the contents of all files in a zip to the console line by line:
public static void main(String[] args) throws ZipException, IOException {
final File file = new File("myZipFile.zip");
final ZipFile zipFile = new ZipFile(file);
final Enumeration<? extends ZipEntry> entries = zipFile.entries();
while (entries.hasMoreElements()) {
final ZipEntry entry = entries.nextElement();
System.out.println(entry);
if (!entry.isDirectory()) {
final BufferedReader reader = new BufferedReader(new InputStreamReader(zipFile.getInputStream(entry)));
for (String line = reader.readLine(); line != null; line = reader.readLine()) {
System.out.println(line);
}
}
}
zipFile.close();
}

Related

merge file and delete the old file

I have been trying to merge two files into new file and below code does it job. But after the merge i want to delete the old files. The code I am using to delete files just delete 1 file (file2) not the both of them.
public static void Filemerger() throws IOException
{
String resultPath = System.getProperty("java.io.tmpdir");
File result = new File(resultPath+"//NewFolder", "//file3.txt");
// PrintWriter object for file3.txt
PrintWriter pw = new PrintWriter(result);
// BufferedReader object for file1.txt
BufferedReader br = new BufferedReader(new FileReader(resultPath+"file1.txt"));
String line = br.readLine();
// loop to copy each line of
// file1.txt to file3.txt
while (line != null)
{
pw.println(line);
line = br.readLine();
}
pw.flush();
br = new BufferedReader(new FileReader(resultPath+"file2.txt"));
line = br.readLine();
// loop to copy each line of
// file2.txt to file3.txt
while(line != null)
{
pw.println(line);
line = br.readLine();
}
pw.flush();
// closing resources
br.close();
pw.close();
File dir = new File(resultPath);
FileFilter fileFilter1 = new WildcardFileFilter(new String[] {"file1.txt", "file2.txt"}, IOCase.SENSITIVE);
File[] fileList1 = dir.listFiles(fileFilter1);
for (int i = 0; i < fileList1.length; i++) {
if (fileList1[i].isFile()) {
File file1 = fileList1[i].getAbsoluteFile();
file1.delete();
}
}
}
I also try this code to delete the file1 as above code delete the file2:
Path fileToDeletePath = Paths.get(resultPath+"file1.txt");
Files.delete(fileToDeletePath);
but it throws an exception that Exception in thread "main" java.nio.file.FileSystemException: C:\Users\haya\AppData\Local\Temp\file1: The process cannot access the file because it is being used by another process.
Closing the streams as suggested in the comments will fix. However you are writing a lot of code which is hard to debug / fix later. Instead simplify to NIO calls and add try with resources handling to auto-close everything on the way:
String tmp = System.getProperty("java.io.tmpdir");
Path result = Path.of(tmp, "NewFolder", "file3.txt");
Path file1 = Path.of(tmp,"file1.txt");
Path file2 = Path.of(tmp,"file2.txt");
try(OutputStream output = Files.newOutputStream(result)) {
try(InputStream input = Files.newInputStream(file1)) {
input.transferTo(output);
}
try(InputStream input = Files.newInputStream(file2)) {
input.transferTo(output);
}
}
Files.deleteIfExists(file1);
Files.deleteIfExists(file2);

How do I copy the folders inside the nested folders at loadonstartup?

I have around 150 folder and inside each folder images are present , I am trying to copy the whole directory inside the other directory . For few directories it is working then after it stops automatically without throwing any error or exception . I am using FileUtils method to achieve this .
org.apache.commons.io.FileUtils.copyDirectoryToDirectory(originalImageFolder, new File(this.ctx.getRealPath(newFilePath)));
I provided an alternate solution without the need to use a third party, such as apache FileUtils. This can be done through the command line.
I tested this out on Windows and it works for me. A Linux solution follows.
Here I am utilizing Windows xcopy command to copy all files including subdirectories.
The parameters that I pass are defined as per below.
/e - Copies all subdirectories, even if they are empty.
/i - If Source is a directory or contains wildcards and Destination
does not exist, xcopy assumes Destination specifies a directory name
and creates a new directory. Then, xcopy copies all specified files
into the new directory.
/h - Copies files with hidden and system file attributes. By default,
xcopy does not copy hidden or system files
My example(s) utilizes the ProcessBuilder class to construct a process to execute the copy(xcopy & cp) commands.
Windows:
String src = "C:\\srcDir";
String dest = "C:\\destDir";
List<String> cmd = Arrays.asList("xcopy", src, dest, "/e", "/i", "/h");
try {
Process proc = new ProcessBuilder(cmd).start();
BufferedReader inp = new BufferedReader(new InputStreamReader(proc.getInputStream()));
String line = null;
while ((line = inp.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
Linux:
String src = "srcDir/";
String dest = "~/destDir/";
List<String> cmd = Arrays.asList("/bin/bash", "-c", "cp", "r", src, dest);
try {
Process proc = new ProcessBuilder(cmd).start();
BufferedReader inp = new BufferedReader(new InputStreamReader(proc.getInputStream()));
String line = null;
while ((line = inp.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
A combo that can work on both Windows or Linux environments.
private static final String OS = System.getProperty("os.name");
private static String src = null;
private static String dest = null;
private static List<String> cmd = null;
public static void main(String[] args) {
if (OS.toLowerCase().contains("windows")) { // setup WINDOWS environment
src = "C:\\srcDir";
dest = "C:\\destDir";
cmd = Arrays.asList("xcopy", src, dest, "/s", "/e", "/i", "/h");
System.out.println("on: " + OS);
} else if (OS.toLowerCase().contains("linux")){ // setup LINUX environment
src = "srcDir/";
dest = "~/destDir/";
cmd = Arrays.asList("/bin/bash", "-c", "cp", "r", src, dest);
System.out.println("on: " + OS);
}
try {
Process proc = new ProcessBuilder(cmd).start();
BufferedReader inp = new BufferedReader(new InputStreamReader(proc.getInputStream()));
String line = null;
while ((line = inp.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}

How do you read/write and combine the output of multiple .text files and create a single .txt file? [duplicate]

This question already has answers here:
How to use PrintWriter and File classes in Java?
(11 answers)
Closed 7 years ago.
In my program I'm trying to print my output to a file but the file is empty. The program reads text files in a directory. I get the desired output to the console but not in the output.text file. Not sure what is missing in the program. thanks in advance for the help.
import java.io.*;
public class CacheData {
public static void main(String[] args) throws IOException {
String target_dir = "C:\\Files";
String output = "C:\\Files\\output.txt";
File dir = new File(target_dir);
File[] files = dir.listFiles();
for (File textfiles : files) {
if (textfiles.isFile() && textfiles.getName().endsWith(".txt")) {
BufferedReader inputStream = null;
try {
inputStream = new BufferedReader(new FileReader(textfiles));
String line;
while ((line = inputStream.readLine()) != null) {
System.out.println(line);
PrintWriter outputStream = new PrintWriter(output);
outputStream.println();
outputStream.close();
}
} finally {
if (inputStream != null) {
inputStream.close();
}
}
}
}
}
}
Looks like you're wanting to combine the contents of multiple files (text files in your case) into a single file.
Here's an IMO simpler solution. Simpler in that you don't have to worry about safely opening and closing the files yourself as you read or write.
public static void main(String[] args) throws Exception {
String targetDir = "Path to your directory of input files";
String outputFile = "Path to your output file";
File dir = new File(targetDir);
File[] files = dir.listFiles(new FilenameFilter() {
// Only get files that end with .txt
#Override
public boolean accept(File dir, String name) {
return name.toLowerCase().endsWith(".txt");
}
});
// Read all file lines into a List
List<String> inputFileLines = new ArrayList<>();
for (File file : files) {
inputFileLines.addAll(Files.readAllLines(Paths.get(file.getAbsolutePath())));
}
// Write the List to the console
for (String line : inputFileLines) {
System.out.println(line);
}
// Write the List to a single file
Files.write(Paths.get(outputFile), inputFileLines, StandardOpenOption.CREATE);
}
PrintWriter outputStream = new PrintWriter(output);
//you are not printing anything to output file.
outputStream.println();
//Change it to
outputStream.println(line);
outputStream.close();
Some modifications to your code to write to your file. Please see the inline-comments for further informations.
import java.io.*;
public class CacheData {
public static void main(String[] args) throws IOException {
String target_dir = "C:\\Files";
String output = "C:\\Files\\output.txt";
File dir = new File(target_dir);
File[] files = dir.listFiles();
for (File textfiles : files) {
if (textfiles.isFile() && textfiles.getName().endsWith(".txt")) {
BufferedReader inputStream = null;
try {
inputStream = new BufferedReader(new FileReader(textfiles));
String line;
//open the Printwriter before your loop
PrintWriter outputStream = new PrintWriter(output);
while ((line = inputStream.readLine()) != null) {
System.out.println(line);
//Write Content not just linebreaks
outputStream.println(line);
}
//close the outputstream after the loop
outputStream.close();
} finally {
if (inputStream != null) {
inputStream.close();
}
}
}
}
}
}
To write the content of every txt-File in your file, move the Printwriter before the for-loop and close the printwriter after the for-loop and not just the while-loop.

Delete Temp File in Java

Am having the below code , creating a Temp file and read that and deleting the file.
But after deletion also file available to read .Please help to find wrong with my code....
public static void main(String args[]) throws Exception
{
Calendar mSec = Calendar.getInstance();
String fileName="hubname_"+"msgname_"+mSec.getTimeInMillis();
String str ="Hello How are you doing .......";
System.out.println("fileName :"+fileName);
File f = File.createTempFile(fileName, ".xml");
FileWriter fw = new FileWriter(f);
fw.write(str);
fw.flush();
fw.close();
printFileContent(f);
f.delete();
printFileContent(f);
}
public static void printFileContent(File f)throws Exception
{
BufferedReader reader = new BufferedReader( new FileReader(f));
String line = null;
StringBuilder stringBuilder = new StringBuilder();
String ls = System.getProperty("line.separator");
while( ( line = reader.readLine() ) != null ) {
stringBuilder.append( line );
stringBuilder.append( ls );
}
System.out.println("stringBuilder.toString() :"+stringBuilder.toString());
}
Output :
fileName :hubname_msgname_1358655424194
stringBuilder.toString() :Hello How are you doing .......
stringBuilder.toString() :Hello How are you doing .......
You should close reader in printFileContent. File.delete cannot delete an opened file (at least on Windows, see Keith Randall's comment below) in which case it returns false. You could check if delete was successful
if (!f.delete()) {
throw new IOException("Cannot delete " + f);
}
The following comment was added to File.delete API in Java 7
Note that the Files class defines the delete method to throw an IOException when a file cannot be deleted. This is useful for error reporting and to diagnose why a file cannot be deleted.
public static void printFileContent(File f)throws Exception
{
BufferedReader reader = new BufferedReader( new FileReader(f));
String line = null;
StringBuilder stringBuilder = new StringBuilder();
String ls = System.getProperty("line.separator");
while( ( line = reader.readLine() ) != null ) {
stringBuilder.append( line );
stringBuilder.append( ls );
}
System.out.println("stringBuilder.toString() :"+stringBuilder.toString());
if(reader != null){
reader.close();
}
}

Reading a zip file within a jar file

Previously we had some zip files within our web application. We would want to pares a specific text document within the zip file. This wasn't a problem:
URL url = getClass().getResource(zipfile);
ZipFile zip = new ZipFile(url.getFile().replaceAll("%20", " "));
Entry entry = zip.getEntry("file.txt");
InputStream is = zip.getInputStream(entry);
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String line = reader.readLine();
while (line != null) {
// do stuff
}
However we've moved these zip files into another module and want to package them within a jar. Unfortunately, creating the ZipFile now fails. I can get an InputStream for the zip: but I have no way of getting an input stream for the entry itself.
InputStream is = getClass().getResourceAsStream(zipfile);
ZipInputStream zis = new ZipInputStream(is);
ZipEntry entry = zis.getNextEntry();
while (entry != null && !entry.getName().equals("file.txt")) {
entry = zis.getNextEntry();
}
but I have no way of getting an input stream for the entry itself. I tried finding the length of the entry and getting the next n bytes from the ZipInputStream but this didn't work for me. It seemed all bytes read were 0.
Is there a way round this or am I going to have to move the zip files back into the core project?
How about TrueZip? Using it you could simply open the zipped file as if it was located inside a directory.
new FileOutputStream("/path/to/some-jar.jar/internal/zip/file.zip/myfile.txt");
According to the docs, infinite nesting is also supported. I have yet to actually use this project, but it's been on my radar for a while and it seems applicable to your problem.
Project Site: http://truezip.java.net/ (edited)
entry can give you the inputstream of the inner-zip file.
InputStream innerzipstream = zip.getInputStream(entry);
So you can use
new ZipInputStream(innerzipstream);
and ask the ZipInputStream to retrieve the content of the inner-zip-file (in an ordered fashion, you don't have random access because it's a ZipInputStream)
Look at http://download.oracle.com/javase/1.4.2/docs/api/java/util/zip/ZipInputStream.html
Sequential zip access
As ZipInputStream is reading a zip file from an input stream it has to do things in order:
// DO THIS for each entry
ZipEntry e = zipInputStreamObj.getNextEntry();
e.getName // and all data
int size = e.getSize(); // the byte count
while (size > 0) {
size -= zipInputStreamObj.read(...);
}
zipInputStreamObj.closeEntry();
// DO THIS END
zipInputStreamObj.close();
Note: I don't know if ZipInputStream.getNextEntry() returns null when end of zip file is reached or not. I hope so because I don't know other way to realize when there are no more entries.
I have modified the Sequential Zip access code provided above:
File destFile = new File(destDir, jarName);
JarOutputStream jos = new JarOutputStream(new FileOutputStream(destFile));
JarInputStream jis = new JarInputStream(is);
JarEntry jarEntry = jis.getNextJarEntry();
for (; jarEntry != null ; jarEntry = jis.getNextJarEntry()) {
jos.putNextEntry(new JarEntry(jarEntry.getName()));
if(jarEntry.isDirectory()) {
continue;
}
int bytesRead = jis.read(buffer);
while(bytesRead != -1) {
jos.write(buffer, 0, bytesRead);
bytesRead = jis.read(buffer);
}
}
is.close();
jis.close();
jos.flush();
jos.closeEntry();
jos.close();
In the above code, I am trying to copy a Jar file inside another Jar file to a folder in file system.
'is' is the input stream to the jar file inside another jar file (jar.getInputStream("lib/abcd.jar"))
it is also possible to parse the string and open an ZipInputStream on another ZipInputStream and set the entry to the file inside.
e.g. you have the String like above "path/to/some-jar.jar/internal/zip/file.zip/myfile.txt"
private static final String[] zipFiles = new String[] { ".zip", ".jar" };
public static InputStream getResourceAsStream(final String ref) throws IOException {
String abstractPath = ref.replace("\\", "/");
if (abstractPath.startsWith("/")) {
abstractPath = abstractPath.substring(1);
}
final String[] pathElements = abstractPath.split("/");
return getResourceAsStream(null, pathElements);
}
private static InputStream getResourceAsStream(final ZipInputStream parentStream, final String[] pathElements)
throws IOException {
if (pathElements.length == 0) return parentStream;
final StringBuilder nextFile = new StringBuilder();
for (int index = 0; index < pathElements.length; index++) {
final String pathElement = pathElements[index];
nextFile.append((index > 0 ? "/" : "") + pathElement);
if (pathElement.contains(".")) {
final String path = nextFile.toString();
if (checkForZip(pathElement)) {
final String[] restPath = new String[pathElements.length - index - 1];
System.arraycopy(pathElements, index + 1, restPath, 0, restPath.length);
if (parentStream != null) {
setZipToEntry(parentStream, path);
return getResourceAsStream(new ZipInputStream(parentStream), restPath);
} else return getResourceAsStream(new ZipInputStream(new FileInputStream(path)), restPath);
} else {
if (parentStream != null) {
setZipToEntry(parentStream, path);
return parentStream;
} else return new FileInputStream(path);
}
}
}
throw new FileNotFoundException("File not found: " + nextFile.toString());
}
private static void setZipToEntry(final ZipInputStream in, final String name) throws IOException {
ZipEntry entry;
while ((entry = in.getNextEntry()) != null) {
if (entry.getName().equals(name)) return;
}
throw new FileNotFoundException("File not found: " + name);
}
private static boolean checkForZip(final String ref) {
for (final String zipFile : zipFiles) {
if (ref.endsWith(zipFile)) return true;
}
return false;
}

Categories