I am trying to create a Java app (with swing) which renames pdf files with a set naming convention. Currently the files are named:
1.pdf, 2.pdf...... 10.pdf, 11.pdf...... 20.pdf, 21.pdf etc.
So I decide to add a prefix (ABC_0) to the file name. The new file names should be:
ABC_01.pdf, ABC_02.pdf.... ABC_10.pdf, ABC_11.pdf...... ABC_20.pdf, ABC_21.pdf etc.
So far everything is working well. The only problem I am facing is that when the prefix gets added to a pdf file name with a number 10 and above, it's renamed as:
ABC_010.pdf, ABC_011.pdf...... ABC_020.pdf, ABC_021.pdf etc.
This is wrong. The 0 should only be added to the pdf file names with a number 1–9 in it.
Could you please help me?
This is the code that I need help with.
{
String dir= txt_src.getText();
String addPrefix= "ABC_0";
File dirFile,dirFile1;
File oldfile, newfile;
String newname;
String filenames[];
int i, count;
dirFile = new File(dir);
if (!dirFile.exists() || !dirFile.isDirectory())
{
message("File not exist or not a directory");
}
filenames = dirFile.list();
for(i = count = 0; i < filenames.length; i++)
{
if (filenames[i].equals(".")) continue;
if (filenames[i].equals("..")) continue;
dirFile1 = new File(dir+"\\"+filenames[i]);
if (!dirFile1.isDirectory())
{oldfile = new File(dirFile, filenames[i]);
newname = addPrefix + filenames[i];
newfile = new File(dirFile, newname);
message("Files Renamed Successfully");
if (oldfile.renameTo(newfile)) count++;
else
{
message("Unable to rename " + oldfile);
}
}
}
}
You can make sure that your filenames are padded with zeros like this:
public String pad(String fileName, int len) {
if (fileName.length() >= len) {
return fileName;
}
String padded = "0000000" + fileName; // Change the number of zeros to your needs
return padded.substring(padded.length() - len);
}
Then you just have to prepend "ABC_" to the padded value:
String newName = "ABC_" + pad(oldNmame, 6); // produce 6 characters per String
produces results like:
10.pdf gets ABC_10.pdf
1.pdf gets ABC_01.pdf
a.pdf gets ABC_0a.pdf
100.pdf gets ABC_100.pdf
a.a gets ABC_000a.a
remove 0 from addPrefix
String addPrefix= "ABC_0";
use this
String addPrefix= "ABC_";
updated this line
newname = addPrefix+i + filenames[i];
I would just create 2 different String variables and let it choose. Check if the number is less than 10, if it is, have it use the string with the 0 ABC_0
If it's greater than 10, use the string without the 0 ABC_
Check my little program. It reads the number before the extension ".pdf". If the number has a length of 1, add a 0 before adding a prefix.
String pdfNames[] = new String[] { "2.pdf", "6.pdf", "19.pdf", "26.pdf" };
String newNames[] = new String[pdfNames.length];
String prefix = "ABC_";
for (int i = 0; i < pdfNames.length; i++) {
String name = pdfNames[i].split(".pdf")[0];
System.out.println(name);
newNames[i] = prefix;
if (name.length() == 1)
newNames[i] += "0";
newNames[i] += name;
System.out.println(newNames[i]);
}
But think about the case you have with files named like 123, 1234 and so on. Then you have to add more than one 0.
EDIT
In your code
filenames = dirFile.list();
for(i = count = 0; i < filenames.length; i++)
{
...
you first fill your String array filenames with a list of file names ;-)
In the for loop you can get the length of the filename by filenames[i].split(".pdf")[0].length().
Related
I'm trying to read every file in a directory, clean up with java util.locale, then write to a new directory. The reading and writing methods work, the Locale.SPANISH might be the issue as I have read in other posts.
I iterated through the available languages in the java.util.locale, spanish was in there.
First, the array issue: the following extract of code below is the long way of entering the Locale.(LANGUAGE) into the array. This seems to work fine. However, I can't understand why the 'short' way doesn't seem to work.
String[] languageLocale = new String[fileArray.length];
languageLocale[0] = "Locale.ENGLISH";
languageLocale[1] = "Locale.FRENCH";
languageLocale[2] = "Locale.GERMAN";
languageLocale[3] = "Locale.ITALIAN";
languageLocale[4] = "Locale.SPANISH";
The short way:
String[] languageLocale = new String[("Locale.ENGLISH" , "Locale.FRENCH" , "Locale.GERMAN" , "Locale.ITALIAN" , "Locale.SPANISH")];
I need to input the Locale.(langauge) into a string so they can be called in the following:
File file = new File("\\LanguageGuessing5.0\\Learning\\");
File[] fileArray = file.listFiles();
ArrayList<String> words = new ArrayList<String>();
for (int i = 0; i < fileArray.length; i++) {
if (fileArray[i].isFile()) {
if (fileArray[i].isHidden()) {
continue;
} else {
String content = readUTF8File("\\LanguageGuessing5.0\\Learning\\"+fileArray[i].getName());
words = extractWords(content, languageLocale[i]);
outputWordsToUTF8File("\\LanguageGuessing5.0\\Model\\"+ fileArray[i].getName() + "out.txt", words);
}
} else if (fileArray[i].isDirectory()) {
System.out.println("Directory " + fileArray[i].getName());
}
}
The following method call:
words = extractWords(content, languageLocale[i]);
also presents the following error:
The method extractWords(String, Locale) in the type CleaningText(the class name) is not applicable for the arguments (String, String)
My understanding is that while the array argument is not a locale, the string holds the correct text to make it valid. I'm clearly incorrect, I'm hoping someone could explain how this works.
The input types of the methods are below for context:
public static String readUTF8File(String filePath)
public static ArrayList extractWords(String inputText, Locale currentLocale)
public static void outputWordsToUTF8File(String filePath, ArrayList wordList)
Many thanks in advance
For example I have data:
000001!1 |TEST 3 |18 01/22 01/23 |789
I will write the data based on specified col/index.
I had been search on internet for the alternative is using string format, but I have been rules that define the specified col on txt and the data.
the example of the rules are:
No.Record on col 1,
Name on col 12.
How I can do this?
Thank you..
I have some pseudo code that might help you for getting the formatted code in the text file ..this is some sort of tabular data
public static void main(String[] args) throws IOException {
File dir = new File("C:\\Test");
dir.mkdirs();
File file = new File(dir, "filename.txt");
FileWriter fileWriter = new FileWriter(file);
int SNIndexlength = "Serial_Number".length();
SNIndexlength = SNIndexlength-3+20;
fileWriter.write(String.format("%s %20s %20s \r\n", "Serial_Number", "Name", "Count"));
List<Data> datas = new ArrayList<Data>();
datas.add(new Data("001", "TEST1", 3));
datas.add(new Data("002", "TEST2", 5));
datas.add(new Data("003", "TEST3", 7));
datas.add(new Data("004", "TEST4", 10));
datas.add(new Data("005", "TEST5", 0));
for (Data data : datas) {
fileWriter.write(String.format("%s %"+SNIndexlength+"s %20s \r\n", data.sNum, data.name, data.count));
}
fileWriter.flush();
fileWriter.close();
}
static class Data{
public String sNum;
public String name;
public int count;
public Data(String no, String name, int count){
this.sNum = no;
this.name = name;
this.count = count;
}
}
I have updated the answer where I have changed the writing to text file as dynamic using a collection, Hope it may help.
It seems you have fixed sized records in text format. One can use a RandomAccessFile. Given the record length and column widths you then can calculate the absolute file position and overwrite bytes padded to the cell width.
This is rather awkward, might fit your use-case or not.
Pseudo-code:
public boolean editFile(AFileObject file, Integer line, Integer col, String value) {
file.openInReadMode();
// We write the results in a temporary file
AFileObject tempFile = AFileObject.getNewTempFile();
tempFile.openInWriteMode();
// We start looping until we'll reach the line to edit
for (int i = 0; ! file.eof() || i < line ; i++) {
tempFile.write(file.readLine());
}
// If we reached the end of file before, do nothing and returns false
if file.eof() {
file.close();
tempFile.delete();
return false;
}
// We edit the line here, then we write it in the temporary file
// in place of the original line
String lineToEdit = file.readLine();
lineToEdit = editLineColumn(lineToEdit, col, value);
tempFile.write(lineToEdit);
// Then we write the remaining lines
while (! file.eof()) {
tempFile.write(file.readLine());
}
// Work done. We just have now to close the files and
// Replace the source file by the temporary one
file.close();
tempFile.close();
tempFile.rename(file.getFileName());
return true;
}
private boolean String editLineColumn(String line, Integer col, String value) {
// Your code here :)
}
As you can see, it's pseudo-code. You'll have to look for the IO package which fits your needs (try with Java.IO one with FileReader and FileWriter objects for example). Start producing your own code, then we'll be able to help.
need your help to convert prn file to csv file using java.
Thank you so much.
Below is my prn file.
i would like to make it shows like this
Thank you so much.
In your example you have four entries as input, each in a row. In your result table they all are in one row. I assume the input describes a complete prn set. So if a file would contain n prn sets, it would have n * 4 rows.
To map the pm set to a csv file you have to
read in the entries from the input file
write a header row (with eight titles)
extract in each entry the relevant values
combine the extracted values from four entries in sequence to one csv row
write the row
repeat steps 3 to 5 as long as there are further entries
Here is my suggestion:
public class PrnToCsv {
private static final String DILIM_PRN = " ";
private static final String DILIM_CSV = ",";
private static final Pattern PRN_SPLITTER = Pattern.compile(DILIM_PRN);
public static void main(String[] args) throws URISyntaxException, IOException {
List<String> inputLines = Files.readAllLines(new File("C://Temp//csv/input.prn").toPath());
List<String[]> inputValuesInLines = inputLines.stream().map(l -> PRN_SPLITTER.split(l)).collect(Collectors.toList());
try (BufferedWriter bw = Files.newBufferedWriter(new File("C://Temp//csv//output.csv").toPath())) {
// header
bw.append("POL1").append(DILIM_CSV).append("POL1_Time").append(DILIM_CSV).append("OLV1").append(DILIM_CSV).append("OLV1_Time").append(DILIM_CSV);
bw.append("POL2").append(DILIM_CSV).append("POL2_Time").append(DILIM_CSV).append("OLV2").append(DILIM_CSV).append("OLV2_Time");
bw.newLine();
// data
for (int i = 0; i + 3 < inputValuesInLines.size(); i = i + 4) {
String[] firstValues = inputValuesInLines.get(i);
bw.append(getId(firstValues)).append(DILIM_CSV).append(getDateTime(firstValues)).append(DILIM_CSV);
String[] secondValues = inputValuesInLines.get(i + 1);
bw.append(getId(secondValues)).append(DILIM_CSV).append(getDateTime(secondValues)).append(DILIM_CSV);
String[] thirdValues = inputValuesInLines.get(i + 2);
bw.append(getId(thirdValues)).append(DILIM_CSV).append(getDateTime(thirdValues)).append(DILIM_CSV);
String[] fourthValues = inputValuesInLines.get(i + 3);
bw.append(getId(fourthValues)).append(DILIM_CSV).append(getDateTime(fourthValues));
bw.newLine();
}
}
}
public static String getId(String[] values) {
return values[1];
}
public static String getDateTime(String[] values) {
return values[2] + " " + values[3];
}
}
Some remarks to the code:
Using the nio-API you can read the whole file with one line of code.
To extract the values of an entry line I used a Pattern to split the line into an array with each single word as a value.
Then it is easy get the relevant values of an entry using the appropriate array indexes.
To write the csv file line by line (without additional libs) you can use a BufferedWriter.
The file you're writting to is a resource. It is recommended to use resources with the try-with-resource-statement.
I hope I could answer your question.
I'm looking for a snippet of code that does the following:
Given two list of string representing two files
For example,
FILE1 = {"SSome" , "SSimple", "TText", "FFile"}
FILE2 = {"AAnother", "TText", "FFile", "WWith", "AAdditional", "LLines"}
If I call diff(file1,file2)
The output would be the diff between FILE1 and FILE2:
*SSome|Another
-SSimple
TText
FFile
+WWith
+AAdditional
+LLines
Many thanks!
I gather from your question the following:
*word1|word2 - Means the word from file 1 was changed in file 2
-word - Means the word from file 1 was removed file 2
word - Means the word from file 1 remained the same in file 2
+word - Means the word wasn't originally in file 1, but was added to file 2
I figured file 1 is the "source" file and file 2 is the "destination" file for which we are showing these differences from. Having said that, try this algorithm (It's not perfect to DiffNow but it's pretty close):
public static void main(String[] args) throws Exception {
List<String> file1 = new ArrayList(Arrays.asList("Some", "Simple", "Text", "File"));
List<String> file2 = new ArrayList(Arrays.asList("Another", "Text", "File", "With", "Additional", "Lines"));
boolean diff = false;
int file2Index = 0;
for (int file1Index = 0; file1Index < file1.size();) {
if (!file1.get(file1Index).equals(file2.get(file2Index)) && !diff) {
diff = true;
// The word from file 1 was changed
System.out.println("*" + file1.get(file1Index) + "|" + file2.get(file2Index));
file1Index++;
file2Index++;
} else if (!file1.get(file1Index).equals(file2.get(file2Index)) && diff) {
// This word was removed from file 1
System.out.println("-" + file1.get(file1Index));
file1Index++;
} else {
System.out.println(file1.get(file1Index));
diff = false;
file1Index++;
file2Index++;
}
}
// Print what's left from file 2
for (; file2Index < file2.size(); file2Index++) {
System.out.println("+" + file2.get(file2Index));
}
}
Results:
*Some|Another
-Simple
Text
File
+With
+Additional
+Lines
Here is what I tried.
import java.util.*;
public class SetDemo
{
public static void main(String[] args){
String[] file1 = new String[]{"Some", "Simple", "Text", "File"};
String[] file2 = new String[]{"Another", "Text", "File", "With", "Additional", "Lines"};
Set<String> set1 = new HashSet<String>();
Set<String> set2 = new HashSet<String>();
for(String s: file1)
{
set1.add(s);
}
for(String s2: file2)
{
set2.add(s2);
}
Set<String> s1intercopy = new HashSet<String>(set1);
Set<String> s2intercopy = new HashSet<String>(set2);
s1intercopy.retainAll(s2intercopy); //Finds the intesection
Set<String> s1symdiffcopy = new HashSet<String>(set1);
Set<String> s2symdiffcopy = new HashSet<String>(set2);
s1symdiffcopy.removeAll(set2);
s2symdiffcopy.removeAll(set1);
int count = 0;
for(String s7: s1intercopy){
count++;
System.out.println(Integer.toString(count)+'.'+s7);
}
if (set1.size() > set2.size())
{
for(String s3: s1symdiffcopy){
count++;
System.out.println(Integer.toString(count)+'.'+'+'+s3);
}
for(String s4: s2symdiffcopy){
count++;
System.out.println(Integer.toString(count)+'.'+'-'+s4);
}
}else if (set2.size() > set1.size())
{
for(String s5: s2symdiffcopy){
count++;
System.out.println(Integer.toString(count)+'.'+'+'+s5);
}
for(String s6: s1symdiffcopy){
count++;
System.out.println(Integer.toString(count)+'.'+'-'+s6);
}
}
}
}
Output:
1.Text
2.File
3.+Lines
4.+Additional
5.+Another
6.+With
7.-Some
8.-Simple
I wasn't sure what you meant by *Some|Another, but what the above code does is simply find the intersection and the symmetric differences between the sets, determine which set is bigger, and assign '+' to the values which are part of the bigger set and '-' to those of the smaller set. I didn't read in from a file to save time but that part is easy and you can look that up. It seems based on your output that you were searching through one file and for each string in that file searching through the other file. This is pretty inefficient for large files so I believe the above solution optimizes that by saving it into sets and performing set operations.
In my current project I have to read a JavaScript file from the web and extract an object from it. The variable can vary from time to time, so I have to read it instead of hard coding it into my android app.
Say I want to extract the following variable (and parse the string using JSONObject after that, which is trivial):
var abc.xyz = {
"a": {"one", "two", "three"},
"b": {"four", "five"}
}
I have a problem with this. Do I have to implement some compiler-like scanner just to look for the name and get its value, or there is some existing tool I can use?
The JavaScript file is not as simple as this example. It contains a lot of other code. So a simple new JSONObject() or something will not do.
There are many libraries in Java to parse the JSON. There is a list on JSON.org
Read the file with Java
import org.json.JSONObject;
URL url = new URL("http://example.com/foo.js");
InputStream urlInputStream = url.openStream();
JSONObject json = new JSONObject(urlInputStream.toString());
Finally code it myself.
//remove comments
private String removeComment(String html){
String commentA = "/*";
String commentB = "*/";
int indexA, indexB;
indexA = html.indexOf(commentA);
indexB = html.indexOf(commentB);
while(indexA != -1 && indexB != -1 ){
html = html.substring(0, indexA) + html.substring(indexB + commentB.length());
indexA = html.indexOf(commentA);
indexB = html.indexOf(commentB);
}
return html;
}
//find variable with name varName
private String findVar(String varName, String html, char lBrace, char rBrace){
String tmp = html.substring(html.indexOf(varName));
tmp = tmp.substring(tmp.indexOf(lBrace));
int braceCount = 0;
int index = 0;
while(true){
if(tmp.charAt(index) == lBrace){
braceCount ++;
}else if(tmp.charAt(index) == rBrace){
braceCount --;
}
index ++;
if(braceCount == 0){
break;
}
}
return tmp.substring(0, index);
}