I'm trying to see how many of these text files exist, but even with them there, the program always says the numFiles = 0. I have the files in a folder called Levels within the src folder. Thanks
int numFiles = 0;
for(int i = 0; i < 24; i++){
File file = new File("/Levels/level" + (i+1) + ".txt");
if(file.exists()){
numFiles++;
}
}
System.out.println(numFiles);
Edited
I overlooked that DirectoryStream doesn't support count()
You could go with an absolute path and make use of Stream API and lambdas. Like so:
String dirString = "..." //absolute Path
Path dir = Paths.get(dirString);
int numFiles = dir.getNameCount();
System.out.println(numFiles);
One advantage is that you can rename the files at will as long as they stay in the same directory. If you only want to work with specific files you can use filter() like so:
Files.newDirectoryStream(dir).filter(Predicate);
or add the filter directly when creating the DirectoryStream like so:
Files.newDirectoryStream(dir, RegEx);
To do something with each File you can use the consumer forEach() or have a look at Stream JavaDoc for other consumers/intermediate operations. Also double check if the DirectoryStream supports the Stream operation you want to use.
Your path is incorrect - if you are referring to an absolute location only then start with a /.
Also if you are using an editor remember your Java files are in src but but you don't run Java File you run class files and the class files may be in your bin/build directory most likely - check if the text file are in the build or bin directory.
Your path is incorrect, if you are referring to a local file(like something in your project folder) use
File file = new File("Levels/level" + (i+1) + ".txt");
the slash you used in front of the name makes it look in the root of the drive, not the local directory.
Related
I am working on a Java project, which runs fine on Windows 10, but when I tested it in Ubuntu, it shows
"AWT-EventQueue-0" java.lang.NullPointerException: Cannot read the array length because "allFiles" is null.
I read this answer, but could not find a fix.
What I am doing in the project is load an array of images from a certain path. Here is the faulty part of my code:
BufferedImage[] allImages;
public ImageArray(String set, int n) {
File path = new File("res/mnist_png/" + set + "/" + n);
File[] allFiles = path.listFiles();
allImages = new BufferedImage[allFiles.length];
JLabel label[] = new JLabel[allFiles.length];
for (int i = 0; i < allFiles.length; i++) {
try {
allImages[i] = ImageIO.read(allFiles[i]);
label[i] = new JLabel();
ImageIcon icon = new ImageIcon(allImages[i]);
I tried removing the variable allFiles and replacing its use with the actual code it holds but with no success. I saw in the previously answered that the use of the new / this keywords could fix the issue, but I don't seem to be able to find if and where to use them.
I printed the value of the allFiles and path.listFiles() and it is indeed null. Is there a way for the program to work if they remain null? Would changing the null somehow break their intended work?
As I mentioned, the problem occurs only on Linux, but works fine on Windows. Some help would be much appreciated.
First problem: You are using a relative file name. Relative file names have a different meaning depending on the current working directory of the Java process. This is not a Java concept; each process in a system has had its own current directory since long before Java existed.
Second problem: You are trying to list application resources. If you ever choose to package your application as a .jar file, this will not work, because a .jar is a single archive file; the data inside it is all part of one file and they do not constitute actual files.
Relative file names
Any file that does not start with a directory separator (/ on most systems, or optionally \ in Windows) is a relative file name. The actual file location that relative file name refers to depends on the current directory of the Java process. All programs, not just Java programs, work this way.
Some examples:
File name Current directory Actual file location
--------- ----------------- --------------------
res/mnist_png/A/1/image01.png /home/gosho09/project /home/gosho09/project/res/mnist_png/A/1/image01.png
mnist_png /home/gosho09/project /home/gosho09/project/mnist_png
mnist_png / /mnist_png
/home/gosho09/project/res /tmp /home/gosho09/project/res
/home/gosho09/project/res /home/gosho09 /home/gosho09/project/res
/home/gosho09/project/res /usr/local/bin /home/gosho09/project/res
/var/log /tmp /var/log
/var/log /home/gosho09 /var/log
/var/log /usr/local/bin /var/log
As you can see, if the file name does not start with a /, it is relative, and the current directory determines the actual location.
If the file name starts with /, it is considered an absolute file name. Absolute file names are not affected by the current directory.
However… you should not use file names at all.
If you ever want to distribute your application, you will most likely want it to be packaged as a .jar file. A .jar file is a single archive file which contains compiled classes, and application resource files, like your image sets.
Because a .jar file is an archive (it’s actually a specialized zip file), the entries inside it are just parts of the archive, in compressed form. They are not individual files, just sequences of bytes. You cannot read them with the File class.
Fortunately, there is a way to read application resources, which will work both when your application is packaged as a .jar file, and when it exists as regular .class files and data files: the Class.getResource method.
A typical usage might look like this:
String path = "/mnist_png/" + set + "/" + n + "/image" + i + ".png");
URL imageLocation = ImageArray.class.getResource(path);
if (imageLocation == null) {
throw new RuntimeException("Missing resource \"" + path + "\"");
}
allImages[i] = ImageIO.read(imageLocation);
You may be wondering how one is supposed to list files without the File class. The answer is: You can’t and you shouldn’t.
By design, application resources cannot be listed. This is because they are not guaranteed to be listable. Resources are loaded by ClassLoaders, and ClassLoaders may or may not read from directories or from .jar files.
(In fact, the Java SE runtime no longer includes its core classes as a .jar file; as a result, third party tools which used to assume those classes would be available as a .jar file had to be rewritten. Java did not pull the rug out from under those tools’ developers; it was never considered safe to assume classes would come from .jar files, and those developers chose not to heed that warning.)
The alternative to listing the resources is to include a resource which contains a list of the known resource paths. It’s your application; you know what’s in it. So just write a simple plain text listing, include it in your application, and read from that:
String root = "/mnist_png/" + set + "/" + n + "/";
String listingPath = root + "image-list.txt";
try (BufferedReader listing = new BufferedReader(
new InputStreamReader(
Objects.requireNonNull(
ImageArray.class.getResourceAsStream(listingPath),
"Missing resource \"" + listingPath + \""),
StandardCharsets.UTF_8))) {
List<JLabel> labelList = new ArrayList<>();
String path;
while ((path = listing.readLine()) != null) {
URL imageLocation = ImageArray.class.getResource(root + path);
if (imageLocation == null) {
throw new RuntimeException(
"Missing resource \"" + root + path + "\"");
}
labelList.add(new JLabel(new ImageIcon(imageLocation)));
}
labels = labelList.toArray(new JLabel[0]);
}
I'm uploading images using Spring and Hibernate. I'm saving images on the server as follows.
File savedFile = new File("E:/Project/SpringHibernet/MultiplexTicketBooking/web/images/" + itemName);
item.write(savedFile);
Where itemName is the image file name after parsing the request (enctype="multipart/form-data"). I however need to mention the relative path in the constructor of File. Something like the one shown below.
File savedFile = new File("MultiplexTicketBooking/web/images/" + itemName);
item.write(savedFile);
But it doesn't work throwing the FileNotFoundException. Is there a way to specify a relative path with File in Java?
Try printing the working directory from your program.
String curDir = System.getProperty("user.dir");
Gets you that directory. Then check if the directories MultiplexTicketBooking/web/images/ exist in that directory.
Can't count the number of times I've been mistaken about my current dir and spent some time looking for a file I wrote to...
It seems the server should offer functionality as might be seen in the methods getContextPath() or getRealPath(String). It would be common to build paths based on those types of server related and reproducible paths. Do not use something like user.dir which makes almost no sense in a server.
Update
ServletContext sc=request.getSession().getServletContext();
File savedFile = new File(sc.getRealPath("images")+"\\" + itemName);
Rather than use "\\" I'd tend to replace that with the following which will cause the correct file separator to be used for each platform. Retain cross-platform compatibility for when the client decides to swap the MS/ISS based server out for a Linux/Tomcat stack. ;)
File savedFile = new File(sc.getRealPath("images"), itemName); //note the ','
See File(String,String) for details.
You could get the path of your project using the following -
File file = new File("");
System.out.println("" + file.getAbsolutePath());
So you could have a constants or a properties file where you could define your path which is MultiplexTicketBooking/web/images/ after the relative path.
You could append your path with the path you get from file.getAbsolutePath() and that will be the real path of the file. - file.getAbsolutePath() + MultiplexTicketBooking/web/images/.
Make sure the folders after the Project path i.e. MultiplexTicketBooking/web/images/ exist.
You can specify the path both absolute and relative with File. The FileNotFoundException can be thrown because the folder might be there. Try using the mkdirs() method first in to create the folder structure you need in order to save your file where you're trying to save it.
Is it possible to move to a directory one level down in Java?
For example in command prompt:
C:\Users\foo\
I can use cd.. to go to:
C:\Users\
Is it possible to do this in Java, because I'm getting a directory using System.getProperty("user.dir"); however that is not the directory I'd want to work at, but rather 1 level down the directory.
I have thought of using the Path class method; subpath(i,j), but if the "user.dir" were to be changed to another directory, then the returned subpath would be different.
The File class can do this natively.
File upOne = new File(System.getProperty("user.dir")).getParentFile()
http://docs.oracle.com/javase/6/docs/api/java/io/File.html#getParentFile%28%29
On my system, the ".." is a valid component of a path.
Here is an example.
File file;
String userDir = System.getProperty("user.dir");
file = new File(userDir);
System.out.println(file.getCanonicalPath());
file = new File(userDir+"/..");
System.out.println(file.getCanonicalPath());
Output is:
C:\ano\80g\workaces\_JAV_1.0.0\CODE_EXAMPLE
C:\ano\80g\workaces\_JAV_1.0.0
As the previous answers have pointed out, you can do this using File. Alternatively, using the Java 7 NIO classes, as you appear to be doing, the following should do the same:
Paths.get(System.getProperty("user.dir") + "/..").toRealPath();
Note that "/" is a valid directory separator on the Windows file system as well (though I tested this code on Linux).
private static void downDir(int levels) {
String oldPath = System.getProperty("user.dir");
String[] splitedPathArray = oldPath.split("/");
levels = splitedPathArray.length - levels;
List<String> splitedPathList = Arrays.asList(splitedPathArray);
splitedPathList = splitedPathList.subList(0, levels);
String newPath = String.join("/", splitedPathList);
System.setProperty("user.dir", newPath);
}
Should work. For the levels, just specify 1.
This question has been brought up before, and I have searched many of the answers. It always ends in "You want getResourceAsStream". This is not what I am looking for.
My issue is , for a game object, I am using a folder structure to keep sprite strips rather than having one large sprite. This results in :
Media/
CharacterName/
AnimationName/
image.extension
the programming object just holds it's folder as a string, and I pass the getResource() URL to an object to fill the map of images. there can be {n} number of AnimationName/ sub directories. My error comes from this code:
dir = new File(s.toURI());
I take the directory, and call listFiles and pass the file names found to the sprite loader. Here is a code snippet:
dir = new File(s.toURI());
File[] chld = dir.listFiles();
//get a list of files in the image/character folder
for(File f:chld)
{
//get a list of the files for each dir
File[] grandChild = f.listFiles();
for(File t:grandChild)
{
String fname = t.getAbsolutePath();
System.out.println(fname);
String temp = fname;
temp = temp.substring(temp.lastIndexOf("/") + 1,temp.lastIndexOf("."));
String animName = temp.replaceAll("\\d*$", "");
int numPics = 0;
Pattern p = Pattern.compile("[0-9]+");
Matcher m = p.matcher(temp);
while(m.find()){
numPics = Integer.parseInt(m.group());
}
System.out.println("animation name: " + animName);
System.out.println("file name: " + fname);
System.out.println("number of pictures: " + numPics);
Animations.put(animName, sl.loadStripImageArray(fname, numPics));
}
}
Excuse the poor naming and temp variables, it's still being worked on.
sl is the sprite loader, and Animations is a hash map. This works fine until I package the project. I don't want to write a bunch of convoluted code that only works if I have a jar file, and not when I'm working in netbeans with the source folders.
I have considered having an application data folder, but I'd like to stay with a jar package if I can.
You do still want to use getResourceAsStream. Nothing here requires that all resources must be kept at the same folder within the JAR. You can use relative paths, or absolute paths to the root of the JAR by prefixing your path with /.
You can't make File work with resources within the JAR - even if instantiated with a URL that points to a resource contained within a JAR.
You may have to rework some other things, as the classpath is not really meant to be enumerated against (as you're currently listing files from the parent directory). It is designed to retrieve a resource by name. So one possibility (that I would recommend) is to have a "manifest" file that contains the files you want to load from each directory. (Read this file, then load the additional resources by name.)
Alternatively, if you can find the name of the JAR file you're loading from, you can create a Jarfile from it, then call its entries() method to find all of the contained resources. But even then, they aren't returned in a "tree structure", so ideally, you'd read this one, create your own tree structure from it (possibly as a series of Maps), then use it to retrieve the "directory listings" as needed.
If you are absolutely sure that the sprites are located in a jar - you could try using the JarFile class. There is a method entries. I didn't try it but it seems to return all resources located in the whole jar file. You would have to filter out which resources are in the right path.
I'm trying to save a file in a subdirectory in Android 1.5.
I can successfully create a directory using
_context.GetFileStreamPath("foo").mkdir();
(_context is the Activity where I start the execution of saving the file) but then if I try to create a file in foo/ by
_context.GetFileStreamPath("foo/bar.txt");
I get a exception saying I can't have directory separator in a file name ("/").
I'm missing something of working with files in Android... I thought I could use the standard Java classes but they don't seem to work...
I searched the Android documentation but I couldn't fine example and google is not helping me too...
I'm asking the wrong question (to google)...
Can you help me out with this?
Thank you!
I understood what I was missing.
Java File classes works just fine, you just have to pass the absolute path where you can actually write files.
To get this "root" directory I used _context.getFilesDir(). This will give you the root of you application. With this I can create file with new File(root + "myFileName") or as Sean Owen said new File(rootDirectory, "myFileName").
You cannot use path directly, but you must make a file object about every directory.
I do not understand why, but this is the way it works.
NOTE: This code makes directories, yours may not need that...
File file = context.getFilesDir();
file.mkdir();
String[] array = filePath.split("/");
for (int t = 0; t < array.length - 1; t++) {
file = new File(file, array[t]);
file.mkdir();
}
File f = new File(file, array[array.length - 1]);
RandomAccessFileOutputStream rvalue = new RandomAccessFileOutputStream(f, append);
Use getDir() to get a handle on the "foo" directory as a File object, and create something like new File(fooDir, "bar.txt") from it.