I am currently creating a directory based on file names and then moving the files into the new directories. At the moment i am creating the new directories fine using the following code:
String filename = filesInFolder.get(i).toString();
File fullPathFile = new File(filename.replaceAll("(\\w+)_(\\d+).*", "$1/$2/$0"));
fullPathFile.getParentFile().mkdirs();
Then i am trying to use InputStream and OutputStream to move the files to the new directories, the code is ok it seems but when i create the new directories, all the folders are set to read-only so i cannot move the files into the knew directories
So is there a way to set the folders to read-write when they are created?
I believe fullPathFile.getParentFile().setWritable(true) before calling mkdirs() should do.
The method setWritable (bool) is a convenience method to set the owner's write permission for this abstract pathname. Since is a File, you can apply it.
Related
So I have a project, and this is one of the demands:
You should have a class named Project3, containing a main method.
This program reads the levels information from a file whose name is
specified as a command-line parameter (The file should also be
relative to the class-path as described here:)
All the file names specified in the levels and block definition files
should be relative to the class path. The reason we want them to be
relative to the class path is that later we will be able to read the
files from inside a jar, something we can not do with regular File
references.
To get an input stream relative to the class path (even if it's inside
a jar), use the following:
InputStream is =
ClassLoader.getSystemClassLoader().getResourceAsStream("image.png");
The idea is to keep a folder with files(definitions and images) and
then add that folder to the class path when running the JVM:
java -cp bin:resources ... If you don't add the resources folder to
you class path you wont be able to load them with the command from
above.
When run without parameters, your program should read a default level
file, and run the game accordingly. The location of the default level
file should be hard-coded in your code, and be relative to the
classpath_.
When run without parameters, your program should read a default level file, and run the game accordingly. The location of the default level file should be hard-coded in your code, and be relative to the classpath_.
The part of the code that handles the input is:
public Void run() throws IOException {
LevelReader level = new LevelReader();
List<level> chosenLevels = new ArrayList<>();
if (args.length >= 1) {
File f = new File(args[0]);
if (f.exists()) {
chosenLevels = level.makeLevel(args[0]);
}
}
if (chosenLevels.size() == 0) {
game.runLevels(defaultLevels);
} else {
game.runLevels(chosenLevels);
}
return null;
}
So my question is:
An argument should be the full path of a file which means:
D:\desktop\level3.txt
Is it possible to read a file from every location on my computer?
Because right now I can do it only if my text file is in the
project's directory (not even in the src folder).
I can't understand the rest of their demands. What does is mean "should be hard-coded in your code, and be relative to the
classpath_." and why is it related to InputStream method(?)
I'm confused all over this.
Thanks.
A classpath resource is not the same as a file.
As you have correctly stated, the full path of a file is something like D:\desktop\level3.txt.
But if ever want to distribute your application so it can run on other computers, which probably won’t have that file in that location, you have two choices:
Ask the user to tell the program where to find the file on their computer.
Bundle the file with the compiled program.
If you place a non-.class file in the same place as .class files, it’s considered a resource. Since you don’t know at runtime where your program’s class files are located,¹ you use the getResource or getResourceAsStream method, which is specifically designed to look in the classpath.
The getResource* methods have the additional benefit that they will work both when you are developing, and when the program is packaged as a .jar file. Individual entries in a .jar file are not separate files and cannot be read using the File or FileInputStream classes.
If I understand your assignment correctly, the default level file should be an application resource, and the name of that resource is what should be hard-coded in your program. Something like:
InputStream is;
if (args.length > 0) {
is = new BufferedInputStream(
new FileInputStream(args[0]));
} else {
// No argument provided, so use program's default level data.
is = ClassLoader.getSystemClassLoader().getResourceAsStream("defaultlevel.txt");
}
chosenLevels = level.makeLevel(is);
¹ You may find some pages that claim you can determine the location of a running program’s code using getProtectionDomain().getCodeSource(), but getCodeSource() may return null, depending on the JVM and ClassLoader implementation, so this is not reliable.
To answer your first question, it doesn't seem like they're asking you to read from anywhere on disk, just from within your class path. So that seems fine.
The second question, "What does is mean 'should be hard-coded in your code, and be relative to the classpath'?". You are always going to have a default level file in your project directory. Define the path to this file as a String in your program and that requirement will be satisfied. It's related to the InputStream because the stream requires a location to read in from.
My app needs to get an existing file for processing. Now I have the path of the file in String format, how can I get the File with it? Is it correct to do this:
File fileToSave = new File(dirOfTheFile);
Here dirOfTheFile is the path of the file. If I implement it in this way, will I get the existing file or the system will create another file for me?
That's what you want to do. If the file exists you'll get it. Otherwise you'll create it. You can check whether the file exists by calling fileToSave.exists() on it and act appropriately if it does not.
The new keyword is creating a File object in code, not necessarily a new file on the device.
I would caution you to not use hardcoded paths if you are for dirOfFile. For example, if you're accessing external storage, call Environment.getExternalStorageDirectory() instead of hardcoding /sdcard.
The File object is just a reference to a file (a wrapper around the path of the file); creating a new File object does not actually create or read the file; to do that, use FileInputStream to read, FileOutputStream to write, or the various File helper methods (like exists(), createNewFile(), etc.) for example to actually perform operations on the path in question. Note that, as others have pointed out, you should use one of the utilities provided by the system to locate directories on the internal or external storage, depending on where you want your files.
try this..
File fileToSave = new File(dirOfTheFile);
if(fileToSave.exists())
{
// the file exists. use it
} else {
// create file here
}
if parent folder is not there you may have to call fileToSave.getParentFile().mkdirs() to create parent folders
This is the problem I have: If part or all of the path does not already exist, the server should create additional directories as necessary in the hierarchy and then create a new file as above.
Files.createDirectories(path);
That's what I am currently using, but it does not create the end file. For example is the path="/hello/test.html" it will create a directory called "hello" and one called "test.html", I want the test.html to be a file. How can I do that?
This is what I did to solve this "problem" or misuse of the libraries.
Files.createDirectories(path.getParent());
Files.createFile(path);
The first line will get the parent directory, so lets say this is what I want to create "/a/b/c/hello.txt", the parent directory will be "/a/b/c/".
The second like will create the file within that directory.
Have you looked at the javadoc? createDirectories only creates... directories. If you're intent on using Files.createDirectories, parse off the file name, call createDirectories passing only the path portion, then create a new file passing the entire path. Otherwise this is a better approach.
Files.createDirectories(path.substring(0, path.lastIndexOf(File.separator)+1));
File yourFile = new File(path);
you can parse the 'path' variable to isolate the file and the directory using delimiter as '/', and do File file = new File(parsedPath); This would work only when you know that you ALWAYS pass the file name at the end of it.
If you know when you are a) creating a directory b) creating a directory and file, you can pass the boolean variable that would describe if file needs to be created or not.
Is it possible to create directory in directory. To create one directory simply call this:
File dir1 = getDir("dir1",Context.MODE_PRIVATE);
But how to create other directory in dir1 ?
this:
File dir2 =getDir("dir1"+"/"+"dir2",Context.MODE_PRIVATE);
throw exception:
File dirFile = java.lang.IllegalArgumentException: File app_dir1/dir2 contains a path separator
Thanks.
The Context.getDir() appears to be an Android-unique method for abstracting out the process of creating a directory within the private storage area - it is not a generic way of making directories in general.
To make your child subdirectory, you should use normal java methods, such as
File dir2 =new File(dir1, "dir2").mkdir();
Note that the first parameter here is the File Object representing the first directory you created, not the name.
You may want to subsequently set the permissions on this directory.
warning: untested
File testDir = new File("C:\temp\test");
testDir.createNewFile();
As I understand it, the above will create a directory called test in the directory c:\temp
File testDir = new File("C:\temp\test.dir");
testDir.createNewFile();
As I understand it, the above will create a file called test.dir in the directory c:\temp
What should I be doing to the code above if I wish for test.dir to actually be a directory?
No, the first one will create a regular file - after all, that's what you asked it to do:
Atomically creates a new, empty file named by this abstract pathname if and only if a file with this name does not yet exist. The check for the existence of the file and the creation of the file if it does not exist are a single operation that is atomic with respect to all other filesystem activities that might affect the file.
Nothing there says it will create a directory. You'll want to escape the backslashes though, or it's trying to find C:<tab>emp<tab>est
If you want to create a directory, use File.mkdir or File.mkdirs(). You'll still need to escape the backslashes:
File testDir = new File("C:\\temp\\test.dir");
bool created = testDir.mkdir();
(Use mkdirs to create parent directories as well.) The return value tells you whether or not it actually created a directory.
That's not true.
File.createFile() will create a file.
File.mkdir() creates a directory.
http://download.oracle.com/javase/6/docs/api/java/io/File.html
File testDir = new File("C:\temp\test");
testDir.createNewFile();
As I understand it, the above will
create a directory called test in the
directory c:\temp
Wrong - it will create file called "test". Files do not have to have a "filename extension".
To create a directory:
testDir.mkdir();
BTW, this kind of question is most easily and quickly answered by looking at the API doc. Do yourself a favor and get familiar with it.