I have a Java program that searches through your cookies files and then saves each file into an array. I then try to search through each of those files for a certain string, however when I try to search the files I KNOW exist, java tells me that they don't. Any ideas?
Here is my code so far:
import java.io.*;
import java.util.*;
public class CheckCookie
{
static String[] textFiles = new String[100];
static String userName = "";
public static void findCookies()
{
String path = "pathtocookies";
String files;
File folder = new File(path);
File[] listOfFiles = folder.listFiles();
for (int i = 0; i < listOfFiles.length; i++)
{
if (listOfFiles[i].isFile())
{
files = listOfFiles[i].getName();
if (files.endsWith(".txt") || files.endsWith(".TXT"))
{
textFiles[i] = files;
}
}
}
}
public static boolean searchCookies()
{
for(int j = 0; j < textFiles.length; j++) {
String path2 = "pathtocookies"+textFiles[j];
File file = new File(path2);
try {
Scanner scan = new Scanner(file);
while (scan.hasNext()) {
String line = scan.nextLine();
if(line.contains("ineligible_age")) {
System.out.println("A cookie for ineligible age was set.");
return true;
}
}
}
catch(FileNotFoundException e) {
System.out.println("File was not found.");
return false;
}
}
System.out.println("A cookie for ineligible age was not set.");
return false;
}
public static void main(String[] args)
{
findCookies();
searchCookies();
System.out.println();
System.out.println("Finished searching for cookies. Yum.");
}
}
Actual path:
C:/Users/lucas.brandt/AppData/Roaming/Microsoft/Windows/Cookies
Use a List, instead of an array to store the textFiles.
Imagine a directory with 2 files. The first is "abc.doc", the second "itsme.txt"
Your textFiles array will look like this:
textFiles[0]: null
textFiles[1]: "itsme.txt"
So you try to access "pathtocookies" + "null" which will fail, you go to the catch and return out of the function.
Further hints:
Return the list from the first function, use it as an argument for the second function
Use a debugger or "debug" print statements to debug your code to see whats happening
More hints depends on the actual use case.
--tb
In this line:
String path2 = "pathtocookies"+textFiles[j];
You are missing the File separator between the directory name and the file name. java.io.File has a constructor that takes the parent path and the file name as separate arguments. You can use that or insert File.separator:
String path2 = "pathtocookies" + File.separator + textFiles[j];
You are also picking up directories in your array. Check that it is a file before you try to scan it.
Also, consider the other answer where the files are saved in a List, eliminating the directories.
files = listOfFiles[i].getName();
Try to change to
files = listOfFiles[i].getAbsolutePath();
EDIT
You can also initiate directectly an array of File (instead of String),
and you have to use .canRead() method to verify File access.
Why don't you just store the File instances in a File[] or List<File>?
I think you would also benefot from using a StringBuilder, when doing a lot of string concatenstions...
Related
last week i made this java file wondering to search in my pc files which contains certain words i input.
After to have done it i thought "why not translating it in python?" and in python i have seen that it runs out of memory (because of the recursion), but in java didn't (in python the code works if i dont give a lot of dirs and files), i put here the 2 codes and the error (java vs python) so u can help me(sorry for my english i am not mother tongue).
JAVA:
package com.company;
import java.io.*;
import java.util.ArrayList;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
System.out.println("Input path to start(remember the / at the end):");
Scanner input = new Scanner(System.in);
String path=input.nextLine();
ArrayList<String> words= new ArrayList<>();
String word="";
while(!word.equals("//quit")){
System.out.println("Input word to search (input://quit to stop):");
word=input.nextLine();
if(!word.equals("//quit"))
words.add(word);
}
Finder finder= new Finder(path,castToArray(words));
finder.readFile();
}
private static void readFiles(Finder finder){
String[] files = finder.printFiles();
for(int i=0; i< files.length;i++){
System.out.println(files[i]);
}
}
private static String[] castToArray(ArrayList<String> words){
String[] w0rds = new String[words.size()];
for(int i=0; i< words.size(); i++){
w0rds[i]= words.get(i);
}
return w0rds;
}
}
class Finder {
private String[] words;
private File file;
private String path;
Finder(String path,String... words){
this.words=words;
this.path=path;
file= new File(path);
}
public String[] printFiles(){
String[] files;
files=file.list();
return files;
}
public void readFile(){
String[] files= printFiles();
for(int i=0; i< files.length;i++){
File f = new File(file.getPath()+"/"+files[i]);
if(!f.isDirectory()){
searchWord(f,words);
}else {
Finder finder = new Finder(path+f.getName()+"/",words);
finder.readFile();
}
}
}
public File getFile() {
return file;
}
public void searchWord(File file,String... words){
DataInputStream dis = null;
try {
dis = new DataInputStream(new FileInputStream(file));
byte[] bytes = new byte[512];
dis.readFully(bytes);
String obj = new String(bytes);
for(int i=0; i< words.length;i++){
if(obj.contains(words[i])){
System.out.println(file.getName());
break;
}
}
} catch (FileNotFoundException e) {
} catch (IOException e) {
}
}
}
PYTHON:
import os
class Finder:
path = ""
words= []
def readFile(self,path,words):
new_file = open(path, "r")
data=new_file.read(8192)
new_file.close()
for word in words:
if(data.find(word,0,len(data))!=-1):
print "name: "+new_file.name+" path: "+path
break
def __init__(self,path, words):
self.path=path
self.words=words
def __del__(self):
files=os.listdir(path)
for file in files:
if(os.path.isdir(path+file)!=True):
self.readFile(path+file,words)
else:
dirpath = path+file+"/"
finder = Finder(path,words)
path= raw_input("input path to start(remember the / at the end):\n")
words=[]
word = ""
while word != "//quit":
word=raw_input("input word to search (write //quit to start searching):\n")
if word != "//quit":
words.append(word);
print "start searching for "+str(words)+"..."
finder = Finder(path,words)
PYTHON ERROR:
Exception RuntimeError: 'maximum recursion depth exceeded' in <bound method Finder.__del__ of <__main__.Finder instance at 0x7f5c0b4f4d40>> ignored
Exception RuntimeError: 'maximum recursion depth exceeded' in <bound method Finder.__del__ of <__main__.Finder instance at 0x7f5c0b4f4c68>> ignored
Exception RuntimeError: 'maximum recursion depth exceeded' in <bound method Finder.__del__ of <__main__.Finder instance at 0x7f5c0b4f4d40>> ignored
Exception RuntimeError: 'maximum recursion depth exceeded' in <bound method Finder.__del__ of <__main__.Finder instance at 0x7f5c0b4f4c68>> ignored
In python, you rarely should use the __del__ method. It is a special magic method that is called at an arbitrary time (when the object is garbage-collected) with very few applications and multiple caveats. Instead, for most use cases, you should use a .close() method you call explicitly or with a context manager like contextlib.closing.
That said, I don't know why you made a __del__ method at all since in your java code there is nothing like that. Closest java thing would be a finalize method, but you're not using it, so why did you chose to use __del__ in your translation?
Anyway, in python you can use os.walk() instead of os.listdir() to traverse your directory tree - os.walk() is iteratively recursive so it can handle any path depth without running out of call stack space:
for pth, dirs, files in os.walk(path):
for filename in files:
self.readFile(os.path.join(pth, filename))
This code snippet will call readFile with all files in all subfolders.
The problem in your python code is, that you use the global path variable in __del__ instead of self.path. Therefore you get an infinite recursion.
Better convert your class into functions:
import os
def readFile(path, words):
with open(path, "r") as new_file:
data = new_file.read(8192)
for word in words:
if word in data:
print "name: {} path: {}".format(new_file.name, path)
break
def search(path, words):
files = os.listdir(path)
for filename in files:
fullname = os.path.join(path, filename)
if not os.path.isdir(fullname):
readFile(fullname, words)
else:
search(fullname, words)
path = raw_input("input path to start: ")
words = []
while True:
word = raw_input("input word to search (write //quit to start searching): ")
if word == "//quit":
break
words.append(word)
print "start searching for {}...".format(', '.join(words))
search(path, words)
I have several files including duplicates which I have to compress into an archive.Do you know some tool able to rename duplicate files before creating the archive ex(cat.txt, cat(1).txt, cat(2).txt ...)?
I have created the following code that easily removes duplicates:
static void renameDuplicates(String fileName, String[] newName) {
int i=1;
File file = new File(fileName + "(1).txt");
while (file.exists() && !file.isDirectory()) {
file.renameTo(new File(newName[i-1] + ".txt"));
i++;
file = new File(fileName + "(" + i + ").txt");
}
}
Use is simply as well:
String[] newName = {"Meow", "MeowAgain", "OneMoreMeow", "Meowwww"};
renameDuplocates("cat", newName);
The result is:
cat.txt -> cat.txt
cat(1).txt -> Meow.txt
cat(2).txt -> MeowAgain.txt
cat(3).txt -> OneMoreMeow.txt
Keep on mind that the number of duplicates should be smaller or equal than alternative names in the array of string given. You can prevent it with while cycle modification to:
while (file.exists() && !file.isDirectory() && i<=newName.length)
In this case the remaining files will keep unnamed.
Add static field in some class with some initial value.
static int number = 1;
Then in your java code you may rename duplicates in this way using java 8 streams and Files class :
Set<String> files = new HashSet<String>();
youCollectionOfFiles.stream().forEach((file)->{
if (files.add(file.getFileName().toString()) == false) {
try {
//rename the file
Files.move(file,
file.resolveSibling(file.getFileName().toString() + (number++)));
} catch (Exception e) {
e.printStackTrace();
}
}
});;
Try an approach like this one:
File folder = new File("your/path");
HashMap<String,Integer> fileMap = new HashMap<String,Integer>();
File[] listOfFiles = folder.listFiles();
for (int i = 0; i < listOfFiles.length; i++) {
if(fileMap.containsKey(listOfFiles[i])){
String newName = listOfFiles[i]+"_"
+fileMap.get(listOfFiles[i]);
fileMap.put(listOfFiles[i],fileMap.get(listOfFiles[i])+1);
listOfFiles[i].renameTo(newName);
fileMap.put(newName,1); // can be ommitted
}else{
fileMap.put(listOfFiles[i],1);
}
}
I am not sure if I asked the question 100% right but here it goes:
I got this code:
File root = Environment.getExternalStorageDirectory();
File saveFolder= new File(Root, "Save");
String[] files=saveFolder.list(
new FilenameFilter() {
public boolean accept(File dir, String name) {
//define here you filter condition for every single file
return name.startsWith("1_");
}
});
if(files.length>0) {
System.out.println("FOUND!");
System.out.println("Files length = "+files.length);
} else {
System.out.println("NOT FOUND!");
}
I got 2 files that start with "1_", the println also shows I got 2 files.
But how can I print or see, the file names, of those 2 files, after the boolean?
So something like (between the other System.out.println):
System.out.println("File names = "+files.names);
Loop over the array:
String[] files=SaveFolder.list(...);
for (String name : files) {
System.out.println("File name: " + name);
}
Note that the naming convention of variables is to start them with lower case.
You can use
file.getName(); // for the name of the file
file.getAbsolutePath(); for the full path of the file
replace
public boolean accept(File dir, String Name) {
//define here you filter condition for every single file
return Name.startsWith("1_");
}
with this:
public boolean accept(File dir, String Name) {
//define here you filter condition for every single file
boolean b = Name.startsWith("1_");
if (b)
System.out.println(Name);
return b;
}
Use Arrays.asList() if you want to quickly print out a primitive array
System.out.println(Arrays.asList(files));
Add some code to the if block:
if(files.length>0) {
System.out.println("FOUND!");
System.out.println("Files length = "+files.length);
// next lines print the filenames
for (String fileName:files)
System.out.println(fileName);
}
This is what I use personally if I need filenames to load in a load function.
public void getFiles(String path){
//Store the filesnames to ArryList<String>
File dir = new File(path);
ArrayList<String> savefiles = new ArrayList<String>();
for(File file : dir.listFiles()){
savefiles.add(file.getName());
}
//Check if the filenames or so to say read them
for (int i = 0; i < savefiles.size(); i++){
String s = savefiles.get(i);
System.out.println("File "+i+" : "+s);
}
System.out.println("\n");
}
I hope this helps C:
I was writing a program in Java to search for a piece of text
I took these 3 as inputs
The directory, from where the search should start
The text to be searched for
Should the search must be recursive (to or not to include the directories inside a directory)
Here is my code
public void theRealSearch(String dirToSearch, String txtToSearch, boolean isRecursive) throws Exception
{
File file = new File(dirToSearch);
String[] fileNames = file.list();
for(int j=0; j<fileNames.length; j++)
{
File anotherFile = new File(fileNames[j]);
if(anotherFile.isDirectory())
{
if(isRecursive)
theRealSearch(anotherFile.getAbsolutePath(), txtToSearch, isRecursive);
}
else
{
BufferedReader bufReader = new BufferedReader(new FileReader(anotherFile));
String line = "";
int lineCount = 0;
while((line = bufReader.readLine()) != null)
{
lineCount++;
if(line.toLowerCase().contains(txtToSearch.toLowerCase()))
System.out.println("File found. " + anotherFile.getAbsolutePath() + " at line number " + lineCount);
}
}
}
}
When recursion is set true, the program returns a FILENOTFOUNDEXCEPTION
So, I referred to the site from where I got the idea to implement this program and edited my program a bit. This is how it goes
public void theRealSearch(String dirToSearch, String txtToSearch, boolean isRecursive) throws Exception
{
File[] files = new File(dirToSearch).listFiles();
for(int j=0; j<files.length; j++)
{
File anotherFile = files[j];
if(anotherFile.isDirectory())
{
if(isRecursive)
theRealSearch(anotherFile.getAbsolutePath(), txtToSearch, isRecursive);
}
else
{
BufferedReader bufReader = new BufferedReader(new FileReader(anotherFile));
String line = "";
int lineCount = 0;
while((line = bufReader.readLine()) != null)
{
lineCount++;
if(line.toLowerCase().contains(txtToSearch.toLowerCase()))
System.out.println("File found. " + anotherFile.getAbsolutePath() + " at line number " + lineCount);
}
}
}
}
It worked perfectly then. The only difference between the two snippets is the way of creating the files, but they look the same to me!!
Can anyone point me out where I messed up?
In the second example it is used listFiles() whichs returns files. In your example it is used list() which returns only the names of the files - here the error.
The problem in the first example is in the fact that file.list() returns an array of file NAMES, not paths. If you want to fix it, simply pass file as an argument when creating the file, so that it's used as the parent file:
File anotherFile = new File(file, fileNames[j]);
Now it assumes that anotherFile is in the directory represented by file, which should work.
You need to include the base directory when you build the File object as #fivedigit points out.
File dir = new File(dirToSearch);
for(String fileName : file.list()) {
File anotherDirAndFile = new File(dir, fileName);
I would close your files when you are finished and I would avoid using throws Exception.
Let's say, I have a folder called maps and inside maps I have map1.txt, map2.txt, and map3.txt. How can I use Java and the BufferReader to read all of the .txt files in folder maps (if it is at all possible)?
Something like the following should get you going, note that I use apache commons FileUtils instead of messing with buffers and streams for simplicity...
File folder = new File("/path/to/files");
File[] listOfFiles = folder.listFiles();
for (int i = 0; i < listOfFiles.length; i++) {
File file = listOfFiles[i];
if (file.isFile() && file.getName().endsWith(".txt")) {
String content = FileUtils.readFileToString(file);
/* do somthing with content */
}
}
I would take #Andrew White answer (+1 BTW) one step further, and suggest you would use FileNameFilter to list only relevant files:
FilenameFilter filter = new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.endsWith(".txt");
}
};
File folder = new File("/path/to/files");
File[] listOfFiles = folder.listFiles(filter);
for (int i = 0; i < listOfFiles.length; i++) {
File file = listOfFiles[i];
String content = FileUtils.readFileToString(file);
// do something with the file
}
final File folder = new File("C:/Dev Tools/apache-tomcat-6.0.37/webapps/ROOT/somefile");
for (final File fileEntry : folder.listFiles()) {
System.out.println("FileEntry Directory "+fileEntry);
With NIO you can do the following:
Files.walk(Paths.get("/path/to/files"))
.filter(Files::isRegularFile)
.filter(path -> path.getFileName().toString().endsWith(".txt"))
.map(FileUtils::readFileToString)
// do something
To read the file contents you may use Files#readString but, as usual, you need to handle IOException inside lambda expression.
I think it's good way to read all .txt files from maps and sub folder's
private static void addfiles (File input,ArrayList<File> files)
{
if(input.isDirectory())
{
ArrayList <File> path = new ArrayList<File>(Arrays.asList(input.listFiles()));
for(int i=0 ; i<path.size();++i)
{
if(path.get(i).isDirectory())
{
addfiles(path.get(i),files);
}
if(path.get(i).isFile())
{
String name=(path.get(i)).getName();
if(name.lastIndexOf('.')>0)
{
int lastIndex = name.lastIndexOf('.');
String str = name.substring(lastIndex);
if(str.equals(".txt"))
{
files.add(path.get(i));
}
}
}
}
}
if(input.isFile())
{
String name=(input.getName());
if(name.lastIndexOf('.')>0)
{
int lastIndex = name.lastIndexOf('.');
String str = name.substring(lastIndex);
if(str.equals(".txt"))
{
files.add(input);
}
}
}
}
If you want a better way of doing this using the new java.nio api, then this is the way, taken from the java docs
Path dir = ...;
try (DirectoryStream<Path> stream =
Files.newDirectoryStream(dir, "*.txt")) {
for (Path entry: stream) {
System.out.println(entry.getFileName());
}
} catch (IOException x) {
// IOException can never be thrown by the iteration.
// In this snippet, it can // only be thrown by newDirectoryStream.
System.err.println(x);
}
Using only JDK, If all your files are in one directory:
File dir = new File("path/to/files/");
for (File file : dir.listFiles()) {
Scanner s = new Scanner(file);
// do something with file
s.close();
}
To exclude files, you can use listFiles(FileFilter)