JFileChooser.SetCurrentDirectory not working - java

I have a JFileChooser and I want to set the directory it opens using some information stored in a .txt file (I'm using a .txt file to persist the desired location between sessions). I can get the file, read the data and set it to a string, but when I try to use that string to set the directory I want to open it doesn't work. My code is roughly something like this:
//buffer contains a byte[] for "/Users/user/Documents/Work/folderToOpen"
desiredPath = new String(buffer);
jFileChooser1.setCurrentDirectory(new java.io.File(desiredPath));
After stepping through this, however, the current directory is set to /Users/user.
If anyone has any ideas about what I'm doing wrong or a better way to accomplish this I'd love to hear it.
Thank you
private static String LAST_FOLDER_USED = null;
//Get the desired file path for user preferences
String pluginRoot = System.getProperty("user.dir") + File.separator.toString();
//Create a file using the desired file Path
File userPreferences = new File(pluginRoot + File.separator + "UserPreferences.txt");
//Get a file called UserPreferences.txt from target/classes to create an input stream
String fileName = "UserPreferences.txt";
InputStream readInFile = getClass().getResourceAsStream(fileName);{
//Convert input stream to read from the desired file in the plug-in root ("filePath" Created Above)
try{
readInFile = new FileInputStream(userPreferences);
}
catch (IOException e){
e.printStackTrace();
}}
//Read the readInFile into a byte[]
String desiredPathToOpenImage;
byte[] buffer = new byte[1000];
int i = 0;{
try {
while((i = readInFile.read(buffer)) !=-1){
System.out.println(new String(buffer));
i++;
}}
catch (IOException e) {
e.printStackTrace();
};
//Convert byte[] to string (This should be the path to the desired folder when selecting an image)
desiredPathToOpenImage = new String(buffer);
}
//Create a New File using the desired path
File desiredPath = new File(desiredPathToOpenImage + File.separator + "prefs.txt");
public SelectImage(Viewer parent, boolean modal) {
super(parent, modal);
initComponents();
int returnVal = jFileChooser1.showOpenDialog(parent);
// Sets up arrays for storing file information to be passed back to the viewer class.
String[] filePath = new String[jFileChooser1.getSelectedFiles().length];
String[] fileName = new String[jFileChooser1.getSelectedFiles().length];
String[] fileDir = new String[jFileChooser1.getSelectedFiles().length];
if (returnVal == JFileChooser.APPROVE_OPTION) {
// Cycles through the selected files and stores each piece accordingly
for (int i = 0; i < jFileChooser1.getSelectedFiles().length; i++) {
File file = jFileChooser1.getSelectedFiles()[i];
filePath[i] = file.getPath();
fileName[i] = file.getName();
fileDir[i] = file.getParent();
}
}
parent.setFilePath(filePath, fileName, fileDir);
}
private void initComponents() {
jFileChooser1 = new javax.swing.JFileChooser();
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
jFileChooser1.setMultiSelectionEnabled(true);
//Checks folder_Path to see if a value is present. If value is present sets jFileChooser Directory to that value
if(desiredPathToOpenImage.contains(File.separator)){
//Create a File using the desired path for selecting images
//****Currently doesn't set the Directory correctly****//
jFileChooser1.setCurrentDirectory(desiredPath);
}
//If no value is present in LAST_FOLDER_USED sets jFileChooser Directory to desktop
else{
jFileChooser1.setCurrentDirectory(new java.io.File("/Users/benwoodruff/Desktop"));
}
jFileChooser1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jFileChooser1ActionPerformed(evt);
//After file is selected sets value of LAST_FOLDER_USED to the absolute path of that file
LAST_FOLDER_USED = jFileChooser1.getCurrentDirectory().toString() + File.separator + "UserPreferences.txt";
try {
FileWriter fileWriter = new FileWriter(userPreferences);
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
bufferedWriter.write(jFileChooser1.getCurrentDirectory().toString());
OutputStream outPut = new FileOutputStream(pluginRoot + File.separator + "UserPreferences.txt");
outPut.write(LAST_FOLDER_USED.getBytes());
outPut.close();
bufferedWriter.close();
} catch (IOException e) {
System.out.println("Error Writing to File" + desiredPathToOpenImage);
e.printStackTrace();
}
}
});

I think the directory passed as argument does not exist or is not accessible to the user you are logged in with judging from the javadoc of setCurrentDirectory():
If the file passed in as currentDirectory is not a directory, the parent of the file will be used as the currentDirectory. If the parent is not traversable, then it will walk up the parent tree until it finds a traversable directory, or hits the root of the file system.
Make sure all folders in the given path exist and are accessible to the logged user (on linux the 'executable' bit controls the accessibility of a directory). So if you see something like
-d x Documents
after executing
ls -l *
in a shell then the Documents directory is accessible.

Found a better way to accomplish my goal using Preferences instead of trying to create and access files to store the location.
Preferences prefs = Preferences.userNodeForPackage(this.getClass());
static String LAST_FOLDER_USED = "LAST_FOLDER_USED";
String folder_Location;
and then inside initComponents()
if(LAST_FOLDER_USED != null){
jFileChooser1.setCurrentDirectory(new File(prefs.get(LAST_FOLDER_USED, LAST_FOLDER_USED)));
}
else{
jFileChooser1.setCurrentDirectory(new java.io.File("/Users/benwoodruff/Desktop"));
}
jFileChooser1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jFileChooser1ActionPerformed(evt);
folder_Location = jFileChooser1.getCurrentDirectory().toString();
prefs.put(LAST_FOLDER_USED, folder_Location);
//System.out.println(prefs.get(LAST_FOLDER_USED, folder_Location));
}
});

Related

Create directory in Java but don't throw error if it already exists [duplicate]

The condition is if the directory exists it has to create files in that specific directory without creating a new directory.
The below code only creates a file with the new directory but not for the existing directory . For example the directory name would be like "GETDIRECTION":
String PATH = "/remote/dir/server/";
String fileName = PATH.append(id).concat(getTimeStamp()).append(".txt");
String directoryName = PATH.append(this.getClassName());
File file = new File(String.valueOf(fileName));
File directory = new File(String.valueOf(directoryName));
if (!directory.exists()) {
directory.mkdir();
if (!file.exists() && !checkEnoughDiskSpace()) {
file.getParentFile().mkdir();
file.createNewFile();
}
}
FileWriter fw = new FileWriter(file.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw);
bw.write(value);
bw.close();
Java 8+ version:
Files.createDirectories(Paths.get("/Your/Path/Here"));
The Files.createDirectories() creates a new directory and parent directories that do not exist. This method does not throw an exception if the directory already exists.
This code checks for the existence of the directory first and creates it if not, and creates the file afterwards. Please note that I couldn't verify some of your method calls as I don't have your complete code, so I'm assuming the calls to things like getTimeStamp() and getClassName() will work. You should also do something with the possible IOException that can be thrown when using any of the java.io.* classes - either your function that writes the files should throw this exception (and it be handled elsewhere), or you should do it in the method directly. Also, I assumed that id is of type String - I don't know as your code doesn't explicitly define it. If it is something else like an int, you should probably cast it to a String before using it in the fileName as I have done here.
Also, I replaced your append calls with concat or + as I saw appropriate.
public void writeFile(String value){
String PATH = "/remote/dir/server/";
String directoryName = PATH.concat(this.getClassName());
String fileName = id + getTimeStamp() + ".txt";
File directory = new File(directoryName);
if (! directory.exists()){
directory.mkdir();
// If you require it to make the entire directory path including parents,
// use directory.mkdirs(); here instead.
}
File file = new File(directoryName + "/" + fileName);
try{
FileWriter fw = new FileWriter(file.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw);
bw.write(value);
bw.close();
}
catch (IOException e){
e.printStackTrace();
System.exit(-1);
}
}
You should probably not use bare path names like this if you want to run the code on Microsoft Windows - I'm not sure what it will do with the / in the filenames. For full portability, you should probably use something like File.separator to construct your paths.
Edit: According to a comment by JosefScript below, it's not necessary to test for directory existence. The directory.mkdir() call will return true if it created a directory, and false if it didn't, including the case when the directory already existed.
Trying to make this as short and simple as possible. Creates directory if it doesn't exist, and then returns the desired file:
/** Creates parent directories if necessary. Then returns file */
private static File fileWithDirectoryAssurance(String directory, String filename) {
File dir = new File(directory);
if (!dir.exists()) dir.mkdirs();
return new File(directory + "/" + filename);
}
I would suggest the following for Java8+.
/**
* Creates a File if the file does not exist, or returns a
* reference to the File if it already exists.
*/
public File createOrRetrieve(final String target) throws IOException {
final File answer;
Path path = Paths.get(target);
Path parent = path.getParent();
if(parent != null && Files.notExists(parent)) {
Files.createDirectories(path);
}
if(Files.notExists(path)) {
LOG.info("Target file \"" + target + "\" will be created.");
answer = Files.createFile(path).toFile();
} else {
LOG.info("Target file \"" + target + "\" will be retrieved.");
answer = path.toFile();
}
return answer;
}
Edit: Updated to fix bug as indicated by #Cataclysm and #Marcono1234. Thx guys:)
code:
// Create Directory if not exist then Copy a file.
public static void copyFile_Directory(String origin, String destDir, String destination) throws IOException {
Path FROM = Paths.get(origin);
Path TO = Paths.get(destination);
File directory = new File(String.valueOf(destDir));
if (!directory.exists()) {
directory.mkdir();
}
//overwrite the destination file if it exists, and copy
// the file attributes, including the rwx permissions
CopyOption[] options = new CopyOption[]{
StandardCopyOption.REPLACE_EXISTING,
StandardCopyOption.COPY_ATTRIBUTES
};
Files.copy(FROM, TO, options);
}
Simple Solution using using java.nio.Path
public static Path createFileWithDir(String directory, String filename) {
File dir = new File(directory);
if (!dir.exists()) dir.mkdirs();
return Paths.get(directory + File.separatorChar + filename);
}
If you create a web based application, the better solution is to check the directory exists or not then create the file if not exist. If exists, recreate again.
private File createFile(String path, String fileName) throws IOException {
ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource(".").getFile() + path + fileName);
// Lets create the directory
try {
file.getParentFile().mkdir();
} catch (Exception err){
System.out.println("ERROR (Directory Create)" + err.getMessage());
}
// Lets create the file if we have credential
try {
file.createNewFile();
} catch (Exception err){
System.out.println("ERROR (File Create)" + err.getMessage());
}
return file;
}
A simple solution using Java 8
public void init(String multipartLocation) throws IOException {
File storageDirectory = new File(multipartLocation);
if (!storageDirectory.exists()) {
if (!storageDirectory.mkdir()) {
throw new IOException("Error creating directory.");
}
}
}
If you're using Java 8 or above, then Files.createDirectories() method works the best.

Copying Multiple files using SWT filedialog

I'm working a transfer file program and my program is working but I'm having a problem because when I select multiple files and put it on a textbox the source directory can't read what is on the textbox
this is my code
Opening file/files
btnSearchFile.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
FileDialog fd = new FileDialog(shell, SWT.MULTI);
Collection files = new ArrayList();
String firstFile = fd.open();
if (firstFile != null) {
String[] selectedFiles = fd.getFileNames();
File file = new File(firstFile);
for (int ii = 0; ii < selectedFiles.length; ii++ )
{
if (file.isFile())
{
displayFiles(new String[] { file.toString()});
}
else
displayFiles(file.list());
}
}
}
});
Displaying Files on textbox
public void displayFiles(String[] files) {
for (int i = 0; files != null && i < files.length; i++) {
txtSource.append(files[i]);
txtSource.setEditable(false);
}
}
Copy Files
public static void copyFile(File src, File dest) throws IOException
{
InputStream oInStream = new FileInputStream(src);
OutputStream oOutStream = new FileOutputStream(dest);
// Transfer bytes from in to out
byte[] oBytes = new byte[1024];
int nLength;
BufferedInputStream oBuffInputStream = new BufferedInputStream( oInStream );
while ((nLength = oBuffInputStream.read(oBytes)) > 0)
{
oOutStream.write(oBytes, 0, nLength);
}
oInStream.close();
oOutStream.close();
}
PS: One file is okay but if multiple files are selected and put on the textbox the source directory can't be found
In order to be completely helpful, we could really use some more detail (specific exceptions, a complete MCVE, which SWT widgets are used, etc.).
That said, I think you've provided enough to see that there are some issues with your code:
For starters, when you have multiple files selected, you're displaying the same file name (the name of the first one) over and over. Perhaps this is intentional, but worth mentioning:
String[] selectedFiles = fd.getFileNames();
File file = new File(firstFile);
for (int ii = 0; ii < selectedFiles.length; ii++ )
{
// You've used a FileDialog, so this should always be true
if (file.isFile())
{
// Will always be the first file
displayFiles(new String[] { file.toString()});
}
else
displayFiles(file.list());
}
Based on the context, I'm assuming txtSource is a Text widget. With that in mind, if we look at your displayFiles() method, you have the following:
txtSource.append(files[i]);
When you call displayFiles() repeatedly, you will be tacking on a file name after all the others, effectively building one long String which is the combination of all file names. When you go to copy the files listed, splitting that String back into valid file paths will be tricky.
My guess is that when you say:
"the source directory can't be found"
...you're just grabbing the content of txtSource. Something like this:
new File(txtSource.getText());
"...One file is okay..."
That will certainly work if there's only one file name in the Text object, but if there are multiple names it will result in a non-existent File.
For example, if you've selected two files:
C:\Users\me\FileA
C:\Users\me\FileB
Your txtSource would display C:\Users\me\FileAC:\Users\me\FileB. And the path C:\Users\me\FileAC:\Users\me\FileB most likely does not exist.
In that case, new File(txtSource.getText()).exists() would return false, and using that File in the constructor for FileInputStream (inside copyFile()) would result in a FileNotFoundException.
In short, just make sure that when you make your call to copyFile() and create the source File object that you're giving the path that you think you are, and not the concatenation of all files selected.

Trying to create file without succes - file appears elsewhere?

I tried to create 3 empty files in my home directory, using this:
this.mainpath = System.getenv("HOME"+"/");
this.single = new File(mainpath + "sin.r");
this.complete = new File (mainpath + "com.r");
this.ward = new File (mainpath+"w.r");
I was unter the impression that this would give me the files desired. However, if I search my home directory, or any other directory, for this files, none of them exists. What am I doing wrong?
Edit: I just find out: I do get a file, but not in my home directory, but the path to it would be /home/myname/NetBeansProjects/myorojectname/nullsin.r.
However, I specifically wanted to create the file in my home!
Well, my code now reads:
this.mainpath = System.getenv("user.home");
this.mainpath = this.mainpath + "/";
this.single = new File(mainpath + "sin.r");
this.single.createNewFile();
System.out.println(this.single.getAbsolutePath());
this.complete = new File (mainpath + "comp.r");
this.complete.createNewFile();
this.ward = new File (mainpath+"w.r");
this.ward.createNewFile();
The "success" of this, however, is that I get an IOException at the first createNeWFile(): File not found.
as for my code how I tried to write sth into those file, there it is:
FileWriter writer1 = null;
FileWriter writer2 = null;
FileWriter writer3 = null;
try {
writer1 = new FileWriter(single);
writer2 = new FileWriter(complete);
writer3 = new FileWriter(ward);
writer1.write("x = cbind(1,2,3)");
writer2.write("x = cbind(1,2,3)");
writer3.write("x = cbind(1,2,3)");
writer1.flush();
writer2.flush();
writer3.flush();
} catch (IOException ex) {
System.out.println(ex.getStackTrace());
} finally {
try {
writer1.close();
writer2.close();
writer3.close();
} catch (IOException ex) {
System.out.println(ex.getStackTrace());
}
You need to use getProperty() instead
System.getProperty("user.home");
Also, the / should be appended after getting the directory path.
this.mainpath = System.getProperty("user.home");
this.single = new File(mainpath + "/sin.r");
this.complete = new File (mainpath + "/com.r");
this.ward = new File (mainpath+"/w.r");
You can call the "createNewFile"-method for each of the objects you've declared to actually create them.

Android: Open file with specific path [duplicate]

I have a filename in my code as :
String NAME_OF_FILE="//sdcard//imageq.png";
FileInputStream fis =this.openFileInput(NAME_OF_FILE); // 2nd line
I get an error on 2nd line :
05-11 16:49:06.355: ERROR/AndroidRuntime(4570): Caused by: java.lang.IllegalArgumentException: File //sdcard//imageq.png contains a path separator
I tried this format also:
String NAME_OF_FILE="/sdcard/imageq.png";
The solution is:
FileInputStream fis = new FileInputStream (new File(NAME_OF_FILE)); // 2nd line
The openFileInput method doesn't accept path separators.
Don't forget to
fis.close();
at the end.
This method opens a file in the private data area of the application. You cannot open any files in subdirectories in this area or from entirely other areas using this method. So use the constructor of the FileInputStream directly to pass the path with a directory in it.
openFileInput() doesn't accept paths, only a file name
if you want to access a path, use File file = new File(path) and corresponding FileInputStream
I got the above error message while trying to access a file from Internal Storage using openFileInput("/Dir/data.txt") method with subdirectory Dir.
You cannot access sub-directories using the above method.
Try something like:
FileInputStream fIS = new FileInputStream (new File("/Dir/data.txt"));
You cannot use path with directory separators directly, but you will
have to make a file object for every directory.
NOTE: This code makes directories, yours may not need that...
File file= context.getFilesDir();
file.mkdir();
String[] array=filePath.split("/");
for(int t=0; t< array.length -1 ;t++)
{
file=new File(file,array[t]);
file.mkdir();
}
File f=new File(file,array[array.length-1]);
RandomAccessFileOutputStream rvalue = new RandomAccessFileOutputStream(f,append);
String all = "";
try {
BufferedReader br = new BufferedReader(new FileReader(filePath));
String strLine;
while ((strLine = br.readLine()) != null){
all = all + strLine;
}
} catch (IOException e) {
Log.e("notes_err", e.getLocalizedMessage());
}
File file = context.getFilesDir();
file.mkdir();
String[] array = filePath.split("/");
for(int t = 0; t < array.length - 1; t++) {
file = new File(file, array[t]);
file.mkdir();
}
File f = new File(file,array[array.length- 1]);
RandomAccessFileOutputStream rvalue =
new RandomAccessFileOutputStream(f, append);
I solved this type of error by making a directory in the onCreate event, then accessing the directory by creating a new file object in a method that needs to do something such as save or retrieve a file in that directory, hope this helps!
public class MyClass {
private String state;
public File myFilename;
#Override
protected void onCreate(Bundle savedInstanceState) {//create your directory the user will be able to find
super.onCreate(savedInstanceState);
if (Environment.MEDIA_MOUNTED.equals(state)) {
myFilename = new File(Environment.getExternalStorageDirectory().toString() + "/My Directory");
if (!myFilename.exists()) {
myFilename.mkdirs();
}
}
}
public void myMethod {
File fileTo = new File(myFilename.toString() + "/myPic.png");
// use fileTo object to save your file in your new directory that was created in the onCreate method
}
}
I did like this
var dir = File(app.filesDir, directoryName)
if(!dir.exists()){
currentCompanyFolder.mkdir()
}
var directory = app.getDir(directoryName, Context.MODE_PRIVATE)
val file = File(directory, fileName)
file.outputStream().use {
it.write(body.bytes())
}

Add .txt extension in JFileChooser

I have a method that get text from a JTextArea, create a file and write text on it as code below:
public void createTxt() {
TxtFilter txt = new TxtFilter();
JFileChooser fSave = new JFileChooser();
fSave.setFileFilter(txt);
int result = fSave.showSaveDialog(this);
if(result == JFileChooser.APPROVE_OPTION) {
File sFile = fSave.getSelectedFile();
FileFilter selectedFilter = fSave.getFileFilter();
String file_name = sFile.getName();
String file_path = sFile.getParent();
try{
if(!sFile.exists()) {
sFile.createNewFile();
BufferedWriter out = new BufferedWriter(new FileWriter(sFile));
out.write(jTextArea1.getText());
out.close();
JOptionPane.showMessageDialog(null, "Warning file • " + file_name + " • created succesfully in \n" + file_path);
} else {
String message = "File • " + file_name + " • already exist in \n" + file_path + ":\n" + "Do you want to overwrite?";
String title = "Warning";
int reply = JOptionPane.showConfirmDialog(null, message, title, JOptionPane.YES_NO_OPTION);
if(reply == JOptionPane.YES_OPTION){
sFile.delete();
sFile.createNewFile();
BufferedWriter out = new BufferedWriter(new FileWriter(sFile));
out.write(jTextArea1.getText());
out.close();
JOptionPane.showMessageDialog(null, "File • " + file_name + " • overwritten succesfully in \n" + file_path);
}
}
}
catch(IOException e) {
System.out.println("Error");
}
}
}
and a txt file filter
public class TxtFilter extends FileFilter{
#Override
public boolean accept(File f){
return f.getName().toLowerCase().endsWith(".txt")||f.isDirectory();
}
#Override
public String getDescription(){
return "Text files (*.txt)";
}
}
The file filter for txt works fine but what I want is to add ".txt" extension when I type file name.
How to I have to modify my code?
I just use this
File fileToBeSaved = fileChooser.getSelectedFile();
if(!fileChooser.getSelectedFile().getAbsolutePath().endsWith(suffix)){
fileToBeSaved = new File(fileChooser.getSelectedFile() + suffix);
}
UPDATE
You pointed me out that the check for existing files doesn't work. I'm sorry, I didn't think of it when I suggested you to replace the BufferedWriter line.
Now, replace this:
File sFile = fSave.getSelectedFile();
with:
File sFile = new File(fSave.getSelectedFile()+".txt");
With this replacement, it isn't now needed to replace the line of BufferedWriter, adding .txt for the extension. Then, replace that line with the line in the code you posted (with BufferedWriter out = new BufferedWriter(new FileWriter(sFile)); instead of BufferedWriter out = new BufferedWriter(new FileWriter(sFile+".txt"));).
Now the program should work as expected.
I forgot to mention that you have to comment the line:
sFile.createNewFile();
In this way, you're creating an empty file, with the class File.
Just after this line, there is: BufferedWriter out = new BufferedWriter(new FileWriter(sFile));.
With this line, you are creating again the same file. The writing procedure is happening two times! I think it's useless to insert two instructions that are doing the same task.
Also, on the BufferedWriter constructor, you can append a string for the file name (it isn't possible on File constructor), that's the reason why I added +".txt" (the extension) to sFile.
This is a utility function from one of my programs that you can use instead of JFileChooser.getSelectedFile, to get the extension too.
/**
* Returns the selected file from a JFileChooser, including the extension from
* the file filter.
*/
public static File getSelectedFileWithExtension(JFileChooser c) {
File file = c.getSelectedFile();
if (c.getFileFilter() instanceof FileNameExtensionFilter) {
String[] exts = ((FileNameExtensionFilter)c.getFileFilter()).getExtensions();
String nameLower = file.getName().toLowerCase();
for (String ext : exts) { // check if it already has a valid extension
if (nameLower.endsWith('.' + ext.toLowerCase())) {
return file; // if yes, return as-is
}
}
// if not, append the first extension from the selected filter
file = new File(file.toString() + '.' + exts[0]);
}
return file;
}
I've done this function for this purpose :
/**
* Add extension to a file that doesn't have yet an extension
* this method is useful to automatically add an extension in the savefileDialog control
* #param file file to check
* #param ext extension to add
* #return file with extension (e.g. 'test.doc')
*/
private String addFileExtIfNecessary(String file,String ext) {
if(file.lastIndexOf('.') == -1)
file += ext;
return file;
}
Then you can use the function for example in this way :
JFileChooser fS = new JFileChooser();
String fileExt = ".txt";
addFileExtIfNecessary(fS.getSelectedFile().getName(),fileExt)

Categories