I'm trying to create a list of files in my sdcard (and then get a random one from this list).
I've read tutorials but none of those worked.
My code is as following:
try{
File file=new File("/sdcard");
File[] list = new File ("/sdcard").listFiles();
ArrayList<String> lista = new ArrayList<String>();
for (File f : list){
if (f.isFile()){
if (f.getName().startsWith("aa")){
lista.add(f.getName());
}
}
}
Random gen = new Random();
String s = lista.get(gen.nextInt(lista.size()-1)).toString();
wyswietl.setText(s);
}catch(NullPointerException e){
Log.e("nope", e.getMessage());
}
LogCat shows exceptions.
I've checked every single line - when I try to show lista.size() - it throws ResourcesNotFoundException.
What interesting is, changing String s into
String s = lista.get(1).toString()
works - it shows me one of the files in the folder.
So my question is: how can I fix this and get a list of files (which start with "aa") in /sdcard folder?
If you want to pick one random item in array list, I believe it should be
String s = lista.get(gen.nextInt(lista.size()));
Random.nextInt(int n) retrieves random value between 0-(n-1). See Random.nextInt() documentation.
ResourceNotFound exception I believe is related to failure to locate resource ID inside R.java not index out of bound exception.
TextView.setText() with integer value parameter, interprets integer value as a resource ID, see here. So if you call
atextView.setText(lista.size());
It will throw ResourceNotFoundException because it may not point to correct resource ID. If you want to display number of items in list then
atextView.setText(String.valueOf(lista.size()));
If lista.size () equals 0 then exception can occur...
( because gen.nextInt (-1) )
I hope you to prevent it.
Here is the different way to the filter on list of file based on file name !!!!
File f = new File("/sdcard");
String fileList[];
if(f.isDirectory()){
fileList = f.list(new FilenameFilter() {
#Override
public boolean accept(File dir, String name) {
// TODO Auto-generated method stub
if (name.startsWith("aa")){
return true;
}
return false;
}
});
'FileList' is an array where you get all the File object and then you can easily get the file name from that!!!!
Hope this will help!!!
I've found the solution why this code didn't work. The files weren't in the folder yet - i had to add names to the list manually, then in other function check if they are on sdcard (if not, there is need to copy; if yes, I can display the content).
Related
I have a Java program that goes over all the folders and files inside a given folder and it prints them.
The issues is that now I want to count all the files in the folder by their extension. How can I do that?
This is my code so far:
package ut5_3;
import java.io.File;
import java.util.ArrayList;
import org.apache.commons.io.FilenameUtils;
public class UT5_3 {
ArrayList<String> extensionArray = new ArrayList<String>();
ArrayList<String> extensionArrayTemp = new ArrayList<String>();
public static void main(String[] args) {
File directoryPath = new File("C://Users//Anima//Downloads//MiDir");
File[] directoryContent = directoryPath.listFiles();
UT5_3 prueba = new UT5_3();
prueba.goOverDirectory(directoryContent);
}
public void goOverDirectory(File[] directoryContent) {
for (File content : directoryContent) {
if (content.isDirectory()) {
System.out.println("===========================================");
System.out.println("+" + content.getName());
goOverDirectory(content.listFiles()); // Calls same method again.
} else {
String directoryName = content.getName();
System.out.println(" -" + directoryName);
String fileExtension = FilenameUtils.getExtension(directoryName);
}
}
}
}
So far I've tried making two ArrayList. One to store all the extensions from all the files and another one to store the distinct extensions, but I got really confused and I didn't know how to continue with that idea.
If it is too complex, it'd be great if you could explain an easier way to do it too.
Thanks!
So if I understand you correctly, you want to store the count of all of the file extensions you see. Here is how I would approach it.
First initialize a map with a String as the key and int as the value, at the top of your class like so.
private HashMap<String, Integer> extensions = new HashMap<String, Integer>();
Then you can run this whenever you need to add an extension to the count.
String in = "exe";
if(extensions.containsKey(in))
extensions.put(in, extensions.get(in) + 1);
else
extensions.put(in, 1);
If you want to retrieve the count, simply run extensions.get(in).
If you didn't know already, a HashMap allows you to assign a key to a value. In this case, the key is the file extension and value is the count.
Good day
Using Java 8 or higher is actually not too difficult. First, you need to collect the items. Then, you need to group them by extension and create a map of extensions with the count.
public static void main(String[] args) throws IOException {
Path start = Paths.get("C:/Users/Hector/Documents");
List<String> fileNames = new ArrayList<>();
try (DirectoryStream<Path> stream = Files.newDirectoryStream(start)){
for (Path entry : stream) {
if (!Files.isDirectory(entry)) {
fileNames.add(entry.getFileName().toString());// add file name in to name list
}
}
}
fileNames.stream().map(String::valueOf)
.collect(Collectors.groupingBy(fileName -> fileName.substring(fileName.lastIndexOf(".")+1)))
.entrySet().forEach(entry -> {
System.out.println("File extension: " + entry.getKey() + ", Count: " + entry.getValue().size());
});
}
For my "Documents" directory
Produced the following output
File extension: zargo~, Count: 3
File extension: txt, Count: 1
File extension: exe, Count: 1
File extension: pdf, Count: 3
File extension: ini, Count: 1
File extension: log, Count: 1
File extension: svg, Count: 1
File extension: zargo, Count: 3
File extension: lnk, Count: 1
The reason why I chose this solution over using Files.walk() is because this method can throw an AccessDeniedException which is problematic when you need to traverse different folders. However, if you can control access to a folder by calling canRead() method on the file object, then you could use it. I personally don't like it and many Java developers have issue with that function.
You could modify by adding it to a function that could be called recursively if the current path is a directory. Since the OP requirement is unclear if the count has to be for a given folder or the folder and all subfolders, I decided to just show the count for the current folder.
One last observation, when collecting the extensions, notice that I pass to the substring function to start from the last index of the period character. This is important to capture the real extension for files with multiple periods in the name. For example: Setup.x64.en-US_ProPlusRetail_RDD8N-JF2VC-W7CC6-TVXJC-3YF3D_TX_PR_act_1_OFFICE_13.exe. In a file, the extension always starts after the last period.
struggling again.
I'm recursively searching through a directory and picking out audio files by examining their extensions. Once found, each is to be added to a JList (in the main class - not shown here). However, only the last folder's files are being added to the list. Here is the code:
public void List(String path) throws InterruptedException, IOException {
File root = new File(path);
File[] list = root.listFiles();
DefaultListModel lm = new DefaultListModel();
if (list == null) {
return;
}
for (File f : list) {
if (f.isDirectory()) {
List(f.getAbsolutePath());
} else if (f.isFile()) {
String outPath = f.getAbsolutePath();
try {
String ext = outPath.substring(outPath.lastIndexOf(".") + 1);
if (ext.equals("wma") || ext.equals("m4a") || ext.equals("mp3")) {
lm.addElement(f.getAbsolutePath());
}
} catch (Exception e) {
System.out.println(outPath + " is not a valid file!!!!!");
}
HomeScreen.Library.setModel(lm);
}
}
}
I've tried replacing the lm.addElement(f.getAbsolutePath()) with a simple System.out.println(f.getAbsolutePath) and all files are printed out as expected. I've also tried moving HomeScreen.Library.setModel(lm); into different areas but that generally results in nothing being added to the list at all.
What I think must be happening is that each time a new folder is found, the list model is reset, somehow, and the files are added to the now empty model.
Is there a way around this? Am I doing something dopey in my code which is resulting in this apparent reset?
Many thanks in advance,
Guy
The problem is that you create a new DefaultListModel in each call of your List() method. This explains why you think that
each time a new folder is found, the list model is reset, somehow, and the files are added to the now empty model
I think you want to add files to the same DefaultListModel so create it outside of the List() method, and either pass that as a parameter or make it an instance field which List() can access.
You code create new model every tyme method invoked. You need create model once and update it.
My advice move DefaultListModel lm = new DefaultListModel(); out of you method and pass reference in it. Also move HomeScreen.Library.setModel(lm); out of you method and put it after method call.
DefaultListModel lm = new DefaultListModel();
some.List(path, lm);
HomeScreen.Library.setModel(lm);
PS: By java name convention method names starts from lover case letter.
I wan to create a public, non-static method that does this:
getContent : This method should take as input a String filename and return a String. The method should search for a file with name filename in the array drive and return the data that is stored in that TxtFile. If no such file exists in the array drive, the method should return null.
I don't know how to search for something in an array. can someone show me how to do this?
Come on, try it your self:
Step1: Read all the file Names from a directory.
Step2: Store the list of Files to a List.
Step3: Iterate the list, Write a conditions with a use the File.getName() method to compare and the name and your input.
if(file.getName().equals(inputFileName)){
return "boooo! I have found You!"
}
You search in an array by iterating of it. Something like this (if you are inside a method):
for(String x : someStringArray){
if (somecondition(x)) return x;
}
this should be of help: File search
A definitive source for information.
EDIT: thought of something really simple:
String[] drives = new String[]{"C:\\", "D:\\"};
File file;
for(String drive : drives)
{
file = new File(drive + "abc.txt");
JOptionPane.showMessageDialog(null, file.exists());
}
you can replace the showMessageDialogBox with whatever you want to do if the file exists.
OK this method reads a dirctor, verify the file paths are ok and then pass each file to a method and updates a Map object.
But how can i explain this for java doc. I want to create a java doc and how should i explain this method for the documentation purpose. Please tell me, if you can help me with this example, i can work for my whole project. thank you:
private void chckDir() {
File[] files = Dir.listFiles();
if (files == null) {
System.out.println("Error");
break;
}
for (int i = 0; i < files.length; i++) {
File file = new File(files[i].getAbsoluteFile().toString());
Map = getMap(file);
}
}
Your method doesn't do what you said In your first sentence (doesn't verify file paths, and throws the result of getMap() away), but there's nothing wrong with putting that kind of sentence im the Javadoc.
There are some issues with your code:
The break statement will give a compilation error, I think. It should be a return.
It is bad style to name a field with a capital letter as the first character. If Dir and Map are field names, they should be dir and map respectively.
The statement Map = getMap(file); is going to repeatedly replace the Map field, and when you exit the loop, the field will refer to the object returned by the last getmap call. This is probably wrong.
Finally, change the file declaration as follows. (There is no need to create a new File object ... because getAbsoluteFile() reurns a File)
File file = files[i].getAbsoluteFile();
Is the any way to get the number of files in a folder using Java?
My question maybe looks simple, but I am new to this area in Java!
Update:
I saw the link in the comment. They didn't explained to omit the subfolders in the target folder.
How to do that? How to omit sub folders and get files in a specified directory?
Any suggestions!!
One approach with pure Java would be:
int nFiles = new File(filename).listFiles().length;
Edit (after question edit):
You can exclude folders with a variant of listFiles() that accepts a FileFilter. The FileFilter accepts a File. You can test whether the file is a directory, and return false if it is.
int nFiles = new File(filename).listFiles( new MyFileFilter() ).length;
...
private static class MyFileFilter extends FileFilter {
public boolean accept(File pathname) {
return ! pathname.isDirectory();
}
}
You will need to use the File class. Here is an example.
This method allows you to count files inside the folder without loading all files into memory at once (which is good considering folders with big amount of files which could crash your program), and you can additionaly check file extension etc. if you put additional condition next to f.isFile().
import org.apache.commons.io.FileUtils;
private int countFilesInDir(File dir){
int cnt = 0;
if( dir.isDirectory() ){
Iterator it = FileUtils.iterateFiles(dir, null, false);
while(it.hasNext()){
File f = (File) it.next();
if (f.isFile()){ //this line weeds out other directories/folders
cnt++;
}
}
}
return cnt;
}
Here you can download commons-io library: https://commons.apache.org/proper/commons-io/