Add .txt extension in JFileChooser - java

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)

Related

file.getName() returns nothing

I need to get the name of a CSV file selected for the user, but the getName() method does not return any value.
This is the code
private void readCSV(Uri uri) {
InputStream is;
File file = null;
try {
if (uri.getScheme().equals("file")) {
file = new File(uri.toString());
Log.i("File selected: ", file.getName()); //file.getName() doesn't work
is = new FileInputStream(file);
Why does this not return the name of the file?
Edit 1
private void readCSV(Uri uri) {
InputStream is;
File file;
try {
/*This conditional is false*/
if (uri.getScheme().equals("file")) {
file = new File(uri.toString());
Log.i("File selected: ", file.getName()); //file.getName() doesn't
is = new FileInputStream(file);
} else {
/* this part is the one that runs */
is = this.getContentResolver().openInputStream(uri);
Log.i("File selected: ", uri.getLastPathSegment()); //i tried this, it returns me 5049 but it is not the name of the selected file
}
uri.toString() will return the object reference but not the file path.
You should call uri.getPath()
Use
new File(uri.getPath());
instead of
new File(uri.toString());
NOTE: uri.toString() returns a String in the format: "file:///mnt/sdcard/image.jpg", whereas uri.getPath() returns a String in the format: "/mnt/sdcard/image.jpg".
try this
fileName = uri.getLastPathSegment();
Getting file names through the apachecommons io lib https://commons.apache.org/proper/commons-io/javadocs/api-2.5/org/apache/commons/io/FilenameUtils.html
String name = FileNameUtils.getName(uri.getPath());

JFileChooser.SetCurrentDirectory not working

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));
}
});

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.

How to sequentially numbering files rather than overwriting them when moving

I am writing a code that could move the file from one directory to another, but I have an issue with having a file that have the same name, so I decided to number them as I don't want to overwrite them.
Assume I have file a.txt, I succeed to move to move the file with the same name then call it a_1.txt, but I am wondering what I can do if I have again a.txt?
Moreover, I feel my code is not efficient and it will be appreciated if you help me to enhance it.
My code is:
/*
* Method to move a specific file from directory to another
*/
public static void moveFile(String source, String destination) {
File file = new File(source);
String newFilePath = destination + "\\" + file.getName();
File newFile = new File(newFilePath);
if (!newFile.exists()) {
file.renameTo(new File(newFilePath));
} else {
String fileName = FilenameUtils.removeExtension(file.getName());
String extention = FilenameUtils.getExtension(file.getPath());
System.out.println(fileName);
if (isNumeric(fileName.substring(fileName.length() - 1))) {
int fileNum = Integer.parseInt(fileName.substring(fileName.length() - 1));
file.renameTo(new File(destination + "\\" + fileName + ++fileNum + "." + extention));
} else {
file.renameTo(new File(destination + "\\" + fileName + "_1." + extention));
}
}//End else
}
From the main, I called it as the following (Note that ManageFiles is the class name that the method exist in):
String source = "L:\\Test1\\Graduate.JPG";
String destination = "L:\\Test2";
ManageFiles.moveFile(source, destination);
You can use this logic:
If the file already exists in the destination, you add "(1)" to the file name (before the extension). But then you ask me: what if there's already a file with "(1)"? Then you use (2). If there's already one with (2) too, you use (3), and so on.
You can use a loop to acomplish this:
/*
* Method to move a specific file from directory to another
*/
public static void moveFile(String source, String destination) {
File file = new File(source);
String newFilePath = destination + "\\" + file.getName();
File newFile = new File(newFilePath);
String fileName;
String extention;
int fileNum;
int cont;
if (!newFile.exists()) {
file.renameTo(new File(newFilePath));
} else {
cont = 1;
while(newFile.exists()) {
fileName = FilenameUtils.removeExtension(file.getName());
extention = FilenameUtils.getExtension(file.getPath());
System.out.println(fileName);
newFile = new File(destination + "\\" + fileName + "(" + cont++ + ")" + extention);
}
newFile.createNewFile();
}//End else
}

file path from \ to /

I have this problem: I am choosing a file from JFileChooser and if i take a system print i get this path: C:\Users\Joakim\Desktop\dude.txt and when i want to use this link to copy this file to another location i need to have the path like this: C://Users/Joakim/Desktop/dude.txt
How can i do this?
public void upload(String username) throws RemoteException, NullPointerException{
JFileChooser chooser = new JFileChooser(getProperty + "/desktop/");
int returnVal = chooser.showOpenDialog(parent);
if (returnVal == JFileChooser.APPROVE_OPTION) {
System.out.println("You chose to open this file: " + chooser.getSelectedFile().getName());
} try {
String fileName = chooser.getSelectedFile().getName();
System.out.println(fileName); //name of the file
File selectedFile = chooser.getSelectedFile();
System.out.println(selectedFile); //path of the file
//File path= selectedFile.replaceAll('/','/');
String serverDirectory = ("C://Users/Joakim/Dropbox/Project RMI/SERVER/");
byte[] filedata = cf.downloadFile(selectedFile);
BufferedOutputStream output = new BufferedOutputStream(new FileOutputStream(serverDirectory + fileName));
output.write(filedata, 0, filedata.length);
output.flush();
output.close();
} catch (Exception e) {
System.err.println("FileServer exception: " + e.getMessage());
e.printStackTrace();
}
}
Thanks in Advance :)
Edit: So this did not work out as i planed. I wanted to change the path to C://Users/Joakim/Desktop/dude.txt but thats not enough. I need to have //C://Users/Joakim/Desktop/dude.txt. The problem i have now is to get that and still use it as a File. I did test out
File newFil = new File("//" + selectedFile);
byte[] filedata = cf.downloadFile(nyFil);
This do not work for me. I still get out C://Users/Joakim/Desktop/dude.txt
Do someone have a tip or two? :)
You should really be using the system properties file.separator:
Character that separates components of a file path. This is "/" on
UNIX and "\" on Windows.
String fileSeparator = System.getProperty("file.separator");
You can also access the file separator as File.separator
Consider breaking up your path to incorporate the use of this property in lieu of forward or backward slashes.
It's simple, try this :
String first = "C:\\Mine\\Java";
String second = first.replace("\\", "/");
second = second.replaceFirst("/", "//");
System.out.println(second);
OUTPUT :
Hope this might help in some way.
Regards
This should work: C:\Users use double \
Try with this
/**
* Prepare dropbox path from the path.
*
* #param path
* that is to be formated.
* #return
* Return dropbox formated path.
*/
public static String createDropboxPathFormat(String path) {
// Replaced all \ with / of the path.
String dropboxPath = path.replaceAll("[\\\\]", "/");
// Finally replaced all // with /
dropboxPath = dropboxPath.replaceAll("[//]", "/");
return dropboxPath;
}

Categories