I am currently working on a method that will create files and directories. Bellow is the use case & problem explained.
1) When a user specifies a path e.g "/parent/sub folder/file.txt", the system should be able to create the directory along with the file.txt. (This one works)
2) When a user specifies a path e.g "/parent/sub-folder/" or "/parent/sub-folder", the system should be able to create all directories. (Does not work), Instead of it creating the "/sub-folder/" or /sub-folder" as a folder, it will create a file named "sub-folder".
Here is the code I have
Path path = Paths.get(rootDir+"test/hello/");
try {
Files.createDirectories(path.getParent());
if (!Files.isDirectory(path)) {
Files.createFile(path);
} else {
Files.createDirectory(path);
}
} catch (IOException e) {
System.out.println(e.getMessage());
}
You need to use createDirectories(Path) instead of createDirectory(path). As explained in the tutorial:
To create a directory several levels deep when one or more of the
parent directories might not yet exist, you can use the convenience
method, createDirectories(Path, FileAttribute). As with the
createDirectory(Path, FileAttribute) method, you can specify an
optional set of initial file attributes. The following code snippet
uses default attributes:
Files.createDirectories(Paths.get("foo/bar/test"));
The directories
are created, as needed, from the top down. In the foo/bar/test
example, if the foo directory does not exist, it is created. Next, the
bar directory is created, if needed, and, finally, the test directory
is created.
It is possible for this method to fail after creating some, but not
all, of the parent directories.
Not sure of which File API you are using. But find below the simplest code to create file along with folders using java.io package.
import java.io.File;
import java.io.IOException;
public class FileTest {
public static void main(String[] args) {
FileTest fileTest = new FileTest();
fileTest.createFile("C:"+File.separator+"folder"+File.separator+"file.txt");
}
public void createFile(String rootDir) {
String filePath = rootDir;
try {
if(rootDir.contains(File.separator)){
filePath = rootDir.substring(0, rootDir.lastIndexOf(File.separator));
}
File file = new File(filePath);
if(!file.exists()) {
System.out.println(file.mkdirs());
file = new File(rootDir);
System.out.println(file.createNewFile());
}
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
Related
Let's say I have a method like:
public void copyAndMoveFiles() throws IOException {
Path source = Paths.get(path1);
Path target = Paths.get(path2);
if (Files.notExists(target) && target != null) {
Files.createDirectories(Paths.get(target.toString()));
}
for (String fileInDirectory: Files.readAllLines(source.resolve(fileToRead))) {
Files.copy(source.resolve(fileInDirectory), target.resolve(fileInDirectory), StandardCopyOption.REPLACE_EXISTING);
}
}
How would I do a unit test on this? I have tried looking at mockito but it doesn't return anything or have anything I can assert. I read about JimFs, but for some reason, I can't grasp my head around that.
I don't think mocking is the right way to go here. Since you're code reads and writes files, you need a file system, and you need to assert its state at the end of the test.
I'd create temporary directories for source and target (e.g., using JUnit's TempDir). Then, you can set up various test cases in the source directory (e.g., it's empty, one file, nested directories, etc) and at the end of the test used java.io functionality to assert the files were copied correctly.
EDIT:
stub-by example of the concept:
class MyFileUtilsTest {
#TempDir
File src;
#TempDir
File dest;
MyFileUtils utils;
#BeforeEach
void setUp() {
utils = new MyFileUtils();
}
#Test
void copyAndMoveFiles() throws IOException {
// Create a file under src, initialize the utils with src and dest
File srcFile = File.createTempFile("myprefix", "mysuffix", src);
utils.copyAndMoveFiles();
File destFile = new File(dest, srcFile.getName());
assertTrue(destFile.exists());
}
}
I made a program for my employer, with one of the abilities being that non-software employees can change properties in several different parameter files. For example (something that isn't actually in the program), I put a "volume" parameter that the user can change in volume.txt.
However, it appears that when running the actual jar file, changing these values doesn't affect the program. Am I safe to assume that when I create the artifact, java builds the file into the jar file? I changed values for the parameter file in both source and the artifact production, but nothing changed. How should I fix this so that changes in the file will be read? Should I build the artifact without the files in the source folder and instead put them in the location of the executable jar? Thanks!
Properties files that can be edited by your users should be on a directory where your users have access to and where they cannot do much harm.
It is not clear in your question but i assume that the properties can be modified while your application is running. To detect file changes you can use a java.nio.file.WatchService.
I have created a small demo program for you. Hope this helps.
import java.io.IOException;
import java.nio.file.*;
import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY;
public class Main {
private static String WATCH_DIR = "c:/temp";
private static String WATCH_FILE_NAME = "volume.txt";
public static void main(String[] args) {
FileSystem fileSystem = FileSystems.getDefault();
try (final WatchService watchService = fileSystem.newWatchService()) {
fileSystem.getPath(WATCH_DIR).register(watchService, ENTRY_MODIFY);
while (true) {
final WatchKey watchKey = watchService.take();
for (WatchEvent<?> event : watchKey.pollEvents()) {
// "ENTRY_MODIFY" so context will be an instance of Path.
final Path changed = (Path) event.context();
if (changed.endsWith(WATCH_FILE_NAME)) {
System.out.println("Volume.txt was changed");
}
}
if (!watchKey.reset()) {
System.out.println("Key invalid");
}
}
} catch (IOException | InterruptedException e) {
System.out.println("Oops, something is not working");
e.printStackTrace();
}
}
}
I am trying to use resource bundle in my project. i am new for development. is it professional way to put property files inside src/ folder i mean inside jar.
Also i have tried by placing my propert [AppProp] outside of the src folder [/resources/properties/AppProp]. I have added Add Class Folder from build path eclipse. I am trying to run this in eclipse. But it says Can't find bundle for base name. Please see my below code. Please provide any suggestion.
public class PropertyReader {
private String bundleName = null;
ResourceBundle resourceBundle = null;
public PropertyReader(String bundle){
this.bundleName = bundle;
loadProperty();
}
public void loadProperty(){
try{
resourceBundle = ResourceBundle.getBundle(bundleName);
} catch(Exception e){
e.printStackTrace();
}
}
public static void main(String a[]){
try{
PropertyReader pr = new PropertyReader("resources/properties/AppProp");
} catch(Exception e){
e.printStackTrace();
}
}
}
You don't need to change the code. But make sure following
1) You are providing the correct file path.
2) File type must be .properties in your case it should be be like AppProp.properties
There are lot of techniques/standards to organize your source files and code.
But for now above points are the solution of your problem.
I have a simple java program to test Try with resource in java , I am getting the File Not Found error, The Program and file are in the same package, Can somebody tell me what directory does File with resource start to search with
public class LoadConfigFile {
public static String getProperty(String propertyName) {
String propertyValue = null;
try (InputStream in = new FileInputStream("Properties.properties")) {
Properties prop = new Properties();
prop.load(in);
propertyValue = prop.getProperty(propertyName);
} catch (IOException e) {
System.out.println("Error Reading Property File" + e.getMessage().toString());
}
return propertyValue;
}
}
Properties.properties
properties.one=1
properties.two=2
properties.three=3
properties.four=4
properties.five=5
Main.java
public class Main {
public static void main(String[] args) {
String s = LoadConfigFile.getProperty("property.one");
System.out.println(s);
}
}
Working directory for process, to get that in Java you can use
System.out.println(System.getProperty("user.dir"));
If you have file within a Java package you should not access it as file but as resource:
InputStream in = this.getClass().getResourceAsStream("Properties.properties");
If you look at the source code for the FileInputStream constructor, you'll see that it, in turn, invokes File's constructor.
And if you have a look at the documentation for File, you will find a good explanation of how the path string is interpreted.
In particular, notice the following snippet:
A pathname, whether abstract or in string form, may be either absolute
or relative. An absolute pathname is complete in that no other
information is required in order to locate the file that it denotes. A
relative pathname, in contrast, must be interpreted in terms of
information taken from some other pathname. By default the classes in
the java.io package always resolve relative pathnames against the
current user directory. This directory is named by the system property
user.dir, and is typically the directory in which the Java virtual
machine was invoked.
I already have a code that works, but I don't want it to actually delete the temp folder if possible. I am using the apache fileutils. Also does anyone know how to exclude folders from being deleted?
public class Cleartemp {
static String userprofile = System.getenv("USERPROFILE");
public static void main(String[] args) {
try {
File directory = new File(userprofile+"\\AppData\\Local\\Temp");
//
// Deletes a directory recursively. When deletion process is fail an
// IOException is thrown and that's why we catch the exception.
//
FileUtils.deleteDirectory(directory);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Here's an actually recursive method:
public void deleteDirectory(File startFile, FileFilter ignoreFilter) {
if(startFile.isDirectory())
for(File f : startFile.listFiles()) {
deleteDirectory(f, ignoreFilter);
}
if(!ignoreFilter.accept(startFile)) {
startFile.delete();
}
}
Hand it a file filter set to return true for directories (see below) to make it not delete directories. You can also add exceptions for other files too
FileFilter folderFilter = new FileFilter() {
#Override
public boolean accept(File paramFile) {
return paramFile.isDirectory();
}
};
How about FileUtils.cleanDirectory ? It cleans a directory without deleting it.
You could also use Apache Commons DirectoryWalker if you need some filtering logic. One of the examples on the page includes FileCleaner implementation.
Simple,
Use isDirectory() to exclude it from being deleted.
Refer here: http://docs.oracle.com/javase/1.4.2/docs/api/java/io/File.html#isDirectory()
First ever post, don't consider myself an expert but am stuck with 1.4...
Here's a recursive delete method that works well, deletes all files and subfolders within a parent folder then the parent folder itself, assumes the File being passed is a directory as it is in my case.
private void deleteTemp(File tempDir) {
File[] a = (tempDir.listFiles());
for (int i = 0; i < a.length; i++) {
File b = a[i];
if (b.isDirectory())
deleteTemp(b);
b.delete();
}
tempDir.delete();
}