I have developed a java code that reads files from the folder chosen by the user. It displays how many lines of code are in each file, it reads only .java filesonly and final outcome is shown on console , I was thinking that output to be get displayed on console but along with a text file conataing the same information to be get stored on desktop also, please advise how to that and the name of the file that is generated its name is to be based on timestamp lets assume that name of the output file would be 'output06282012' and that text file should contain the same information that is shown on the console , here is my piece of code...
public static void main(String[] args) throws FileNotFoundException {
JFileChooser chooser = new JFileChooser();
chooser.setCurrentDirectory(new java.io.File("C:" + File.separator));
chooser.setDialogTitle("FILES ALONG WITH LINE NUMBERS");
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
chooser.setAcceptAllFileFilterUsed(false);
if (chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION)
{ Map<String, Integer> result = new HashMap<String, Integer>();
File directory = new File(chooser.getSelectedFile().getAbsolutePath());
int totalLineCount = 0;
File[] files = directory.listFiles(new FilenameFilter(){
#Override
public boolean accept(File directory, String name) {
if(name.endsWith(".java"))
return true;
else
return false;
}
}
);
for (File file : files)
{
if (file.isFile())
{ Scanner scanner = new Scanner(new FileReader(file));
int lineCount = 0;
try
{ for (lineCount = 0; scanner.nextLine() != null; lineCount++) ;
} catch (NoSuchElementException e)
{ result.put(file.getName(), lineCount);
totalLineCount += lineCount;
}
} }
System.out.println("*****************************************");
System.out.println("FILE NAME FOLLOWED BY LOC");
System.out.println("*****************************************");
for (Map.Entry<String, Integer> entry : result.entrySet())
{ System.out.println(entry.getKey() + " ==> " + entry.getValue());
}
System.out.println("*****************************************");
System.out.println("SUM OF FILES SCANNED ==>"+"\t"+result.size());
System.out.println("SUM OF ALL THE LINES ==>"+"\t"+ totalLineCount);
}
}
Now the idea in my mind id for this logic
1) construct the file name you want to use
2) open the file for write
3) each time you call a System.out.println(), make a similar call to write the same message to the file
4) when you are all done, make sure you close the file handle.
I have an rough idea something like this
try{
java.util.Date date= new java.util.Date();
System.out.println(new Timestamp(date.getTime()));
BufferedWriter out = new BufferedWriter(new FileWriter("C://Desktop//output"+new Timestamp(date.getTime())+".txt"));
out.write("some information");
out.close;
}catch(IOException e){
e.printStackTrace();
}
please advise how to that and the name of the file that is generated its name is to be based on timestamp lets assume that name of the output file would be 'output06282012' and that text file should contain the same information that is shown on the console
As far as I can tell, this is the only thing you are actually asking:
Please advise how to that and the name of the file that is generated its name is to be based on timestamp. Lets assume that name of the output file would be 'output06282012' ...
The simple answer is:
String fileName = "output" + new Date().getTime();
You then go on to say:
.... and that text file should contain the same information that is shown on the console
You've got two choices:
You can change where System.out goes to by calling System.setOut(...). (Check the javadoc for details.)
You can create a PrintWriter or PrintStream wrapper for your file stream and write to that instead of writing to System.out.
In my opinion, it is a bad idea to use System.setOut(...) unless you've got no choice. It is a "global action" that affects the entire application. It is better to pass the writer that you want to use as a parameter ...
could you please sow in code as I have done that will clear the understanding
Sorry, I don't write people's programs for them (unless it is an interesting problem!). You need to write and debug the code yourself, using the information provided in the relevant javadocs. You can find the Java documentation online on the Oracle website: http://docs.oracle.com/javase/7/docs/
Related
I am writing a method that takes a a string of html and writes it to a file. The method should increment the file name if the file already exists. For example, if wordmatch.html already exists then a new file should be created wordmatch1.html so and so fourth.
I have created a method that writes the html to a file. I'm working on the last part to incrementally change the name of a new file if the file already existst.
public void saveContent(WordMatch wordMatch){
logger.info(wordMatch);
try {
File file = new File("wordmatch0.html");
String html = wordMatch.toString();
String cleanedHTML = html.replace("WordMatch(content=","").replace(")","");
logger.info(cleanedHTML);
if (file.createNewFile()) {
System.out.println("File created: " + file.getName());
try {
FileWriter myWriter = new FileWriter("word_match.html");
myWriter.write(cleanedHTML);
myWriter.close();
System.out.println("Successfully wrote to the file.");
} catch (IOException e) {
System.out.println("An error occurred.");
e.printStackTrace();
}
} else {
String fileName = file.getName().toString();
String index = fileName.substring(fileName.indexOf("h") + 1);
index = index.substring(0, index.indexOf("."));
Integer parsedInt = Integer.parseInt(index);
System.out.println(parsedInt);
parsedInt+=1;
fileName = fileName.replace(index,parsedInt.toString());
System.out.println(fileName);
System.out.println("fileName should have been printed by now");
file = new File(fileName);
FileWriter myWriter = new FileWriter(file);
myWriter.write(cleanedHTML);
myWriter.close();
//TODO add method to write file name with new index
System.out.println("File already exists.");
}
} catch (IOException e) {
System.out.println("An error occurred.");
e.printStackTrace();
}
}
Any help with this would be greatly appreciated. Thanks.
A simple approach will be count the number of files matching your file name and then increment the numberOfFiles to create a new file name :
Stream<Path> files = Files.list(Paths.get("C:\\your\\local\\path"));
long numberOfFiles = files.map(Path.class::cast)
.filter(path -> path.getFileName().toString().startsWith("wordmatch"))
.count();
After all you have to manage certains situations, to have a good algorithm for managing your files.
A problem that seems trivial but has so many pitfalls.
The algorithm you wrote won't work for the following reasons:
Simple if-else is not enough, you need to go through a loop to find the last index, because potentially there could be many files created already.
Else block tries to find an index from the file name that should't have one.
Moreover, there are additional questions that may raise.
What if someone deleted the intermediate indexes and now you have 1 and 4, do you want to go with 2 or 5?
Can someone delete the files from the directory except the programm?
Are nested directories possible?
How often files are created?
Can someone manually create a file with a proper name bypassing the programm?
And more importand question is - do you really want to stick to the strict brute-force counter on the actual files listed in a directory?
If the answer is yes, the more reasonable would be to check the files using File.list(), sort them, take the last index and increment them instead of trying to create a file and increment on a failure.
public class Main {
public static void main(String[] args) {
File directoryPath = new File("path_to_your_dir");
FilenameFilter filenameFilter = (dir, name) -> !dir.isFile();
Integer maxIndex = Arrays.stream(directoryPath.list(filenameFilter))
// Take numeric index from the end of the file name, beware of file extensions!
.map(name -> name.substring("word_match".length(), name.lastIndexOf('.')))
.map(Main::parseOrDefault) // Parse it to a number
.max(Integer::compareTo) // Define how to compare them
.orElse(-1);
// -1 is no files, 0 if a file with no index, otherwise max index
System.out.println(maxIndex);
}
private static Integer parseOrDefault(String integer) {
try {
return Integer.valueOf(integer);
} catch (NumberFormatException e) {
return 0;
}
}
}
If the answer is no, you can have a counter that is persisted somewhere (file system, BD) and incremented regardless every time.
And more simple approach is establish a frequence of file creations and simply append a timestamp/date-time to the end of each file.
I have a Java program that I am using to scan a directory to look for certain files. It finds the files but now I am trying to get the code to open the files once it finds them, but I am not sure how to do that.
Here a part of my code
File file = new File("/Users/******/Desktop/******");
String[] A = file.list();
File[] C = file.listFiles();
for (String string : A) {
if (string.endsWith(".txt")) {
System.out.println(string);
}
if (string.contains("******")) {
System.out.println("It contains X file");
}
}
I am trying to get it so once it finds the files ending in .txt, it opens all of them
I have tried using Google on how to solve his, I came across .getRuntime() and so I tried
try{
Runtime.getRuntime().exec("******.txt");
} catch(IOException e){
}
But I am not fully understanding how how this works. I am trying to get to so that once it finds the files it opens them. I am not trying to have the IDE open the text on the screen. I want the actual Notepad/TextEdit program to open.
File[] files = new File("/Users/******/Desktop/******").listFiles();
for (File f : files) {
String fileName = f.getName();
if (fileName.endsWith(".txt")) {
System.out.println(fileName);
}
if (fileName.contains("******")) {
System.out.println("It contains X file");
}
}
How would it be possible to enable my application to save to a new .txt file each time the user wishes to save, as opposed to overwriting the existing one?
I have this code which functions and saves information to a text file:
if(Menu.menuChoice == 1 && Library.ManualList.size() > 0){
Library.displayManualList();
boolean saveYesNo = Console.readYesNo("The ManualKeeper® app is able to save your current library to a '.txt' \nfile in your workspace directory.\n\nWould you like to save the current library? (Y/N):\n");
if(saveYesNo){
try {
FileWriter fw = new FileWriter("Library.txt");
PrintWriter pw = new PrintWriter(fw);
for (int i1 = 0; i1 < Library.ManualList.size(); i1++){
pw.println("-------------------- Index Number: " + i1 + " --------------------");
pw.println(Library.ManualList.get(i1).displayManual());
pw.println("---------------------------------------------------------\n");
}
pw.close();
} catch (IOException e) {
System.out.println("Error! Library unable to save.");
}
System.out.println("\n\n--------------------------------------------------------------------------");
System.out.println("\n Library saved!\n");
System.out.println("--------------------------------------------------------------------------\n");
}
else if(saveYesNo){
System.out.println("\n");
}
Ideally I would like the files to be saved in a numbered fashion, so the user could easily select which .txt file to view, at a later date.
To save it to a new file each time, the file name has to be unique.
You can achieve this in mulitple ways. Some ideas:
Date+Time in file name
Add the current date+time to the file name, this will also be informative as when it was created/saved, and when listing files, newer files will be at the end of the list naturally.
String name = "Library-"
+ new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss").format(new Date()) + ".txt";
As an alternative, you could simply append System.currentTimeMillis() which will preserve natural creation order but will not be as nice looking/informative:
String name = "Library-" + System.currentTimeMillis() + ".txt";
Random String in file name
This might not be as nice looking, but for example:
String name = "Library-" + UUID.randomUUID() + ".txt";
Counter in the file name
The idea is to use a counter in the file name, so the first should be "Library.txt", the next should be "Library (2).txt", the third should be "Library (3).txt" etc.
For this to implement, we have to check existing files to determine the next value of the counter. Here is an example how to do it. This is not optimal, but does the job:
public static Path uniqueFile() {
Path file = Paths.get("Library.txt").toAbsolutePath();
if (!Files.exists(file))
return file;
Path folder = file.getParent();
for (int counter = 2; true; counter++) {
file = folder.resolve(String.format("Library (%d).txt", counter));
if (!Files.exists(file))
return file;
}
}
And using it:
String name = uniqueFile().getFileName().toString();
If the application is made with a GUI, a fileDialog would be best (save if he wants to override the file, save as if he wants to save it to a new file, like a lot of applications have).
In your case you should use a counter and add it to the end of the file like Library1.txt.
If rerun the application, of course this counter variable is reset resp. it is not stored. I would suggest to store this variable (and other attributes like that) in another file, e.g. config.txt
This config.txt file you can read (and parse it like I showed you in a previous answer). So everytime you start your application you read the config.txt file, set the counter. Before exiting the application of course you have to save the counter to the config.txt file.
Just pseudocode:
//load at start of application
counter = loaded from config.txt
//save to a new file
FileWriter fw = new FileWriter("Library" + counter++ + ".txt");
//save counter to config.txt file
I have a file which is needed for running tests - this file needs to be personalized (name and password) by whomever is running the test. I do not want to store this file in Eclipse (since it would need to be changed by whomever runs the test; also it would be storing personal info in the repo), so I have it in my home folder (/home/conrad/ssl.properties). How can I point my program to this file?
I've tried:
InputStream sslConfigStream = MyClass.class
.getClassLoader()
.getResourceAsStream("/home/" + name + "/ssl.properties");
I've also tried:
MyClass.class.getClassLoader();
InputStream sslConfigStream = ClassLoader
.getSystemResourceAsStream("/home/" + name + "/ssl.properties");
Both of these give me a RuntimeException because the sslConfigStream is null. Any help is appreciated!
Use a FileInputStream to read data from a file. The constructor takes a string path (or a File object, which encapsulates string path).
Note 1: A "resource" is a file which is in the classpath (alongside your java/class files). Since you don't want to store your file as a resource because you don't want it in your repo, ClassLoader.getSystemResourceAsStream() is not what you want.
Note 2: You should use a cross-platform way of getting a file in a home directory, as follows:
File homeDir = new File(System.getProperty("user.home"));
File propertiesFile = new File(homeDir, "ssl.properties");
InputStream sslConfigStream = new FileInputStream("/home/" + name + "/ssl.properties")
You can simplify your work, using Java's 7 method:
public static void main(String[] args) {
String fileName = "/path/to/your/file/ssl.properties";
try {
List<String> lines = Files.readAllLines(Paths.get(fileName),
Charset.defaultCharset());
for (String line : lines) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
You can also improve your way of reading properties file, using Properties class and forget about reading and parsing your .properties file:
http://www.mkyong.com/java/java-properties-file-examples/
Is this a graphics program (ie. using the Swing library)? If so it is a pretty simple task of using a JFileChooser.
http://docs.oracle.com/javase/6/docs/api/javax/swing/JFileChooser.html
JFileChooser f = new JFileChooser();
int rval = f.showOpenDialog(this);
if (rval == JFileChooser.APPROVE_OPTION) {
// Do something with file called f
}
You can also use Scanner to read the file.
String fileContent = "";
try {
Scanner scan = new Scanner(
new File( System.getProperty("user.home")+"/ssl.properties" ));
while(scan.hasNextLine()) {
fileContent += scan.nextLine();
}
scan.close();
} catch(FileNotFoundException e) {
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Reading the java files from the folder
I have developed a java code that reads files from the folder chosen by the user. It displays how many lines of code are in each file, it reads only .java filesonly and final outcome is shown on console , I was thinking that output to be get displayed on console but along with a text file conataing the same information to be get stored on desktop also, please advise how to that and the name of the file that is generated its name is to be based on timestamp lets assume that name of the output file would be 'output06282012' and that text file should contain the same information that is shown on the console , here is my piece of code...
public static void main(String[] args) throws FileNotFoundException {
JFileChooser chooser = new JFileChooser();
chooser.setCurrentDirectory(new java.io.File("C:" + File.separator));
chooser.setDialogTitle("FILES ALONG WITH LINE NUMBERS");
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
chooser.setAcceptAllFileFilterUsed(false);
if (chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION)
{ Map<String, Integer> result = new HashMap<String, Integer>();
File directory = new File(chooser.getSelectedFile().getAbsolutePath());
int totalLineCount = 0;
File[] files = directory.listFiles(new FilenameFilter(){
#Override
public boolean accept(File directory, String name) {
if(name.endsWith(".java"))
return true;
else
return false;
}
}
);
for (File file : files)
{
if (file.isFile())
{ Scanner scanner = new Scanner(new FileReader(file));
int lineCount = 0;
try
{ for (lineCount = 0; scanner.nextLine() != null; lineCount++) ;
} catch (NoSuchElementException e)
{ result.put(file.getName(), lineCount);
totalLineCount += lineCount;
}
} }
System.out.println("*****************************************");
System.out.println("FILE NAME FOLLOWED BY LOC");
System.out.println("*****************************************");
for (Map.Entry<String, Integer> entry : result.entrySet())
{ System.out.println(entry.getKey() + " ==> " + entry.getValue());
}
System.out.println("*****************************************");
System.out.println("SUM OF FILES SCANNED ==>"+"\t"+result.size());
System.out.println("SUM OF ALL THE LINES ==>"+"\t"+ totalLineCount);
}
}
output that is displayed on console is to be stored in a text file on desktop also, please advise how to that and the name of the file that is generated its name is to be based on timestamp lets assume that name of the output file would be 'output06282012' and that text file should contain the same information that is shown on the console
I'd advice you to ask questions more precisely. From what I understand from your question, you want to write some information to a text file. To do this all you have to do is this -
try{
java.util.Date date= new java.util.Date();
System.out.println(new Timestamp(date.getTime()));
BufferedWriter out = new BufferedWriter(new FileWriter("C://Desktop//output"+new Timestamp(date.getTime())+".txt"));
out.write("some information");
out.close;
}catch(IOException e){
e.printStackTrace();
}
So in your code inplace of System.out.println(); statements you can use out.write()
statements to write to a text file.
Hope this helps you.