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.
Related
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 have one folder ("all_folders") which contains 5 sub folders ("folder_1","folder_2","folder_3","folder_4" and "folder_5" ).
Each of these sub-folders contains 2 text files having names like "file_1.txt" ,"file_2.txt" and so on.
Each of the text file contains address to the next file say "file_1.txt" content is GOTO "file_2.txt".
In the same manner a file can have multiple address and those file in turn can have address of other files.
Basically its like a binary tree.I want a user to input a file name for which he wants to know all the address the file he entered contains.
The output I want should be like a binary tree. I.e like file_10 contains address of file file_7 , file_8 and file_9.
Again file_9 contains address of file_6 and file_4.
file_8 contains address of file_5.
file_7 doesn't contain any address of file and so on....
I have attached the image of the output which I want and the files and folder i have.
Till now I have written the below code in which i am storing the address which file_10 contains (assuming user entered file_10) in a array list and able to print that.
But now I want this code to repeat till a file doesn't have any address (see image for the output required).
I am planning to use JTree to display output as a binary tree as shown in image.
But that is the second thing and first I need to get the output.
I need help on how we can repeatedly call function to show all file addresses.
Secondly I am using array list but my concern is , do I need to have as many array list as many level of parent child relationship I have in my tree.
Because at present I just only have 5 folders and 10 files but it may increase.so there will be lot many array list.
Can you please help me to achieve this output.
As this is a big code i have tried to write comments wherever possible but sorry as i might not be following good practices in the code as I am a beginner.
Output Image:
Attached all_folder files:
https://drive.google.com/open?id=0B9hvL6YZBpoTRkVYV0dUWEU5V2M
My Code is as below:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Scanner;
public class FindFile
{
String result;
static ArrayList<String> storeAllFileName = new ArrayList<String>(); // This array list will store all file names from all the sub-folders of all_folders
static int i = 0;
public void listFilesAndFilesSubDirectories(String directoryName)
{
File directory = new File(directoryName);
File[] fList = directory.listFiles();
for (File file : fList)
{
if (file.isFile())
{
if (file.getName().endsWith(".txt")) // Checking if the file is
// a text file
{
storeAllFileName.add(file.getName().toLowerCase());
i++;
}
} else if (file.isDirectory())
{
listFilesAndFilesSubDirectories(file.getAbsolutePath());
}
}
}
public static void main(String[] args) throws FileNotFoundException
{
recurrenceFileFind();
}
public static void recurrenceFileFind() throws FileNotFoundException
{
FindFile FindFile = new FindFile();
String fileName = "file_10.txt"; // Hardcoded this value assuming user
// have entered file_10.txt
final String directoryName = "C:\\all_folders"; // Hardcoded this value
// assuming all folder
// of user are placed in
// C:\all_folders
// directory
FindFile.listFilesAndFilesSubDirectories(directoryName);
FindFile.searchDirectory(new File(directoryName), fileName);
System.out.println("\nFile Found at: " + FindFile.getResult());
String filedirectoryName = FindFile.getResult(); // Passing the location
// of the file found
// at so that now we
// can read the text
// of the file and
// search for the
// address of child
// files
File file = new File(filedirectoryName);
Scanner in = new Scanner(file);
ArrayList<String> viewText = new ArrayList<String>(); // This array list
// will store the
// content of the
// file
while (in.hasNext())
{
viewText.add(in.next().toLowerCase()); // Store the content of file
// in a array list viewText
}
ArrayList<String> comparingList = new ArrayList<String>(viewText); // copy
// viewText
// array
// List
// to
// new
// array
// list
// comparingList
comparingList.retainAll(storeAllFileName); // store only those address
// in the comparingList for
// which we have file with
// that name in any of the
// sub-folder, as the file
// can have extra content
// like GOTO or any other
// words
System.out.println("\n\"" + file.getName() + "\"" + " contains below files:");
allListPrint(comparingList); // printing address of files which the
// parent file contains
}
public void searchDirectory(File directory, String fileNameToSearch)
{
if (directory.isDirectory())
{
search(directory, fileNameToSearch);
} else
{
System.out.println(directory.getAbsoluteFile() + " is not a directory!");
}
}
private void search(File directory, String fileNameToSearch)
{
if (directory.isDirectory())
{
System.out.println("Searching directory ... " + directory.getAbsoluteFile());
if (directory.canRead())
{
for (File temp : directory.listFiles())
{
if (temp.isDirectory())
{
search(temp, fileNameToSearch);
} else
{
if (fileNameToSearch.equalsIgnoreCase(temp.getName().toLowerCase()))
{
result = (temp.getAbsoluteFile().toString());
}
}
}
} else
{
System.out.println(directory.getAbsoluteFile() + "Permission Denied");
}
}
}
private static void allListPrint(ArrayList<String> List) // method to print
// array list
{
Iterator<String> itr = List.iterator();
while (itr.hasNext())
{
System.out.println(itr.next());
}
}
public String getResult()
{
return result;
}
}
Here is a recursive solution. I assume you can create HashMap<String,Node> from the directory of files yourself. I just manually created such HashMap to save time. But it's quite straightforward to do automatically. In one pass you read all files and create a Nodefor each file, and in the second pass you update their children field.
class Node {
String name;
List<Node> children = new ArrayList();
public Node(String name) {
this.name = name;
}
}
public class FileTree {
//recursive function for returning children
public void retChildHeirarchy(Node n) {
if (n == null) {
return;
}
for (Node child : n.children) {
retChildHeirarchy(child);
System.out.println(child.name);
}
}
public static void main(String[] args) {
HashMap<String, Node> treeStructure = new HashMap<>();
/*To save time, I manually create the nodes and update HashMap of Nodes
but you can do it automatically.
*/
Node f4 = new Node("file_4");
Node f6 = new Node("file_6");
Node f7 = new Node("file_7");
Node f8 = new Node("file_8");
Node f9 = new Node("file_9");
Node f10 = new Node("file_10");
//update f_10
f10.children.add(f9);
f10.children.add(f8);
f10.children.add(f7);
//update f9
f9.children.add(f6);
f9.children.add(f4);
treeStructure.put("file_4", f4);
treeStructure.put("file_6", f6);
treeStructure.put("file_7", f7);
treeStructure.put("file_8", f8);
treeStructure.put("file_9", f9);
treeStructure.put("file_10", f10);
FileTree ft = new FileTree();
//call the recursive function for the Node that you want:
ft.retChildHeirarchy(f9);
}
}
An the output is as follows. Note for f10 the recursive function works ok, but when manually updating f10 I didn't add 5, 2 3, and 1 to the list of its children.
ft.retChildHeirarchy(f9);
file_6
file_4
ft.retChildHeirarchy(f10);
file_6
file_4
file_9
file_8
file_7
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().
I am using java jwi API for searching the wordnet to get the synonyms of a word. The problem is that it only gives me one result the word to find its synonyms itself. Please guide me. Is it possible to get the list of all possible synonyms of a given word? My code is:
public void searcher() {
try {
url = new URL("file", null, path);
dict = new Dictionary(url);
try {
dict.open();
} catch (IOException ex) {
JOptionPane.showMessageDialog(null, "Dictionary directory does not exist\n" + ex + "\nClass:Meaning Thread", "Dictionary Not Found Error", JOptionPane.ERROR_MESSAGE);
}
IIndexWord idxWord = dict.getIndexWord("capacity", POS.NOUN);
IWordID wordID = idxWord.getWordIDs().get(0);
IWord word = dict.getWord(wordID);
//Adding Related Words to List of Realted Words
ISynset synset = word.getSynset();
for (IWord w : synset.getWords()) {
System.out.println(w.getLemma());
}
} catch (Exception e) {
}
}
The output is only:
capacity
itself! The actual synonyms must be:
capability
capacitance
content
electrical capacitance
mental ability...(so on)
So is there anything I missed in the code or can somebodygive me any ideas what is the real problem?
Thanks in advance
So, here comes the answer i use Java JAWS for wordnet searching! The steps are:
1- Download WordNet Dictionary from
Here
2- Install WordNet
3- Go to Installed Directory and copied the WordNet Directory (in my case C:\Program Files (x86) was the Directory for WordNet Folder)
4- Pasted it into my Java Project (under MyProject>WordNet)
5- Making Path to the directory as:
File f=new File("WordNet\\2.1\\dict");
System.setProperty("wordnet.database.dir", f.toString());
6- Got Synonyms as:
public class TestJAWS{
public static void main(String[] args){
String wordForm = "capacity";
// Get the synsets containing the word form=capicity
File f=new File("WordNet\\2.1\\dict");
System.setProperty("wordnet.database.dir", f.toString());
//setting path for the WordNet Directory
WordNetDatabase database = WordNetDatabase.getFileInstance();
Synset[] synsets = database.getSynsets(wordForm);
// Display the word forms and definitions for synsets retrieved
if (synsets.length > 0){
ArrayList<String> al = new ArrayList<String>();
// add elements to al, including duplicates
HashSet hs = new HashSet();
for (int i = 0; i < synsets.length; i++){
String[] wordForms = synsets[i].getWordForms();
for (int j = 0; j < wordForms.length; j++)
{
al.add(wordForms[j]);
}
//removing duplicates
hs.addAll(al);
al.clear();
al.addAll(hs);
//showing all synsets
for (int i = 0; i < al.size(); i++) {
System.out.println(al.get(i));
}
}
}
}
else
{
System.err.println("No synsets exist that contain the word form '" + wordForm + "'");
}
}
The Thing is you must have jaws-bin.jar
What you are getting is "capacity#1", which has the meaning of "capability to perform or produce", and it does indeed only have one synonym. (Play around with the PWN search page to get a feel for how WordNet organizes the words into synsets.)
It sounds like what you are after is the union of all synonyms in all the synsets? I think you either use getSenseEntryIterator(), or simply put a loop around idxWord.getWordIDs().get(0);, replacing the 0 with the loop counter, so you are not only ever getting the first item in the array.
If you want to use JWI and want to fetch more than 1 synonym then change your code from this exact spot:
IIndexWord idxWord = dict.getIndexWord(inputWord, POS.NOUN);
try {
int x = idxWord.getTagSenseCount();
for (int i = 0; i < x; i++) {
IWordID wordID = idxWord.getWordIDs().get(i);
IWord word = dict.getWord(wordID);
// Adding Related Words to List of Realted Words
ISynset synset = word.getSynset();
for (IWord w : synset.getWords()) {
System.out.println(w.getLemma());
// output.add(w.getLemma());
}
}
} catch (Exception ex) {
System.out.println("No synonym found!");
}
It works perfectly fine.