I'm having a problem getting all the selected files deleted. What I'm trying to do is after clicking "Add" whatever files are selected are moved to a new folder and are deleted in their previous folder. One file works fine. It deletes and moves the file. But more than one and only the first gets deleted. My loop is recognizing each file just not deleting them. I'm posting the actionevent. If more code is needed let me know. I've indicated where the problem is, so I think, so you don't have to search the code.
public void actionPerformed(ActionEvent e) {
int returnValue = 0;
int option = 0;
File[] selectedFiles = new File[0];
if (e.getActionCommand().equals("CLOSE")) System.exit(0);
else if (e.getActionCommand().equals("ADD")) {
JFileChooser chooser = new JFileChooser();
chooser.setMultiSelectionEnabled(true);
returnValue = chooser.showOpenDialog(this);
if (returnValue == JFileChooser.APPROVE_OPTION) {
File[] file = chooser.getSelectedFiles();
try {
FileInputStream fstream = null;
FileOutputStream ostream = null;
for (int i = 0; i < file.length; i++) {
fstream = new FileInputStream(file[i]);
ostream = new
FileOutputStream(file[i].getName());
Path path = Paths.get(file[i].getPath());
byte[] fileArray;
fileArray = Files.readAllBytes(path);
listModel.add(0, file[i].getName());
selectedFilesList.setModel(listModel);
//ostream.write(fileArray, 0, fileArray.length);
}
fstream.close();
//ostream.close();
try {
for(int i = 0; i < file.length; i++) {
//**----------------------->>>PROBLEM**
Files.delete(Paths.get(file[i].getPath()));
System.out.println(file[i].getName());
}
} catch (NoSuchFileException x) {}
System.err.format("%s: no such" + " file or directory%n")
} catch (DirectoryNotEmptyException x) {
System.err.format("%s not empty%n");
} catch (IOException x) {
// File permission problems are caught here.
System.err.println(x);
} catch (Exception err) {
}
}
This could be caused by you failing to close your file streams in the first loop.
for (int i = 0; i < file.length; i++) {
fstream = new FileInputStream(file[i]);
ostream = new
FileOutputStream(file[i].getName()); // This is never closed
Path path = Paths.get(file[i].getPath());
byte[] fileArray;
fileArray = Files.readAllBytes(path);
listModel.add(0, file[i].getName());
selectedFilesList.setModel(listModel);
//ostream.write(fileArray, 0, fileArray.length);
}
fstream.close(); // Only the last input stream is closed
should be more like
for (int i = 0; i < file.length; i++) {
try {
fstream = new FileInputStream(file[i]);
ostream = new
FileOutputStream(file[i].getName());
Path path = Paths.get(file[i].getPath());
byte[] fileArray;
fileArray = Files.readAllBytes(path);
listModel.add(0, file[i].getName());
selectedFilesList.setModel(listModel);
//ostream.write(fileArray, 0, fileArray.length);
} finally {
fstream.close();
ostream.close();
}
}
Closing the same number of files you open.
This could be causing your problem by holding a lock on all but one of your files which would prevent deletion.
Also your catch exception block (last statement) does nothing with the error.
Don't move files like that!
If you are on Java 7, have at look at this page instead.
For older versions, use oldFile.renameTo(newFile).
EDIT: To understand why your code is not working, use a debugger. I would think your deletion loop is left because of an exception.
Related
I went through this tutorial to learn how to use Netbeans to create a GUI application to take information in on a form, be able to edit it, and save it to a JTable. I now want to expand what I learned to be able to write this JTable to a delimited text file and read it in at a later date to add more data. I have managed to successfully write the data to a file. The code for that is here and is executed through a menu event I created:
private void mnuSaveActionPerformed(java.awt.event.ActionEvent evt) {
int returnVal = fileChooser.showSaveDialog(this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
File file = fileChooser.getSelectedFile();
try {
FileWriter fw = new FileWriter(file.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw);
for (int i = 0; i < tblProduct.getRowCount(); i++) {
for (int j = 0; j < tblProduct.getColumnCount(); j++) {
bw.write((String) tblProduct.getModel().getValueAt(i, j) + "#");
}
bw.newLine();
}
bw.close();
fw.close();
} catch (IOException ex) {
System.out.println("problem accessing file" + file.getAbsolutePath());
}
} else {
System.out.println("File access cancelled by user.");
}
}
I have read many posts dealing with things such as StringTokenizer but I just can't seem to wrap my head around what approach to take. Any direction would be appreciated.
UPDATE:
#camickr: Wasn't working at first but I figured it out. I wasn't adding a "\n" when writing the file. I have updated my code and also added code to clear my Jtable when opening a new file. Let me know if there's anything that is not "good practice".
private void mnuOpenActionPerformed(java.awt.event.ActionEvent evt) {
String line;
DefaultTableModel model = (DefaultTableModel) tblProduct.getModel();
for (int i = tblProduct.getRowCount() - 1; i >= 0; i--) {
model.removeRow(i);
}
int returnVal = fileChooser.showOpenDialog(this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
File file = fileChooser.getSelectedFile();
try {
FileReader fr = new FileReader(file.getAbsoluteFile());
BufferedReader br = new BufferedReader(fr);
while ((line = br.readLine()) != null) {
model.addRow(line.split("#"));
}
br.close();
fr.close();
} catch (IOException ex) {
System.out.println("problem accessing file" + file.getAbsolutePath());
}
} else {
System.out.println("File access cancelled by user.");
}
}
Here is what my test textfile looks like as generated:
Test1#Electronic#23.50#
Test2#Art#100.00#
Test3#Food#25.00#
Test4#Electronic#10.00#
Test5#Art#1.00#
Test6#Electricity#3.00#
Test7#Food#5.00#
Test8#Food#7.00#
Test9#Electronic#9.00#
Create an empty DefaultTableModel with your column names.
Then you can use the String.split(...) method to split each line of data.
Then you can use the addRow(...) method of the DefaultTableModel to add the data to the model.
Then can create your JTable with the DefaultTableModel.
I'm trying to convert a directory into tar file, which includes an empty sub-directory and sub-directories with some .json file, using Java's JTar. Folders that contain files are automatically included in the .tar file, but the empty folders are not.I want to create .tar file with all(empty and with data init) the sub directories.
My code is this way:
try
{
File tarFile = new File("somefilename.tar");
TarOutputStream tos = new TarOutputStream(new FileOutputStream(tarFile));
tartar("directoryname", tos);
tos.close();
}
catch (Exception e)
{
e.printStackTrace();
}
private static void tartar(String dir, TarOutputStream tos)
{
File f = new File(dir);
String[] flist = f.list();
int buffersize = 1024;
byte[] buf = new byte[buffersize];
for (int i = 0; i < flist.length; i++)
{
File f2 = new File(f, flist[i]);
if (f2.isDirectory())
{
tartar(f2.getPath(), tos);
continue;
}
try
{
FileInputStream fis = new FileInputStream(f2);
// TarEntry te = new TarEntry(f2.getPath());
TarEntry te = new TarEntry(f2, f2.getPath());
tos.putNextEntry(te);
int count = 0;
while ((count = fis.read(buf, 0, buffersize)) != -1)
{
tos.write(buf, 0, count);
}
// tos.closeEntry();
// tos.close();
fis.close();
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
While I have not worked with invoking tarball in Java, but in Linux you can run command "tar -cvzf file_name.tar.gz directory_name/" using Runtime, Process and ProcessBuilder API.
I have to accomplish a task of writing a set of data to file, use it, then overwrite it with new data. Thus overwrite of the file takes place repeatedly.I know i can accomplish the above by creating FileWriter object each time with the option to overwrite like below
FileWriter object = new FileWriter("fileName", false)
and close it to write to the file.
If i am supposed to overwrite the file n number of times , according to the above method i need to create n number of FileWriter objects. Is there any efficient way to overwrite a file repeatedly by only creating a single FileWriter object?
Not a direct answer, but anyway.
DON'T DO THAT!
What do you think will happen if for some reason writing the new data to the file fails?
You not only lose your original file, but also the new file contents...
Write the new content to another file, ensure that it is well written and closed, and then rename the new file atomically to the original file.
PS: and do not forget to correctly .close().
PS2: if you use Java 7, use the new Files API.
Its better to make a temp file and then rename the tempfile and delete the old like here:
public static void nachtragenTRA(File files) throws IOException{
Scanner sc=null;
File f= files;
String analyse = "";
String NTausgabe = "";
int max = 0;
int k = 0;
String updatedLine[] = new String [4];
int filenr = 1;
boolean sucess = false;
try{
sc= new Scanner(f);
}catch(FileNotFoundException x){
System.out.println("Error: File not found!");
}
while (sc.hasNextLine()){ //get next line
analyse = sc.nextLine();
max = analyse.length(); //get line lenght
StringBuffer sb = new StringBuffer(analyse); //write analyse in StringBuffer
//to change the string
if(k == 1)
{
sb.replace(Daten.NTdatapos[3],max, Daten.NTProbentypTextfield.getText());
updatedLine[0] =String.valueOf(sb);
}
else if(k == 2)
{
sb.replace(Daten.NTdatapos[4],max, Daten.NTPrueferTextfield.getText());
updatedLine[1] =String.valueOf(sb);
}
else if(k == 3)
{
sb.replace(Daten.NTdatapos[5],max, Daten.NTKundeTextfield.getText());
updatedLine[2] =String.valueOf(sb);
}
else if(k == 4)
{
sb.replace(Daten.NTdatapos[5],max, Daten.NTWerkstoffTextfield.getText());
updatedLine[3] =String.valueOf(sb);
}
if(k>3)
{
break;
}
k++;
}
sc.close();
//NTausgabe=DatenTextarea.getText()+"\n"+updatedLine[0]+"\n"+updatedLine[1];
//DatenTextarea.setText(String.valueOf(NTausgabe));
//NTausgabe=DatenTextarea.getText()+"\n"+NTKundeTextfield.getText()+"\n"+NTPrueferTextfield.getText();
//DatenTextarea.setText(String.valueOf(NTausgabe));
//create tmp file with the new data
PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(String.valueOf(f)+".tmp")));
BufferedReader br = null;
FileReader reader = null;
try {
reader = new FileReader(String.valueOf(f));
br = new BufferedReader(reader);
String line;
while ((line = br.readLine()) != null)
{
//Change speciffic lines
if(filenr == 2)
{
writer.println(updatedLine[0]);
}
else if(filenr == 3)
{
writer.println(updatedLine[1]);
}
else if(filenr == 4)
{
writer.println(updatedLine[2]);
}
else if(filenr == 5)
{
writer.println(updatedLine[3]);
}
//Andere Zeilen beibehalten
else
{
writer.println(line);
}
filenr = filenr + 1;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}finally{
reader.close();
br.close();
File realName = new File(String.valueOf(f));
realName.delete(); //delete old file
writer.close();
sucess = new File(String.valueOf(f)+".tmp").renameTo(realName); //rename tmp File to the others name
if(sucess != true)
{
NTausgabe=Daten.DatenTextarea.getText()+"\n"+"Rename File failed";
Daten.DatenTextarea.setText(String.valueOf(NTausgabe));
}
else
{
NTausgabe=Daten.DatenTextarea.getText()+"\n"+"File renamed sucessfully";
Daten.DatenTextarea.setText(String.valueOf(NTausgabe));
}
}
}
I have a directory that contains sequentially numbered log files and some Excel spreadsheets used for analysis. The log file are ALWAYS sequentially numbered beginning at zero, but the number of them can vary. I am trying to concatenate the log files, in the order they were created into a single text file which will be a concatenation of all the log files.
For instance, with log files foo0.log, foo1.log, foo2.log would be output to concatenatedfoo.log by appending foo1 after foo0, and foo2 after foo1.
I need to count all the files in the given directory with the extension of *.log, using the count to drive a for-loop that also generates the file name for concatenation. I'm having a hard time finding a way to count the files using a filter...none of the Java Turtorials on file operations seem to fit the situation, but I'm sure I'm missing something. Does this approach make sense? or is there an easier way?
int numDocs = [number of *.log docs in directory];
//
for (int i = 0; i <= numberOfFiles; i++) {
fileNumber = Integer.toString(i);
try
{
FileInputStream inputStream = new FileInputStream("\\\\Path\\to\\file\\foo" + fileNumber + ".log");
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
try
{
BufferedWriter metadataOutputData = new BufferedWriter(new FileWriter("\\\\Path\\to\\file\\fooconcat.log").append());
metadataOutputData.close();
}
//
catch (IOException e) // catch IO exception writing final output
{
System.err.println("Exception: ");
System.out.println("Exception: "+ e.getMessage().getClass().getName());
e.printStackTrace();
}
catch (Exception e) // catch IO exception reading input file
{
System.err.println("Exception: ");
System.out.println("Exception: "+ e.getMessage().getClass().getName());
e.printStackTrace();
}
}
how about
public static void main(String[] args){
final int BUFFERSIZE = 1024 << 8;
File baseDir = new File("C:\\path\\logs\\");
// Get the simple names of the files ("foo.log" not "/path/logs/foo.log")
String[] fileNames = baseDir.list(new FilenameFilter() {
#Override
public boolean accept(File dir, String name) {
return name.endsWith(".log");
}
});
// Sort the names
Arrays.sort(fileNames);
// Create the output file
File output = new File(baseDir.getAbsolutePath() + File.separatorChar + "MERGED.log");
try{
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(output), BUFFERSIZE);
byte[] bytes = new byte[BUFFERSIZE];
int bytesRead;
final byte[] newLine = "\n".getBytes(); // use to separate contents
for(String s : fileNames){
// get the full path to read from
String fullName = baseDir.getAbsolutePath() + File.separatorChar + s;
BufferedInputStream in = new BufferedInputStream(new FileInputStream(fullName),BUFFERSIZE);
while((bytesRead = in.read(bytes,0,bytes.length)) != -1){
out.write(bytes, 0, bytesRead);
}
// close input file and ignore any issue with closing it
try{in.close();}catch(IOException e){}
out.write(newLine); // seperation
}
out.close();
}catch(Exception e){
throw new RuntimeException(e);
}
}
This code DOES assume that the "sequential naming" would be zero padded such that they will lexigraphically (?? sp) sort correctly. i.e. The files would be
0001.log (or blah0001.log, or 0001blah.log etc)
0002.log
....
0010.log
and not
1.log
2.log
...
10.log
The latter pattern will not sort correctly with the code I have given.
Here's some code for you.
File dir = new File("C:/My Documents/logs");
File outputFile = new File("C:/My Documents/concatenated.log");
Find the ".log" files:
File[] files = dir.listFiles(new FilenameFilter() {
#Override
public boolean accept(File file, String name) {
return name.endsWith(".log") && file.isFile();
}
});
Sort them into the appropriate order:
Arrays.sort(files, new Comparator<File>() {
#Override
public int compare(File file1, File file2) {
return numberOf(file1).compareTo(numberOf(file2));
}
private Integer numberOf(File file) {
return Integer.parseInt(file.getName().replaceAll("[^0-9]", ""));
}
});
Concatenate them:
byte[] buffer = new byte[8192];
OutputStream out = new BufferedOutputStream(new FileOutputStream(outputFile));
try {
for (File file : files) {
InputStream in = new FileInputStream(file);
try {
int charCount;
while ((charCount = in.read(buffer)) >= 0) {
out.write(buffer, 0, charCount);
}
} finally {
in.close();
}
}
} finally {
out.flush();
out.close();
}
By having the log folder as a File object, you can code like this
for (File logFile : logFolder.listFiles()){
if (logFile.getAbsolutePath().endsWith(".log")){
numDocs++;
}
}
to find the number of log files.
I would;
open the output file once. Just use a PrintWriter.
in a loop ...
create a File for each possible file
if it doesn't exist break the loop.
Using a BufferedReader
to read the lines of the file with readLine()
write each line to the output file.
You should be able to do this with about 12 lines of code. I would pass the IOExceptions to the caller.
You can use SequenceInputStream for concatenation of FileInputStreams.
To see all log files File.listFiles(FileFilter) can be used.
It will give you unsorted array with files. To sort files in right order, use Arrays.sort.
Code example:
static File[] logs(String dir) {
File root = new File(dir);
return root.listFiles(new FileFilter() {
#Override
public boolean accept(File pathname) {
return pathname.isFile() && pathname.getName().endsWith(".log");
}
});
}
static String cat(final File[] files) throws IOException {
Enumeration<InputStream> e = new Enumeration<InputStream>() {
int index;
#Override
public boolean hasMoreElements() {
return index < files.length;
}
#Override
public InputStream nextElement() {
index++;
try {
return new FileInputStream(files[index - 1]);
} catch (FileNotFoundException ex) {
throw new RuntimeException("File not available!", ex);
}
}
};
SequenceInputStream input = new SequenceInputStream(e);
StringBuilder sb = new StringBuilder();
int c;
while ((c = input.read()) != -1) {
sb.append((char) c);
}
return sb.toString();
}
public static void main(String[] args) throws IOException {
String dir = "<path-to-dir-with-logs>";
File[] logs = logs(dir);
for (File f : logs) {
System.out.println(f.getAbsolutePath());
}
System.out.println();
System.out.println(cat(logs));
}
I have a dialog using JFileChooser. When I save a file by FileOutputStream, I want to save it as file.txt in the path which the user want. But it always saves in c:/user/Document.
Here is the code:
DownLoadDialog downloadDialog = new DownLoadDialog();
int result = downloadDialog.showSaveDialog(queryPanel);
if (result == downloadDialog.APPROVE_OPTION) {
File file = downloadDialog.getSelectedFile();
//String parth =file.getPath();
//System.out.println(parth);
//if(file.exists()) {
//int response = JOptionPane.showConfirmDialog (null,
// "Overwrite existing file?","Confirm Overwrite",
// JOptionPane.OK_CANCEL_OPTION,JOptionPane.QUESTION_MESSAGE);
//if(response == JOptionPane.OK_OPTION) {}
//} else {
if (resultGoogleSearch > 0) {
{
String parth = new File(downloadDialog.getSelectedFile().
getAbsolutePath().concat(".txt")).toString();
System.out.println(parth);
for (int i = 0; i < resultGoogleSearch; i++) {
String[] temp = googleSearchResult.get(i).split("<br>");
//String resultURL = temp[0];
//File dir = downloadDialog.getCurrentDirectory();
try {
FileOutputStream googleReuslt = new FileOutputStream(
downloadDialog.getSelectedFile().getAbsolutePath()
+ ".txt");
OutputStreamWriter writer = new
OutputStreamWriter(googleReuslt);
BufferedWriter buffer = new BufferedWriter(writer);
writer.write(temp[0]);
writer.close();
buffer.close();
} catch (FileNotFoundException fEx) {
} catch (IOException ioEx) {
}
}
}
JOptionPane.showMessageDialog(IDRSApplication.idrsJFrame,
IDRSResourceBundle.res.getString("successful"));
}
The problem is here: why can't I set path for new file?
FileOutputStream googleReuslt = new FileOutputStream(
downloadDialog.getSelectedFile().getAbsolutePath() + ".txt");
OutputStreamWriter writer = new OutputStreamWriter(googleReuslt);
BufferedWriter buffer = new BufferedWriter(writer);
writer.write(temp[0]);
writer.close();
buffer.close();
The code you provided works as you would expect. (At least under linux.)
I suggest you do a SSCCE and update your question.