I have a
File file = new File("/home/aa.db");
then I call file.delete();
but I like to save this file before delete with the other name in the other location. - how it is possible to do in code without any visual tools?
I need a copy - because I need to remove init file. Renaming will not do the thing
Here the sample of moving file to new directory -
File file = new File("/home/aa.db");
File dir = new File("dir");
if (file.renameTo(new File(dir, file.getName()))) {
// processing here
}
Relevant example:
import java.io.File;
public class Example {
public static void main(String[] args) {
File file = new File("C://aa.db");
File tmpFile = new File("C://temp", file.getName());
if(file.renameTo(tmpFile)) {
if(tmpFile.delete()) {
System.out.println(tmpFile.getName() + " was deleted!");
} else {
System.out.println("Delete operation failed.");
}
}
}
}
Output:
aa.db was deleted!
Read the data of file(your need) in InputStream and then use this function of File
public static long copy(InputStream in,Path target,CopyOption... options)
throws IOException
Copies all bytes from an input stream to a file. On return, the input
stream will be at end of stream.
Before this, first you need to create the target path where you want to copy the data.
Related
I have gone through the link of how to extract a .tar file and several link on SOF using Java.
However, I didnt find any which can relate to my concerns which is multilevel or nested .tar/.tgz/.zip file.
my concern is with something like below
Abc.tar.gz
--DEF.tar
--sample1.txt
--sample2.txt
--FGH.tgz
--sample3.txt
-sample4.txt
This is the simple one which I can give here . As it can be in any compressed combination with the folder like .tar inside .tar and .gz and again .tgz and so on....
My problem is I am able to extract till the first level using Apache Commons Compress library. that is if Abc.tar.gz gets extracted then in the destination/output folder its only DEF.tar available . beyond that my extraction is not working.
I tried to give the output of first to the input to the second on the fly but I got stuck with FileNotFoundException. As at that point of time output file would have not been in place and the second extraction not able to get the file.
Pseudocode:
public class CommonExtraction {
TarArchiveInputStream tar = null;
if((sourcePath.trim().toLowerCase.endsWith(".tar.gz")) || sourcePath.trim().toLowerCase.endsWith(".tgz")) {
try {
tar=new TarArchiveInputStream(new GzipCompressorInputStream(new BufferedInputStream(new FileInputStream(sourcePath))));
extractTar(tar,destPath)
} catch (Exception e) {
e.printStackTrace();
}
}
}
Public static void extractTar(TarArchiveInputStream tar, String outputFolder) {
try{
TarArchiveEntry entry;
while (null!=(entry=(TarArchiveEntry)tar.getNextTarEntry())) {
if(entry.getName().trim().toLowerCase.endsWith(".tar")){
final String path = outputFolder + entry.getName()
tar=new TarArchiveInputStream(new BufferedInputStream(new FileInputStream(path))) // failing as .tar folder after decompression from .gz not available at destination path
extractTar(tar,outputFolder)
}
extractEntry(entry,tar,outputFolder)
}
tar.close();
}catch(Exception ex){
ex.printStackTrace();
}
}
Public static void extractEntry(TarArchiveEntry entry , InputStream tar, String outputFolder){
final String path = outputFolder + entry.getName()
if(entry.isDirectory()){
new File(path).mkdirs();
}else{
//create directory for the file if not exist
}
// code to read and write until last byte is encountered
}
}
Ps: please ignore the syntax and all in the code.
Try this
try (InputStream fi = file.getInputStream();
InputStream bi = new BufferedInputStream(fi);
InputStream gzi = new GzipCompressorInputStream(bi, false);
ArchiveInputStream archive = new TarArchiveInputStream(gzi)) {
withArchiveStream(archive, result::appendEntry);
}
As i see what .tar.gz and .tgz is same formats. And my method withArchiveEntry is:
private void withArchiveStream(ArchiveInputStream archInStream, BiConsumer<ArchiveInputStream, ArchiveEntry> entryConsumer) throws IOException {
ArchiveEntry entry;
while((entry = archInStream.getNextEntry()) != null) {
entryConsumer.accept(archInStream, entry);
}
}
private void appendEntry(ArchiveInputStream archive, ArchiveEntry entry) {
if (!archive.canReadEntryData(entry)) {
throw new IOException("Can`t read archive entry");
}
if (entry.isDirectory()) {
return;
}
// And for example
String content = new String(archive.readAllBytes(), StandardCharsets.UTF_8);
System.out.println(content);
}
You have a recursive problem, so you can use recursion to solve it. Here is some pseudocode to show how it can be done:
public class ArchiveExtractor
{
public void extract(File file)
{
List<File> files; // list of extracted files
if(isZip(file))
files = extractZip(file);
else if(isTGZ(file))
files = extractTGZ(file);
else if(isTar(file))
files = extractTar(file);
else if(isGZip(file))
files = extractGZip(file);
for(File f : files)
{
if(isArchive(f))
extract(f); // recursive call
}
}
private List<File> extractZip(File file)
{
// extract archive and return list of extracted files
}
private List<File> extractTGZ(File file)
{
// extract archive and return list of extracted files
}
private List<File> extractTar(File file)
{
// extract archive and return list of extracted files
}
private List<File> extractGZip(File file)
{
// extract archive and return list of extracted file
}
}
where:
isZip() tests if the file extension is zip
isTGZ() tests if the file extension is tgz
isTar() tests if the file extension is tar
isGZip() tests if the file extension is gz
isArchive() means isZip() || isTGZ() || isTar() || isGZip()
As for the directory where each archive is extracted: you are free to do as you want.
If you process test.zip for example, you may extract in the same directory as where the archive is,
or create the directory test and extract in it.
I want to append to the file and if its not empty; and want to write if its empty. Below is is my code. write function works, append is not. Can anyone guide here?
public class Filecreate {
public static void main(String args[]) throws IOException {
File file = new File("newFileCreated.txt");
System.out.println("file path "+file.getAbsolutePath() +" file length - "+file.length());
FileWriter myWriter = new FileWriter(file);
if((int)file.length() != 0){
myWriter.append("appended text\n");
}else{
myWriter.write("Files in Java might be tricky, but it is fun enough!");
}
myWriter.close();
System.out.println("file length after writing to file "+file.length());
}
}
You don't need to worry about whether or not the file contains anything. Just apply the argument of true to the append parameter in the FileWriter constructor then always use the Writer#append() method, for example:
String ls = System.lineSeparator();
String file = "MyFile.txt";
FileWriter myWriter = new FileWriter(file, true)
myWriter.append("appended text" + ls);
/* Immediately write the stream to file. Only really
required if the writes are in a loop of some kind
and you want to see the write results right away.
The close() method also flushes the stream to file
before the close takes place. */
myWriter.flush();
System.out.println("File length after writing to file " +
new File(file).length());
myWriter .close();
If the file doesn't already exist it will be automatically created
and the line appended to it.
If the file is created but is empty then the line is appended to it.
If the file does contain content then the line is merely appended to
that content.
The issue occurs because you measure file's size after you open it. Thus, you have to check file's size before you open it. Also, I won't recommend to cast long to int, because your solution won't work on big files. To conclude, following code will work for you:
public static void main(String[] args) throws IOException {
File file = new File("newFileCreated.txt");
long fileSize = file.length();
System.out.println("file path "+file.getAbsolutePath() +" file length - "+file.length());
FileWriter myWriter = new FileWriter(file);
if(fileSize > 0L){
myWriter.append("appended text\n");
}else{
myWriter.write("Files in Java might be tricky, but it is fun enough!");
}
myWriter.close();
System.out.println("file length after writing to file "+file.length());
}
When I write an FileInputStream, while I have the valid file, it throws a FileNotFoundException.
I used this:
package io;
import java.io.*;
public class implementIo {
public static int i;
public static FileOutputStream output;
public static FileInputStream input;
public static void main(String args[]) {
try {
output = new FileOutputStream("writeModification.txt");
input = new FileInputStream("modification.txt");
do {
i = input.read();
if(i != -1) output.write(i);
}while(i != -1);
} catch (Exception e) {
System.out.println("Exception caught " + e);
} finally {
try {
if(output == null) input.close();
}catch(IOException e) {
System.out.println("IOException caught: " + e);
}
}
}
}
While I had a two separate files named "modification.txt" and "printModification.txt" in the same package folder, yet the system threw a FileNotFoundException. Please help!
This is because the FileInputStream doesn't provide the file creation during initialization like new FileOutputStream() does. So if these have been said, we can see one interesting thing to keep in mind: the modification.txt will be created every time when you initialize the FileOutputStream (and won't be overwritten) and this is why most probably your code breaks at the new FileInputStream() line.
How can you handle your exception?
You either create your file before executing the code( manually with New -> Text Document etc. ) or modify your code and make use of File class :
File file = new File("modification.txt");
try {
file.createNewFile();
input = new FileInputStream(file);
//your code here - output etc.
Your code still doesn't work even if you have the files created in the same package folder? It's because the default path that your streams are looking for your files is the current working directory. Here is an example :
myproject
|___src
| |___main
| |___java
| |___io
| |___implementIo
|___writeModification.txt
|___modification.txt
This is the correct structure if you want to use the streams like you did (with just a simple file name in stream constructor argument). But if your files are not there, you have to specify the absolute path. Here is an example :
myproject
|___src
|___main
|___java
|___io
|___implementIo
|___writeModification.txt
|___modification.txt
And the correct way to access the files is this:
FileInputStream input = new FileInputStream("C://myproject//src//main//java//io//modification.txt");
Same for the output stream. (Please modify the path with your correct file location)
I wrote a file writing script that lets you write in a file you are looking for in the console, then when you press enter it tries to find the file to see if it exists. My program works, but I don't like that I need the full pathname, every single time. I want a user to just be able to write, say, file_name.txt and the program searches a single directory for it.
Currently, I must use the full pathname every single time. This is not all of my code, but you can see that my file names have a hard coded String pathname. But what if someone else wants to run the program on their own computer? I tried looking for answers to this, but Java is always very difficult for me. If you know a way to make my code generic enough so my Scanner object can take just the file name, that would be so helpful. Thanks, let me know if anything is unclear. I have a Mac, but it should be able to work on any OS.
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.time.LocalDate;
import java.util.Scanner;
public class FileHandler {
public static boolean fileCheck = true;
public static File logFile;
public static PrintWriter logPrinter;
public static PrintWriter handMadeFile;
public static LocalDate date = LocalDate.now();
public static File fileFromScanner;
public static File directory = new File("/Users/mizu/homework");
public static String fileName;
public static File file;
public static String created = "Log has been created.";
public static String myLogFileName = "/Users/mizu/homework/my_log.txt";
public static String mainFileName = "/Users/mizu/homework/main_file.txt";
public static String fileFromMethod = "/Users/mizu//homework/file_from_method.txt";
public static String fileMessage = "I just wrote my own file contents.";
public static void main(String[] args) {
if (!directory.exists())
{
// create new directory called homework
directory.mkdir();
}
// gets file request from user
System.out.print("Enter file to find: ");
Scanner in = new Scanner(System.in);
String fileName = in.nextLine();
// initialize the main_file
fileFromScanner = new File(mainFileName);
// if main_file exists or not, print message to my_log
if (!fileFromScanner.exists())
{
// create my_log file (logFile), to keep track of events
writeToLog(created);
writeToLog("File path you entered: "
+ fileName + " does not exist.");
System.out.println(fileName + " - does not exist.");
// create file since it doesn't exist
File mainFile = new File(mainFileName);
try {
PrintWriter pwMain = new PrintWriter(new BufferedWriter
(new FileWriter(mainFile)));
writeToLog("Created " + mainFileName);
pwMain.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else
{
writeToLog(fileName + " already exists.");
System.out.println(fileName + " - already exists.");
}
// use writeToFile method to write file, create new file name
FileHandler testFile = new FileHandler(fileFromMethod);
testFile.writeToFile(testFile, fileMessage);
} // end Main
All of the other methods are below here, but not shown to keep it short.
As stated in the comments, there are several tools already available to search files in a directory. However, to answer your question, I wrote a simple program that should do what you are looking for:
public static void main(String[] args) {
// Get the absolute path from where your application has initialized
File workingDirectory = new File(System.getProperty("user.dir"));
// Get user input
String query = new Scanner(System.in).next();
// Perform a search in the working directory
List<File> files = search(workingDirectory, query);
// Check if there are no matching files
if (files.isEmpty()) {
System.out.println("No files found in " + workingDirectory.getPath() + " that match '"
+ query + "'");
return;
}
// print all the files that matched the query
for (File file : files) {
System.out.println(file.getAbsolutePath());
}
}
public static List<File> search(File file, String query) {
List<File> fileList = new ArrayList<File>();
// Get all the files in this directory
File[] files = file.listFiles();
if (files != null) {
for (File f : files) {
if (f.isDirectory()) {
// use recursion to search in all directories for the file
fileList.addAll(search(f, query));
} else if (f.getName().toLowerCase().contains(query.toLowerCase())) {
// if the filename matches the query, add it to the list
fileList.add(f);
}
}
}
return fileList;
}
1- You can make users set an environment variable to your path and use the path name in your code.
2- You can check the operating system, and put your files in a well-known folder. (C: for windows, /home for Ubuntu, /WhateverMacFolder for mac and if it is some other os ask user to enter the path.
3- You can create a folder in default path of your program and use it.
I have a file which is needed for running tests - this file needs to be personalized (name and password) by whomever is running the test. I do not want to store this file in Eclipse (since it would need to be changed by whomever runs the test; also it would be storing personal info in the repo), so I have it in my home folder (/home/conrad/ssl.properties). How can I point my program to this file?
I've tried:
InputStream sslConfigStream = MyClass.class
.getClassLoader()
.getResourceAsStream("/home/" + name + "/ssl.properties");
I've also tried:
MyClass.class.getClassLoader();
InputStream sslConfigStream = ClassLoader
.getSystemResourceAsStream("/home/" + name + "/ssl.properties");
Both of these give me a RuntimeException because the sslConfigStream is null. Any help is appreciated!
Use a FileInputStream to read data from a file. The constructor takes a string path (or a File object, which encapsulates string path).
Note 1: A "resource" is a file which is in the classpath (alongside your java/class files). Since you don't want to store your file as a resource because you don't want it in your repo, ClassLoader.getSystemResourceAsStream() is not what you want.
Note 2: You should use a cross-platform way of getting a file in a home directory, as follows:
File homeDir = new File(System.getProperty("user.home"));
File propertiesFile = new File(homeDir, "ssl.properties");
InputStream sslConfigStream = new FileInputStream("/home/" + name + "/ssl.properties")
You can simplify your work, using Java's 7 method:
public static void main(String[] args) {
String fileName = "/path/to/your/file/ssl.properties";
try {
List<String> lines = Files.readAllLines(Paths.get(fileName),
Charset.defaultCharset());
for (String line : lines) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
You can also improve your way of reading properties file, using Properties class and forget about reading and parsing your .properties file:
http://www.mkyong.com/java/java-properties-file-examples/
Is this a graphics program (ie. using the Swing library)? If so it is a pretty simple task of using a JFileChooser.
http://docs.oracle.com/javase/6/docs/api/javax/swing/JFileChooser.html
JFileChooser f = new JFileChooser();
int rval = f.showOpenDialog(this);
if (rval == JFileChooser.APPROVE_OPTION) {
// Do something with file called f
}
You can also use Scanner to read the file.
String fileContent = "";
try {
Scanner scan = new Scanner(
new File( System.getProperty("user.home")+"/ssl.properties" ));
while(scan.hasNextLine()) {
fileContent += scan.nextLine();
}
scan.close();
} catch(FileNotFoundException e) {
}