navigate directory structure and name each processed file uniquely - java

I have a directory structure of the form start/one/two/three/*files*
My goal is to construct this program such that it can navigate my directory structure autonomously, grab each file then process it, which it seems to be doing correctly.
BUT I also need the output to be written to a new file with a unique name, i.e. the file named 00001.txt should be processed and the results should be written to 00001_output.txt
I thought I implemented that correctly but, apparently not.
Where have I gone astray?
String dirStart = "/home/data/";
Path root = Paths.get(dirStart);
Files.walkFileTree(root.toAbsolutePath().normalize(), new SimpleFileVisitor<Path>()
{
#Override
public FileVisitResult visitFile(Path file, java.nio.file.attribute.BasicFileAttributes attrs) throws IOException
{
try(InputStream inputStream = Files.newInputStream(file);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)))
{
// CHANGE OUTPUT TO NEW FILE
String print_file = file.getFileName().toString();
String fileNameWithOutExt = FilenameUtils.removeExtension(print_file);
System.out.println(fileNameWithOutExt);
PrintStream out = new PrintStream(new FileOutputStream( fileNameWithOutExt + "_output.txt" ) );
System.setOut(out);
// SOUP PART
StringBuilder sb = new StringBuilder();
String line = bufferedReader.readLine();
while (line != null)
{
sb.append(line);
sb.append(System.lineSeparator());
line = bufferedReader.readLine();
}
String everything = sb.toString();
Document doc = Jsoup.parse(everything);
String link = doc.select("block.full_text").text();
System.out.println(link);
}
catch (IOException e)
{
e.printStackTrace();
}
return FileVisitResult.CONTINUE;
}
});
This is also my question, it might give some additional insight on what I'm actually trying to do.

System.setOut seems like a bad idea.
Below is some untested code which might work.
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import org.apache.commons.io.FilenameUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
public class App {
public static void main(String[] args) throws IOException {
String dirStart = "/home/data/";
Path root = Paths.get(dirStart);
Files.walkFileTree(root.toAbsolutePath().normalize(), new SimpleFileVisitor<Path>() {
#Override
public FileVisitResult visitFile(Path file, java.nio.file.attribute.BasicFileAttributes attrs) throws IOException {
// CHANGE OUTPUT TO NEW FILE
String print_file = file.getFileName().toString();
String fileNameWithOutExt = FilenameUtils.removeExtension(print_file);
System.out.println(fileNameWithOutExt);
// SOUP PART
String everything = new String(Files.readAllBytes(file), StandardCharsets.UTF_8);
Document doc = Jsoup.parse(everything);
String link = doc.select("block.full_text").text();
try (PrintStream out = new PrintStream(new FileOutputStream(fileNameWithOutExt + "_output.txt"))) {
out.println(link);
} catch (IOException e) {
e.printStackTrace();
}
return FileVisitResult.CONTINUE;
}
});
}
}

Related

Is there a standard way to transform a String into a File considerning the possibility of a URL/URI formatted input String

I would like to obtain the most accurate File typed representation of a String that is supposed to refer to a local (existing) file in one of several forms like:
String file0 = "/home/my_user/file.txt"
String file1 = "file:///home/my_user/file.txt"
String file2 = "file.txt"; // assuming that the working dir is /home/my_user.
Is there a (quasy) single liner using the standard library or perhaps a common third party like apache-commons that would do the trick?
Thanks.
You can define your own function for this purpose. Given below is the function definition and test code:
import java.io.File;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
public class Main {
public static void main(String[] args) {
String file0 = "/Users/arvind.avinash/file.txt";
String file1 = "file:///Users/arvind.avinash/file.txt";
String file2 = "file.txt"; // assuming that the working dir is /Users/arvind.avinash.
System.out.println(getFile(file0).exists());
System.out.println(getFile(file1).exists());
System.out.println(getFile(file2).exists());
}
static File getFile(String pathOrUri) {
URI uri;
File file = null;
try {
uri = new URL(pathOrUri).toURI();
} catch (MalformedURLException e) {
return new File(pathOrUri);
} catch (URISyntaxException e) {
return new File(pathOrUri);
}
if (uri != null) {
file = new File(uri);
}
return file;
}
}
Output:
true
true
true
[Update]
Given below is a more simplified version:
import java.io.File;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
public class Main {
public static void main(String[] args) {
String file0 = "/Users/arvind.avinash/file.txt";
String file1 = "file:///Users/arvind.avinash/file.txt";
String file2 = "file.txt"; // assuming that the working dir is /Users/arvind.avinash.
System.out.println(getFile(file0).exists());
System.out.println(getFile(file1).exists());
System.out.println(getFile(file2).exists());
}
static File getFile(String pathOrUri) {
URI uri;
try {
uri = new URL(pathOrUri).toURI();
} catch (MalformedURLException | URISyntaxException e) {
return new File(pathOrUri);
}
return new File(uri);
}
}
You be able to call new File(x) on examples 1 and 3 and it should work.
As for #2, you can create a URI, and then create File from that. In fact I think they all probably will work using URI
String fileStr = "file:///home/my_user/file.txt";
try {
URI uri = new URI(fileStr);
File f = new File(uri);
} catch (URISyntaxException ex) { ...}

update a csv file after 1 hour in java

I have made a thread in java which continuously checks the recent items in the windows after a time interval of 1 hour and make a .csv file of all of the recent items. Moreover i have accesstime and folder location of all of the files in the recent items. Now what i am trying to do is as recent items continuously update itself so if there is a new file in the recent item it should append at the end of that already made csv file but i am stuck here and have no idea how to do that kindly help me My code is here
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package record;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributeView;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileTime;
import static java.sql.DriverManager.println;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import sun.awt.shell.ShellFolder;
/**
*
* #author zeeshan
*/
public class Record
{
static String user=System.getProperty("user.name");
static String path1="C:\\Users\\"+user+"\\AppData\\Roaming\\Microsoft\\Windows\\Recent\\";
static String path2="C:\\Users\\Fa16Rcs028\\Dropbox\\Spring 17\\Special Topics In HCI\\Sir Aimal Project\\output.csv";
static PrintWriter pw;
static StringBuilder sb = new StringBuilder();
public void createcsv()throws IOException
{
File directory = new File(path1);
File[] fList = directory.listFiles();
pw = new PrintWriter(new File(path2));
sb.append("File/Folder Name");
sb.append(',');
sb.append("Access Time");
sb.append(',');
sb.append("File Location");
sb.append('\n');
for (int i=0;i<fList.length;i++)
{
String filename=fList[i].getName();
String actualfilename=filename.replace(".lnk", "");
ShellFolder sf = ShellFolder.getShellFolder(fList[i]);
ShellFolder target = sf.getLinkLocation();
if (target != null)
{
Path p = Paths.get(path1+filename);
BasicFileAttributes view= Files.getFileAttributeView(p, BasicFileAttributeView.class).readAttributes();
FileTime fileTime=view.creationTime();
sb.append(actualfilename);
sb.append(',');
sb.append(new SimpleDateFormat("dd/MM/yyyy HH:mm:ss").format((fileTime.toMillis())));
sb.append(',');
sb.append(target.getAbsolutePath());
sb.append('\n');
}
}
pw.write(sb.toString());
pw.close();
}
public static class maintainrecord extends Thread
{
#Override
public void run()
{
File directory = new File(path1);
File[] fList = directory.listFiles();
for (File fList1 : fList) {
try {
String filename = fList1.getName();
String actualfilename=filename.replace(".lnk", "");
Path p = Paths.get(path1+filename);
BasicFileAttributes view= Files.getFileAttributeView(p, BasicFileAttributeView.class).readAttributes();
FileTime fileTime=view.creationTime();
String time=new SimpleDateFormat("dd/MM/yyyy HH:mm:ss").format((fileTime.toMillis())).toString();
String line = "";
String cvsSplitBy = ",";
try (BufferedReader br = new BufferedReader(new FileReader(path2)))
{
while ((line = br.readLine()) != null)
{
String[] record = line.split(cvsSplitBy);
String name=record[0];
String checktime=record[1];
if(actualfilename.equals(name) && !time.equals(checktime))
{
br.close();
pw = new PrintWriter(new File(path2));
sb.append(actualfilename);
sb.append(',');
sb.append(actualfilename);
sb.append(',');
}
}
}
}catch (IOException ex)
{
Logger.getLogger(Record.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
public static void main(String[] args) throws IOException
{
Record r=new Record();
r.createcsv();
Thread zeeshan=new Thread(new maintainrecord());
zeeshan.start();
Thread.sleep(600000);
}
}

Print all content from multiple files in directory

I have the following code seen below, this code looks through a directory and then prints all of the different file names. Now my question is, how would I go about changing my code, so that it would also print out all of the content within the files which it finds/prints? As an example, lets say the code finds 3 files in the directory, then it would print out all the content within those 3 files.
import java.io.File;
import java.io.IOException;
public class EScan {
static String usernamePc = System.getProperty("user.name");
final static File foldersPc = new File("/Users/" + usernamePc + "/Library/Mail/V2");
public static void main(String[] args) throws IOException {
listFilesForFolder(foldersPc);
}
public static void listFilesForFolder(final File foldersPc) throws IOException {
for (final File fileEntry : foldersPc.listFiles()) {
if (fileEntry.isDirectory()) {
listFilesForFolder(fileEntry);
} else {
System.out.println(fileEntry.getName());
}
}
}
}
I tested it before posting. it is working.
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* #author EdwinAdeola
*/
public class TestPrintAllFiles {
public static void main(String[] args) {
//Accessing the folder path
File myFolder = new File("C:\\Intel");
File[] listOfFiles = myFolder.listFiles();
String fileName, line = null;
BufferedReader br;
//For each loop to print the content of each file
for (File eachFile : listOfFiles) {
if (eachFile.isFile()) {
try {
//System.out.println(eachFile.getName());
fileName = eachFile.getAbsolutePath();
br = new BufferedReader(new FileReader(fileName));
try {
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException ex) {
Logger.getLogger(TestPrintAllFiles.class.getName()).log(Level.SEVERE, null, ex);
}
} catch (FileNotFoundException ex) {
Logger.getLogger(TestPrintAllFiles.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
}
You may use Scanner to read the contents of the file
try {
Scanner sc = new Scanner(fileEntry);
while (sc.hasNextLine()) {
String s = sc.nextLine();
System.out.println(s);
}
sc.close();
} catch (Exception e) {
e.printStackTrace();
}
You can try one more way if you find suitable :
package com.grs.stackOverFlow.pack10;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.Arrays;
import java.util.List;
public class EScan {
public static void main(String[] args) throws IOException {
File dir=new File("C:/your drive/");
List<File> files = Arrays.asList(dir.listFiles(f->f.isFile()));
//if you want you can filter files like f->f.getName().endsWtih(".csv")
for(File f: files){
List<String> lines = Files.readAllLines(f.toPath(),Charset.defaultCharset());
//processing line
lines.forEach(System.out::println);
}
}
}
Above code can me exploited in number of ways like processing line can be modified to add quotes around lines as below:
lines.stream().map(t-> "'" + t+"'").forEach(System.out::println);
Or print only error messages lines
lines.stream().filter(l->l.contains("error")).forEach(System.out::println);
Above codes and variations are tested.

how to remove empty line in a file in java

I am converting a pdf file to text and removing lines which have page number but the problem is that it leaving an empty space of 2 line.So i want to remove these spaces which have 2 or more empty line continuously but not if 1 line is empty.my code is :
// Open the file
FileInputStream fstream = new FileInputStream("C:\\Users\\Vivek\\Desktop\\novels\\Me1.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
String strLine;
String s=null;
//Read File Line By Line
while ((strLine = br.readLine()) != null) {
String pattern = "^[0-9]+[\\s]*$";
strLine=strLine.replaceAll(pattern, " ");
writeResult("C:\\Users\\Vivek\\Desktop\\novels\\doci.txt",strLine);
}
//Close the input stream
br.close();
}
public static void writeResult(String writeFileName, String text)
{
File log = new File(writeFileName);
try{
if(log.exists()==false){
System.out.println("We had to make a new file.");
log.createNewFile();
}
PrintWriter out = new PrintWriter(new FileWriter(log, true));
out.append(text );
out.println();
out.close();
}catch(IOException e){
System.out.println("COULD NOT LOG!!");
}
}
plz help me.
You can work with sequent empty line counter in your method like SkrewEverything suggested.
Or make a post-processing with regular expressions like this:
package testingThings;
import java.awt.Desktop;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class EmptyLinesReducer {
public Path reduceEmptyLines(Path in) throws UnsupportedEncodingException, IOException {
Path path = Paths.get("text_with_reduced_empty_lines.txt");
String originalContent = new String(Files.readAllBytes(in), "UTF-8");
String reducedContent = originalContent.replaceAll("(\r\n){2,}", "\n\n");
Files.write(path, reducedContent.getBytes());
return path;
}
public Path createFileWithEmptyLines() throws IOException {
Path path = Paths.get("text_with_multiple_empty_lines.txt");
PrintWriter out = new PrintWriter(new FileWriter(path.toFile()));
out.println("line1");
//empty lines
out.println();
out.println();
out.println();
out.println("line2");
//empty lines
out.println();
out.println("line3");
//empty lines
out.println();
out.println();
out.println();
out.println();
out.println();
out.println("line4");
out.close();
return path;
}
public static void main(String[] args) throws UnsupportedEncodingException, IOException {
EmptyLinesReducer app = new EmptyLinesReducer();
Path in = app.createFileWithEmptyLines();
Path out = app.reduceEmptyLines(in);
// open the default program for this file
Desktop.getDesktop().open(out.toFile());
}
}

ArrayList Menu Java

I need to make a menu that list the .txt files in a directory. For example, if i have jonsmith12.txt , lenovo123.txt , dell123.txt in the directory how would I make an arraylist menu of:
Please choose one of the following:
jonsmith12
lenovo123
dell123
Please enter your choice:
I need an arraylist menu is because I don't know how many .txt files are in the directory at any given time.
import java.io.File;
public class ListFiles
{
public static void listRecord() {
// Directory path here
String path = ".";
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"))
{
System.out.println(files);
}
}
}
}
}
Here is the class that will display the information in the .txt file onto the console. It stills need some modifying too but I could probably figure that out.
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/**
* This program reads a text file line by line and print to the console. It uses
* FileOutputStream to read the file.
*
*/
public class DisplayRec {
public static void displayRecord() throws IOException {
File file = new File("williamguo5.txt");
FileInputStream fis = null;
BufferedInputStream bis = null;
DataInputStream dis = null;
try {
fis = new FileInputStream(file);
// Here BufferedInputStream is added for fast reading.
bis = new BufferedInputStream(fis);
dis = new DataInputStream(bis);
// dis.available() returns 0 if the file does not have more lines.
while (dis.available() != 0) {
// this statement reads the line from the file and print it to
// the console.
System.out.println(dis.readLine());
}
// dispose all the resources after using them.
fis.close();
bis.close();
dis.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
So the question is: How do I implement a ArrayList menu into my ListFiles class so it will display the .txt files.
You can use the alternate method signature for File.listFiles(FilenameFilter filter) to simplify your code:
File[] files = dir.listFiles(new FilenameFilter() {
#Override
public boolean accept(File dir, String name) {
return name.toLowerCase().endsWith(".txt");
}
});
And unless you really enjoy writing loops, you don't even need to manually loop over the array to convert it to a List:
List<File> lstRecords = Arrays.asList(files);
Your displayRecord method was pretty close; you just needed to pass the file as an argument and use that instead of a hard-coded filename, and you needed to initialize dis.
Putting it all together:
package com.example.file;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
public class FileExample {
public static List<File> listRecords(File dir) {
File[] files = dir.listFiles(new FilenameFilter() {
#Override
public boolean accept(File dir, String name) {
return name.toLowerCase().endsWith(".txt");
}
});
return Arrays.asList(files);
}
public static void displayRecord(File file) {
FileInputStream fis = null;
BufferedInputStream bis = null;
DataInputStream dis = null;
try {
fis = new FileInputStream(file);
// Here BufferedInputStream is added for fast reading.
bis = new BufferedInputStream(fis);
dis = new DataInputStream(bis);
String line = dis.readLine();
while (line != null) {
// this statement reads the line from the file and print it to
// the console.
System.out.println(line);
line = dis.readLine();
}
// dispose all the resources after using them.
fis.close();
bis.close();
dis.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* #param args
*/
public static void main(String[] args) {
List<File> lstRecords = listRecords(new File("."));
for (File record : lstRecords) {
displayRecord(record);
}
}
}
It's also better to use Reader/Writer instead of InputStream/OutputStream if you're working with text files, and you should close your files in the finally block to avoid a potential resource leak.
You'll also notice I didn't explicitly use an ArrayList. In most cases, it's better to program against the interface (in this case, List) as much as possible, and only declare variables using the implementing class when you need to use a method that's only available to that class.
It looks like your sticking point above is the array. If you just need to iterate over the files in a directory, something as simple as the following will do the trick.
import java.io.File;
public class TxtEnumerator {
public static void main(String[] args) {
TxtEnumerator te = new TxtEnumerator();
te.listFiles();
}
public void listFiles() {
String filepath = "." + File.separator + "textDirectory";
File file = new File(filepath);
if (file.isDirectory()) {
for (File f : file.listFiles()) {
if (f.getName().endsWith(".txt")) {
System.out.println(f.getName());
}
}
}
}
}

Categories