How to pass multiple files to another class?
I am developing an application which first compresses the image and after that it'll convert it into pdf.
The program which i have written works well seperately ie; it compresses the image and then in another project i use the path where the image are stores to convert it to pdf.
Now i want to have both these codes in the same project and i am encountering the problem where i am creating a loop where i pass the path name one by one. The source path works well but i need to specify the destination path which changes the name dynamically this where i am facing the problem. I have attached the code below please tell me what to do.
System.out.println("before convert");
Conversion cc = new Conversion();
File directory = new File(Success);
File[] files = directory.listFiles();
if(files!=null)
{
for(File f:files){
String path = f.getName();
System.out.println("The Name of file is="+path);
cc.createPdf("path" , "output", true);
System.out.println("the file is ="+output+".pdf");
System.out.println("after convert");
}
}
In the above code i need to change the output file name dynamically here cc.createPdf("path" , "output", true);
A simple implementation would be to keep a counter outside loop and increment it before appending it to output file name
int counter = 0;
for(File f:files){
String path = f.getName();
System.out.println("The Name of file is="+path);
counter++; //increment the counter
cc.createPdf("path" , "output"+counter, true); // append it to output
System.out.println("the file is ="+output+".pdf");
System.out.println("after convert");
}
For more robustness, counter can be replaced by UUID generator, System time in milliseconds etc
Im guessing your having trouble getting a File object with a newly created .pdf extension, you will have to adapt this to your code but it should be pretty straight forward.
File inputFile = new File("c:\\myimage.png");
String fileName = inputFile.getName();
File pdfFile = new File(inputFile.getParent(), fileName.substring(0, fileName.indexOf(".")) +".pdf");
System.out.println(inputFile + " " + pdfFile);
I think you should keep things simple by just appending ".pdf" to the names. The fact that you are processing a directory ensures that the source file names are unique. Hence, the new ".pdf" names would also be unique.
Assuming your output files land in the same directory, it also becomes much easier to sort files by names and know immediately which ".pdf" files correlate to which source files.
So, your output file name simply becomes
String path = f.getName();
String output = path.substring(0, path.lastIndexOf('.')) + ".pdf";
Related
I don't get it - I'm trying to get the path of a file so that the file (an image) can be included as an attachment in an email.
My system consists of two parts - a web app and a jar. (actually three parts - a common shared jar containing DAOs etc.)
They're both built using maven.
They both contain this image in this path:
src/main/resources/logo_48.png
WebApp:
String logo1 = getClass().getClassLoader().getResource("logo_48.png").getPath();
This works perfectly - both on local (Windows) and Linux
Jar Application:
String logo1 = getClass().getClassLoader().getResource("logo_48.png").getPath(); //doesn't work
I've taken advice from here:
How to access resources in JAR file?
here:
Reading a resource file from within jar
here:
http://www.coderanch.com/t/552720/java/java/access-text-file-JAR
and others
Most answers offer to load the file as a stream etc. but I'm only wishing to get the path assigned to the String. Other resources have led me to hacking the code for hours only to find the end result doesn't work.
After so many instances of /home/kalton/daily.jar!logo_48.png does not exist errors I was frustrated and settled on the following workaround:
Copy the logo_48.png directly to the folder where the jar resides (/home/kalton/)
Alter my jar application code to:
String logo1 = "/home/kalton/logo_48.png";
And it works.
Could anyone show me the right way to get the PATH (as a String) of a file in the resources folder from a JAR that is not unpacked?
This issue was driving me crazy for weeks!
Thanks in advance.
KA.
Adding actual use code of 'path' for clarity of use:
public static MimeMultipart assemble4SO(String logoTop, String emailHTMLText) throws MessagingException, IOException {
MimeMultipart content = new MimeMultipart("related");
String cid = Long.toString(System.currentTimeMillis());
String cidB = cid + "b";
String cssStyle = "";
String body = "<html><head>" + cssStyle + "</head><body><div>" + "<img src='cid:" + cid + "'/>" + emailHTMLText + "<img src='cid:" + cidB + "'/></div></body></html>";
MimeBodyPart textPart = new MimeBodyPart();
textPart.setContent(body, "text/html; charset=utf-8");
content.addBodyPart(textPart);
//add an inline image
MimeBodyPart imagePart = new MimeBodyPart();
imagePart.attachFile(logoTop);
imagePart.setContentID("<" + cid + ">");
imagePart.setDisposition(MimeBodyPart.INLINE);
content.addBodyPart(imagePart);
.............
From the top…
A .jar file is actually a zip file. A zip file is a single file that acts as an archive. The entries in this archive are not separate files, they're just sequences of compressed bytes within the zip file. They cannot be accessed as individual file names or File objects, ever.
Also important: The getPath method of the URL class does not convert a URL to a file name. It returns the path portion of the URL, which is just the part after the host (and before any query and/or fragment). Many characters are illegal in URLs, and need to be “escaped” using percent encoding, so if you just extract the path directly from a URL, you'll often end up with something containing percent-escapes, which therefore is not a valid file name at all.
Some examples:
String path = "C:\\Program Files";
URL url = new File(path).toURI().toURL();
System.out.println(url); // prints file:/C:/Program%20Files
System.out.println(url.getPath()); // prints /C:/Program%20Files
File file = new File(url.getPath());
System.out.println(file.exists()); // prints false, because
// "Program%20Files" ≠ "Program Files"
String path = "C:\\Users\\VGR\\Documents\\résumé.txt";
URL url = new File(path).toURI().toURL();
// Prints file:/C:/Users/VGR/Documents/r%C3%A9sum%C3%A9.txt
System.out.println(url);
// Prints /C:/Users/VGR/Documents/r%C3%A9sum%C3%A9.txt
System.out.println(url.getPath());
File file = new File(url.getPath());
System.out.println(file.exists()); // prints false, because
// "r%C3%A9sum%C3%A9.txt" ≠ "résumé.txt"
Based on your edit, I see that the real reason you want a String is so you can call MimeBodyPart.attachFile. You have two options:
Do the work of attachFile yourself:
URL logo = getClass().getLoader().getResource("logo_48.png");
imagePart.setDataHandler(new DataHandler(logo));
imagePart.setDisposition(Part.ATTACHMENT);
Copy the resource to a temporary file, then pass that file:
Path logoFile = Files.createTempFile("logo", ".png");
try (InputStream stream =
getClass().getLoader().getResourceAsStream("logo_48.png")) {
Files.copy(stream, logoFile, StandardCopyOption.REPLACE_EXISTING);
}
imagePart.attachFile(logoFile.toFile());
As you can see, the first option is easier. The second option also would require cleaning up your temporary file, but you don't want to do that until you've sent off your message, which probably requires making use of a TransportListener.
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
My problem is very simple and yet I can't figure out how to solve it.
I have text files in a folder:
"C:/aaa/bbb/ccc/ddd/test.txt"
And excel files in a folder within the text files folder:
"C:/aaa/bbb/ccc/ddd/excelFiles/test.xls"
Both text and excel files have the same name.
I would like to be able to access the path of those excel files.
What I did is:
this.file.getParent()+"\\"+"excelFiles"+"\\"+file.getName().substring(0, fileName.indexOf('.'))+".xls"
I get a "String index out of range" error.
Thank you for your help :)
If I understand your question, one option is to use File.getCanonicalPath() like,
try {
File f = new File("C:/aaa/bbb/ccc/ddd/excelFiles/test.xls");
System.out.println(f.getCanonicalPath());
} catch (IOException e) {
e.printStackTrace();
}
You might want to try this ->
String dynamicExcelFileName = file.getName().substring(0, fileName.indexOf('.'))
into a variable and use it in the path for accessing the excel file.
this way you get to be extra sure to check if the path is properly captured in variable or not and thus less chances of getting index out of range error.
plus the code is more readable
Looking at your snippet, I can see that you're accessing the file's name in two different ways:
file.getName().substring(...)
and
fileName.indexOf(...).
Are you sure that fileName is not empty when you try to determine the index of the dot?
this.file.getParent()+"\"+"excelFiles"+"\"+file.getName().substring(0, this.file.getName().indexOf('.'))+".xls"
This could be achieved quite easily, even without using existing libraries like FileUtils.
These three method can create the corresponding Excel File object for your text object
private File getExcelFile(final File txtFile) throws IOException {
final String path = txtFile.getCanonicalPath();
final String directory = path.substring(0, path.lastIndexOf(System.getProperty("file.separator")));
return new File(getExcelSubdirectory(directory), getExcelFilename(txtFile.getName()));
}
private File getExcelSubdirectory(final String parent) {
return new File(parent, "excelFiles");
}
private static String getExcelFilename(final String filename) {
return filename.substring(0, filename.lastIndexOf('.')) + ".xls";
}
If you use them like this:
File txt = new File("C:/aaa/bbb/ccc/ddd/test.txt");
System.out.println(txt.getCanonicalPath());
File excel = getExcelFile(txt);
System.out.println(excel.getCanonicalPath());
.. it will print:
C:\aaa\bbb\ccc\ddd\test.txt
C:\aaa\bbb\ccc\ddd\excelFiles\test.xls
I am writing a program in Java where the output is written to a .txt file. Each time I run the program the file is overwritten. I do not want to use the append switch and add data to the file.
I would like to have it so a new file, with the same name, is created each time I run the program. For example, if overflow.txt is the file name, and I run the program three times, the files overflow(1).txt, overflow(2).txt, and overflow(3).txt should be made.
How can this be achieved?
Check if the file exists, if so rename it. Using File.exists and FileUtils.moveFile
You would need to do this recursively until no conflict is found.
Check if the file exists first. If so, modify the name.
String origName = "overflow";
String ext = ".txt";
int num = 1;
file = new File(origName + ext);
while (file.exists()) {
num++;
file = new File(myOrigFileName +"(" + num + ")" + ext);
}
Modify depending on actual requirements. Question is not very clear.
"A new file with the same name" doesn't make sense in most file systems.
In your example, you've got three files with different names:
overflow(1).txt
overflow(2).txt
overflow(3).txt
The bit in brackets is still part of the name. If you want to emulate that behaviour, you'll have to:
Detect the presence of the "plain" filename (if you want to write to that if it doesn't exist)
Start counting at 1, and work out the "new" filename each time by removing the extension, adding the count in brackets, then putting the extension back
Keep counting until you find a filename which doesn't exist
String dirPath = "./";
String fileName = dirPath + "overflow.txt";
if(new File(dirPath + fileName).exist())
{
int counter = 0;
while(new File(dirPath + "overflow(" + ++counter + ").txt").exist());
fileName = "overflow(" + counter + ").txt";
}
When you instanciate the File object, verify if it exists, if it does, just rename it by adding the braces and number, and check again.
In my Java Spring web app I am creating an image file. This file gets a temporary name and later on I try to rename it using:
public void rename(String productFilename){
String newProductFilename = "newfile.jpg";
File input = new File(imageDir + "/products/" + productFilename);
File output = new File(imageDir + "/products/" + newProductFilename);
Boolean checkRename = input.renameTo(output);
}
For creating the temp file, I'm using:
public String generate(){
String productFilename = "filename.jpg";
ImageIO.write(out, imageFileType, new File(imageDir + "/products/" + productFilename));
return productFilename;
}
the value of imageDir is: /var/images
Throughout the class, the imageDir variable is set to an absolute path. The strange thing is that this all works great on Windows, but when running on Linux, I get a FileNotFoundException.
I'm 100% sure that the file exists. Any clue on what I'm doing wrong?
I found the solution. The filenames needed to be trimmed to be recognised in Linux. This, however, worked without trimming in Windows.