Creating files with names from ArrayList [duplicate] - java

This question already has an answer here:
Java not creating file
(1 answer)
Closed 4 years ago.
I am looking for a way to make a bunch of empty txt files that would be named after elements of an ArrayList in Java.
Assuming that fList has "Apple", "Banana" and "Cherry", this piece of code should create Apple.txt, Banana.txt and Cherry.txt in the project directory.
Unfortunately, it does not, and I do not understand why. I assume it's a logic or syntax error.
public void ViewList() {
for (String fruits : fList) {
String fileName = fruits;
File f = new File(appDir + fileName + ".txt");
if (f.exists() && f.isFile()) {
System.out.println("Success!");
}
}
Can you help me understand what's wrong?

Everything is correct in your code except few lines.
for (String fruit : fList) {
//String fileName = fruits;
File file = new File(appDir + fruit + ".txt");
//OR if appDir doesn't end with `/` or `\` use
//File file = new File(appDir, fruit + ".txt");
// Create the file
if (file.createNewFile()) {
System.out.println("File is created!");
} else {
System.out.println("File already exists.");
}
}
Also You can refer this link for more info:
https://howtodoinjava.com/core-java/io/how-to-create-a-new-file-in-java/
Note: Please note it down, file path strategy will vary between windows and unix system. So create filepath according to that.

Related

How to create a tmp folder with specific name (without random number) in Java? [duplicate]

How do I create Directory/folder?
Once I have tested System.getProperty("user.home");
I have to create a directory (directory name "new folder" ) if and only if new folder does not exist.
new File("/path/directory").mkdirs();
Here "directory" is the name of the directory you want to create/exist.
After ~7 year, I will update it to better approach which is suggested by Bozho.
File theDir = new File("/path/directory");
if (!theDir.exists()){
theDir.mkdirs();
}
With Java 7, you can use Files.createDirectories().
For instance:
Files.createDirectories(Paths.get("/path/to/directory"));
You can try FileUtils#forceMkdir
FileUtils.forceMkdir("/path/directory");
This library have a lot of useful functions.
mkdir vs mkdirs
If you want to create a single directory use mkdir
new File("/path/directory").mkdir();
If you want to create a hierarchy of folder structure use mkdirs
new File("/path/directory").mkdirs();
Create a single directory.
new File("C:\\Directory1").mkdir();
Create a directory named “Directory2 and all its sub-directories “Sub2″ and “Sub-Sub2″ together.
new File("C:\\Directory2\\Sub2\\Sub-Sub2").mkdirs()
Source: this perfect tutorial , you find also an example of use.
For java 7 and up:
Path path = Paths.get("/your/path/string");
Files.createDirectories(path);
It seems unnecessary to check for existence of the dir or file before creating, from createDirectories javadocs:
Creates a directory by creating all nonexistent parent directories first. Unlike the createDirectory method, an exception is not thrown if the directory could not be created because it already exists.
The attrs parameter is optional file-attributes to set atomically when creating the nonexistent directories. Each file attribute is identified by its name. If more than one attribute of the same name is included in the array then all but the last occurrence is ignored.
If this method fails, then it may do so after creating some, but not all, of the parent directories.
The following method should do what you want, just make sure you are checking the return value of mkdir() / mkdirs()
private void createUserDir(final String dirName) throws IOException {
final File homeDir = new File(System.getProperty("user.home"));
final File dir = new File(homeDir, dirName);
if (!dir.exists() && !dir.mkdirs()) {
throw new IOException("Unable to create " + dir.getAbsolutePath();
}
}
Neat and clean:
import java.io.File;
public class RevCreateDirectory {
public void revCreateDirectory() {
//To create single directory/folder
File file = new File("D:\\Directory1");
if (!file.exists()) {
if (file.mkdir()) {
System.out.println("Directory is created!");
} else {
System.out.println("Failed to create directory!");
}
}
//To create multiple directories/folders
File files = new File("D:\\Directory2\\Sub2\\Sub-Sub2");
if (!files.exists()) {
if (files.mkdirs()) {
System.out.println("Multiple directories are created!");
} else {
System.out.println("Failed to create multiple directories!");
}
}
}
}
Though this question has been answered. I would like to put something extra, i.e.
if there is a file exist with the directory name that you are trying to create than it should prompt an error. For future visitors.
public static void makeDir()
{
File directory = new File(" dirname ");
if (directory.exists() && directory.isFile())
{
System.out.println("The dir with name could not be" +
" created as it is a normal file");
}
else
{
try
{
if (!directory.exists())
{
directory.mkdir();
}
String username = System.getProperty("user.name");
String filename = " path/" + username + ".txt"; //extension if you need one
}
catch (IOException e)
{
System.out.println("prompt for error");
}
}
}
Just wanted to point out to everyone calling File.mkdir() or File.mkdirs() to be careful the File object is a directory and not a file. For example if you call mkdirs() for the path /dir1/dir2/file.txt, it will create a folder with the name file.txt which is probably not what you wanted. If you are creating a new file and also want to automatically create parent folders you can do something like this:
File file = new File(filePath);
if (file.getParentFile() != null) {
file.getParentFile().mkdirs();
}
This the way work for me do one single directory or more or them:
need to import java.io.File;
/*enter the code below to add a diectory dir1 or check if exist dir1, if does not, so create it and same with dir2 and dir3 */
File filed = new File("C:\\dir1");
if(!filed.exists()){ if(filed.mkdir()){ System.out.println("directory is created"); }} else{ System.out.println("directory exist"); }
File filel = new File("C:\\dir1\\dir2");
if(!filel.exists()){ if(filel.mkdir()){ System.out.println("directory is created"); }} else{ System.out.println("directory exist"); }
File filet = new File("C:\\dir1\\dir2\\dir3");
if(!filet.exists()){ if(filet.mkdir()){ System.out.println("directory is created"); }} else{ System.out.println("directory exist"); }
if you want to be sure its created then this:
final String path = "target/logs/";
final File logsDir = new File(path);
final boolean logsDirCreated = logsDir.mkdir();
if (!logsDirCreated) {
final boolean logsDirExists = logsDir.exists();
assertThat(logsDirExists).isTrue();
}
beacuse mkDir() returns a boolean, and findbugs will cry for it if you dont use the variable. Also its not nice...
mkDir() returns only true if mkDir() creates it.
If the dir exists, it returns false, so to verify the dir you created, only call exists() if mkDir() return false.
assertThat() will checks the result and fails if exists() returns false. ofc you can use other things to handle the uncreated directory.
This function allows you to create a directory on the user home directory.
private static void createDirectory(final String directoryName) {
final File homeDirectory = new File(System.getProperty("user.home"));
final File newDirectory = new File(homeDirectory, directoryName);
if(!newDirectory.exists()) {
boolean result = newDirectory.mkdir();
if(result) {
System.out.println("The directory is created !");
}
} else {
System.out.println("The directory already exist");
}
}
Here is one attractiveness of the java, using Short Circuit OR '||', testing of the directory's existence along with making the directory for you
public File checkAndMakeTheDirectory() {
File theDirectory = new File("/path/directory");
if (theDirectory.exists() || theDirectory.mkdirs())
System.out.println("The folder has been created or has been already there");
return theDirectory;
}
if the first part of the if is true it does not run the second part and if the first part is false it runs the second part as well
public class Test1 {
public static void main(String[] args)
{
String path = System.getProperty("user.home");
File dir=new File(path+"/new folder");
if(dir.exists()){
System.out.println("A folder with name 'new folder' is already exist in the path "+path);
}else{
dir.mkdir();
}
}
}

(Processing / Java) Converting a singular file function into a function that takes an array

I am trying to create a program that uploads multiple files and stores their name and BPM tag into an ArrayList ready for comparison between the files. I have found two functions to help me but I am unable to combine them to get the function that I need.
The first function takes a singular mp3 file and outputs its data into the console (using mp3agic library):
File file = new File(dataPath("") + "/Song.mp3");
Mp3File mp3file = new Mp3File(file.getPath());
if (mp3file.hasId3v2Tag()) {
ID3v2 id3v2Tag = mp3file.getId3v2Tag();
println("Track: " + id3v2Tag.getTrack());
println("Artist: " + id3v2Tag.getArtist());
println("BPM: " + id3v2Tag.getBPM());
println("Album artist: " + id3v2Tag.getAlbumArtist());
}
The second function takes a data path and outputs the directory containing the names and info of the files in the folder
void setup() {
String path = "Desktop/mp3folder";
println("Listing all filenames in a directory: ");
String[] filenames = listFileNames(path);
printArray(filenames);
println("\nListing info about all files in a directory: ");
File[] files = listFiles(path);
for (int i = 0; i < files.length; i++) {
File f = files[i];
println("Name: " + f.getName());
println("Is directory: " + f.isDirectory())
println("-----------------------");
}
}
// This function returns all the files in a directory as an array of Strings
String[] listFileNames(String dir) {
File file = new File(dir);
if (file.isDirectory()) {
String names[] = file.list();
return names;
} else {
// If it's not a directory
return null;
}
}
// This function returns all the files in a directory as an array of File objects
// This is useful if you want more info about the file
File[] listFiles(String dir) {
File file = new File(dir);
if (file.isDirectory()) {
File[] files = file.listFiles();
return files;
} else {
// If it's not a directory
return null;
}
}
The function I am trying to create combines the two. I need the Artist, Track and BPM from the first function to work with an array list of files from a directory.
Any guidance would be appreciated. Any advice on another way to go about it would also be appreciated.
One way to approach this is to use classes to encapsulate the data you want to track.
For example, here's a simplified class that contains information about artist, track, and bpm:
public class TrackInfo{
private String artist;
private String track;
int bpm;
}
I would also take a step back, break your problem down into smaller steps, and then take those pieces on one at a time. Can you create a function that takes a File argument and prints out the MP3 data of that File?
void printMp3Info(File file){
// print out data about file
}
Get that working perfectly before moving on. Try calling it with hard-coded File instances before you try to use it with an ArrayList of multiple File instances.
Then if you get stuck, you can post a MCVE along with a specific technical question. Good luck.

Odd Bug , using File.RenameTo()

I have a program in which i must rename a set of folders. they are all in "ID [Name]" format, and I want to rename them to "Name [ID]". (Its more of a training for me, for learning java))
the problem is, if the number of folders it must rename go beyond 20-24 . the program won't work, and will give the files faulty names. (the renaming process succeeds, but names are wrong)
but if they are below 20 folders, it works perfectly.(tested with the same folders)
here's the whole code:
public class DirRename {
private String parentDir;
private DirectoryStream<Path> fileList;
public DirRename(final Path dir)
{
parentDir = dir.toString();
if(!Files.exists(dir) || !Files.isDirectory(dir) || !Files.isReadable(dir))
System.out.println("Directory Read Error!!!");
//filter to return only directories in parent folder
DirectoryStream.Filter<Path> dirOnlyFilter =
new DirectoryStream.Filter<Path>() {
public boolean accept(Path file) throws IOException {
return (Files.isDirectory(file));
}
};
try
{
fileList = Files.newDirectoryStream(dir,dirOnlyFilter);
}
catch(IOException | DirectoryIteratorException x)
{
System.err.println(x);
}
}
public void rename()
{
for(Path filepath : fileList)
{
String name = filepath.getFileName().toString();
File inFile = filepath.toFile();
if(!inFile.exists() || !inFile.isDirectory() || !inFile.canWrite())
{
System.out.println("Directory is not writeable");
return;
}
Pattern regex = Pattern.compile("((?:[\\w\\d]*(?:\\s|-){0,2}[\\w\\d]+)*)\\s*-*\\s*(?:\\[|\\Q(\\E)(.+)(?:\\]|\\Q)\\E)$");
Matcher match = regex.matcher(name);
while(match.find())
{
String gameID = match.group(1);
String gameName = match.group(2);
String rename = parentDir+File.separator+gameName+" ["+gameID+"]";
File toFile = new File(rename);
if(!Paths.get(rename).isAbsolute())
{
System.out.println("Cannot rename "+name+"to "+rename);
return;
}
if(inFile.renameTo(toFile))
System.out.println("Success!");
else
System.out.println("Renaming Failed!!! for "+rename);
}
}
}
}
I tried checking the names with "system.out.println(toFile.getName())" while deleting the line "inFile.renameTo(toFile)". all names were correct.
but when i added that line back, the same names were printed incorrectly.(although some that were printed correctly were renamed incorrectly)
I'm completely confused. and I'm new to java, and generally less than a noob programmer. can someone please tell me what's going on?
Many thanks
EDIT: I found the problem.the loop:
for(Path filepath : fileList){}
runs 116 times while i only have 64 folders. I can't find any explanation as to why this happens, I use the same loop to print folder names only in the following function and it runs exactly 64 times.( exactly the number of folders I have)
public void printFolders()
{
for(Path filepath : fileList)
System.out.println(filepath.getFileName());
}
okay I finally Fixed my own problem. here's my guess on why this happened (I don't know the inner working of DirectoryStream so its just a guess).
when the folders were more than a few, the stream would read the previously renamed folders and add them as new folders, thus they were getting renamed twice. either changing the name back to original, or deforming it (the renaming wasn't designed to be 100% re-applicable).
In case of a few folders, the loop would be over before the stream had the chance to refresh, thus no problems.
so here's how i fixed it. by adding the following method, and iterating through an array of paths instead of the stream.
private Path[] getVerifiedPaths()
{
ArrayList<Path> verifiedFilePaths= new ArrayList<>();
for(Path filepath : fileList)
verifiedFilePaths.add(filepath);
return verifiedFilePaths.toArray(new Path[0]);
}
Path[] filePaths = getVerifiedPaths();
for(Path filePath : filePaths) { ...rename...}
instead of:
for(Path filepath : fileList){...rename...}
thanks to "JB Nizet" for his suggestion (comment above).

IO file attributes

import java.io.File;
class AttriDemo{
public static void main(String args[]){
File f1 = new File("FileIO/file.txt");
System.out.println("File name : " + f1.getName());
System.out.println("File path : " + f1.getPath());
System.out.println("File AbsPath : " + f1.getAbsolutePath());
System.out.println("File parent : " + f1.getParent());
f1.setWritable(true);
if(f1.canWrite())
{
System.out.println("File is Writeable");
}
else
{
System.out.println("File is not Writeable");
}
if(f1.canRead())
{
System.out.println("Is readable");
}
else
{
System.out.println("File is not readable");
}
}
}
I the file is readable and writable in real...
then I tried setting it to Writable explicitly but still the output shows it as the file is not writable!!
output:
....
The file is not writable.
The file is not readable.
File f1 = new File("D:/javaProgs/FileIO/AttriDemo.java");
doing this helps solve the problem.
but can someone explain how? I mean the file was in the same directory and the statements above were running just fine. e.g getName() getParent()
What's fooling you is you can create a File object regardless of the path you specified exists or not and you can call all those getParent, getPath functions on that object.
You can create a File object that's not backed by a real file for various reasons like to check if it exists or to create a file specified by that objects path and name.
You can use File.exists() to see if file really exists on file system.

Creating a directory within another directory in user.home?

I was just wondering if the code I made will work to create multiple directories within each other. I used this as a reference.
String username = enterUserTF.getText(); //the username the user enters in a textfield.
boolean myGamesFolderSuccess = new File(System.getProperty("user.home"), "My Games").mkdir();
boolean mainFolderSuccess = new File("My Games", "Type King").mkdir();
boolean userSuccess = new File("TypeKing", username).mkdir(); //creates a folder with the users username.
if(myGamesFolderSuccess){
if(mainFolderSuccess){
if(userSuccess){
System.out.println("Directory " + username + " created.");
File f = new File(username + "/test.txt");
if(!f.exists()){
try {
f.createNewFile();
} catch (IOException e) {
e.printStackTrace();
System.out.println("Could not create user's file.");
}
}
}
}
}
}
So to sum up the above, I made the the first directory "My Games" in user.home, then placed my game's name, "Type King" in that directory, and whenever the user enters a username, I want a directory to be created that is their username. File f just checks for a file in the username directory.
It is recommended to use the mkdirs method of the File class instead of checking multiple status flags when creating nested directories. Also, never use concatenation for creating File objects/paths.
Also, if you want your game to be portable, make sure you don't have special characters in your directory names like a space etc.Why are you asking user for the name instead of retrieving it from user.name system property? Something like this should work:
String username = System.getProperty("user.name");
File myGamesDir = new File(System.getProperty("user.home"), "my-games");
File typeKingDir = new File(myGamesDir, "type-king");
File userDir = new File(typeKingDir, username);
boolean userSuccess = userDir.mkdirs();
if(userSuccess){
System.out.println("Directory " + username + " created.");
File f = new File(userDir, "test.txt");
if(!f.exists()){
try {
f.createNewFile();
} catch (IOException e) {
e.printStackTrace();
System.out.println("Could not create user's file.");
}
}
}
 
If you pass a full path to File.mkdirs (with an s) it will make an arbitrarily deep directory structure. You don't have to build paths one directory at a time. If the directories already exist, or if some of them exist, it will still work as you expect.
import java.io.File;
import javax.swing.JOptionPane;
class Dirs {
public static void main(String[] args) throws Exception {
String subDir = "My Games|Type King";
String userName = JOptionPane.showInputDialog(
null,
"Who are you?");
subDir += "|" + userName;
String[] parts = subDir.split("\\|");
File f = new File(System.getProperty("user.home"));
for (String part : parts) {
f = new File(f, part);
}
boolean madeDir = f.mkdirs();
System.out.println("Created new dir: \t" + madeDir + " \t" + f);
f = new File(f, "eg.txt");
if (!f.exists()) {
boolean madeFile = f.createNewFile();
System.out.println(
"Created new file: \t" + madeFile + " \t" + f );
}
}
}
Output
Created new dir: true C:\Users\Andrew\My Games\Type King\BilboBaggins
Created new file: true C:\Users\Andrew\My Games\Type King\BilboBaggins\eg.txt
I think its better to use existing functionality available in the API. If you don't have any restrictions consider switching to the latest JDK. In 1.7 Oracle did introduce so many enhancements including IO and New IO.
For creating multiple directories within each other you can take advantage of Files.createDirectories available since 1.7. "It will create a directory by creating all nonexistent parent directories first."

Categories

Resources