I am currently working on a "Notepad - type" file for my Object-Oriented Java class. I've got most of the program done - however I am stuck on the following issue:
When the program tries to save a file, it is supposed to first check for a files existence, obviously if the file exists the program will prompt the user for permission to overwrite the existing copy of the file [The overwrite prompt is not written yet, but it will go in the if(selectedFile.exists() == true) portion of code] - and if the file does not exist, the program will create it.
The issue I am having is that the program always creates the file before checking for the files existence. I have looked at probably 20-30+ answers to similar questions - mainly on stackoverflow, and have yet to come across the answer i need. I'm not sure if I am just "not getting it", or if I have really done something wrong..
Any answer - or hint as to where to find the answer - to this issue would be greatly appreciated.
Thank You.
Complete code (for the save portion of the program is shown below).
else if(source == saveFile)//-------------------------//SAVE FILE//--------------------------
{
JFileChooser fileChooser = new JFileChooser();
fileChooser.setCurrentDirectory(new File(System.getProperty("user.home")));
fileChooser.setDialogTitle("JavaPad - Save File");
int result = fileChooser.showSaveDialog(fileChooser);
String myFile;
try
{
if(result == JFileChooser.APPROVE_OPTION)
{
myFile = fileChooser.getSelectedFile().getName();
File selectedFile = new File(myFile);
String[] lines = textArea.getText().split(System.getProperty("line.separator"));
readToSave = new Scanner(lines.toString()); // CANNOT use toString() on an Array - THIS WILL BE CHANGED PROPERLY?
PrintWriter savePWriter = new PrintWriter(selectedFile);
if(selectedFile.exists() == true)
{
JOptionPane.showMessageDialog(null, "This file already exists.");
statusLabel.setText("File Save Aborted...");
}
else
{
System.out.println("Creating File: " + myFile);
File newFile = new File(fileChooser.getSelectedFile().getName());
savePWriter = new PrintWriter(newFile);
int i = 0;
while(i < lines.length)
{
savePWriter.append(lines[i] + "\n");
System.out.println("Lines appended = " + i);
i++;
}
savePWriter.flush();
savePWriter.close();
statusLabel.setText("File Saved.");
}
}
else
{
JOptionPane.showMessageDialog(null, "Save has been canceled.");
}
}
catch(IOException IOSaveError)
{
System.out.println(IOSaveError);
}
}
You are calling new PrintWriter(selectedFile), which creates the file, right before you check whether selectedFile exists.
Don't create the PrintWriter before checking if the file exists. The PrintWriter is what causes the file to be written to.
You do:
myFile = fileChooser.getSelectedFile().getName();
File selectedFile = new File(myFile);
PrintWriter savePWriter = new PrintWriter(selectedFile); // Creates File! Probably unwanted.
if(selectedFile.exists() == true) // always true because of the line above
By the way, your code is far too complicated. Instead of having the variables selectedFile and newFile, which both are newly created File objects, you could simply use the File object returned by the dialog: newFile = fileChooser.getSelectedFile().
if(selectedFile.exists() == true)
can be simplified to
if (selectedFile.exists())
I recommend to do I/O using try-with-resources whenever possible:
try (final PrintWriter writer = new PrintWriter(selectedFile)) {
// Use writer
}
This helps with accidentally forgetting to close streams.
Related
I am currently working on transferring a file from a server to a client via tcp connection. The file exists somewhere within a sharedroot directory of the server. This is the sample code of my upload method for server upload to client.
public void upload(String filename, DataOutputStream out) throws IOException {
File fname = null;
if (filename.contains(sharedroot)) { //this is if the client provides a proper filepath with the filename
fname = new File(filename);
}else { //if client only provides a filename without path
fname = new File(filename);
//"..\\..\\"+ //i was working around with this, but somehow just making the file whether or not it contains the sharedroot seems to give me the "best" output so far...
}
System.out.println(fname.getCanonicalPath());
if (fname.isDirectory()) {
System.out.println("File is a directory");
String quit = "404 not found";
sendOut(quit, out);
return;
}
String path = fname.getAbsolutePath();
System.out.println(path);
if (fname.isFile()) {
String canonpath = fname.getCanonicalPath();
if (canonpath.contains(sharedroot)) {
try {
FileInputStream in = new FileInputStream(fname);
byte[] buffer = new byte[1024];
out.writeInt(fname.getName().length());
out.write(fname.getName().getBytes(), 0, fname.getName().length()); // writes file name only, not
// including the path
long size = fname.length();
out.writeLong(size);
while (size > 0) {
int len = in.read(buffer, 0, buffer.length);
out.write(buffer, 0, len);
size -= len;
}
} catch (Exception e) {
System.out.println("Error occurred in uploading file to client. Please try again");
}
}else {
System.out.println("File not in shared directory");
String quit = "404 not found";
sendOut(quit, out);
}
}else {
System.out.println("File not exists");
String quit = "404 not found";
sendOut(quit, out);
}
}
The output given by getCanonicalPath() and getAbsolutePath() as seen below is wrong because it is checking inside the directory of my eclipse and not the sharedroot directory. How can I get the filepath of the file so that i can compare it to my sharedroot and ensure it exists within the sharedroot? The sharedroot would be for example: D:\seant\2uniFiles\1. FINE2005 Year 3
D:\seant\eclipse-workspace\DCN3005\Lecture 1 Exercise.pdf
D:\seant\eclipse-workspace\DCN3005\Lecture 1 Exercise.pdf
File not exists
Your creation of File does not specify a dedicated directory. There are two constructors requiring a (root) directory and a file name – one as File itself, the other as String. I assume one of your paths is relative but your else-branch creates the file the same way as the full qualified path. You should pass the sharedRoot instead as first parameter and the fileName as second.
File fname = null;
// sharedRoot is more like a constant and startsWith
// avoids reading somewhere else that looks similar
if (filename.startsWith(sharedRoot)) {
fname = new File(filename);
} else {
fname = new File(sharedRoot, filename);
}
In all other cases relative paths are relative to the root directory of the VM process – and I mean process. If for example a user starts this in the user's HOME directory it'll be relative to this. If an operating system task starts the VM it'll be relative to the OS process' root – which might be a Unix cron job or a Windows scheduling thing.
Maybe you introduce a sort of configuration of sharedRoot so you don't need to recompile if this changes in the future.
I don't understand how to use TextIO's readFile(String Filename)
Can someone please explain how can I read an external file?
public static void readFile(String fileName) {
if (fileName == null) // Go back to reading standard input
readStandardInput();
else {
BufferedReader newin;
try {
newin = new BufferedReader( new FileReader(fileName) );
}
catch (Exception e) {
throw new IllegalArgumentException("Can't open file \"" + fileName + "\" for input.\n"
+ "(Error :" + e + ")");
}
if (! readingStandardInput) { // close current input stream
try {
in.close();
}
catch (Exception e) {
}
}
emptyBuffer(); // Added November 2007
in = newin;
readingStandardInput = false;
inputErrorCount = 0;
inputFileName = fileName;
}
}
I had to use TextIO for a school assignment and I got stuck on it too. The problem I had was that using the Scanner class I could just pass the name of the file as long as the file was in the same folder as my class.
Scanner fileScanner = new Scanner("data.txt");
That works fine. But with TextIO, this won't work;
TextIO.readfile("data.txt"); // can't find file
You have to include the path to the file like this;
TextIo.readfile("src/package/data.txt");
Not sure if there is a way to get it to work like the Scanner class or not, but this is what I've been doing in my course at school.
The above answer (about using the correct file name) is correct, however, as a clarification, make sure that you actually use the proper file path. The file path suggested above, i.e. src/package/ will not work in all circumstances. While this will be obvious to some, for those of you who need clarification, keep reading.
For example (and I use NetBeans), if you have already moved the file into NetBeans, and the file is already in the folder you want it to be in, then right click on the folder itself, and click 'properties'. Then expand the 'file path' section by clicking on the three dots next to the hidden file path. You will see the actual file path in its entirety.
For example, if the entire file path is:
C:\Users..\NetBeansProjects\IceCream\src\icecream\icecream.dat
Then, in the java code file itself, you can write:
TextIo.readfile("src/icecream/icecream.dat");
In other words, make sure you include the words 'src' but also everything that follows the src as well. If it's in the same folder as the rest of the files, you won't need anything prior to the 'src'.
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 8 years ago.
I'm totally new in this world. I want to make a simple file move program. It works fine with only 1 file and until I add the new code for multiple files move. But I wanted more and I added multiple file selection to JFileChooser. To do the move of files I search around the web and found some users that asked for something similar to it. I tried to put it in my code but I've obtained an Error like this:
Exception in thread "main" java.lang.NullPointerException
at jfile.main(jfile.java:27)
Line 27 is: for (int i = 0; i < files.length; i++) {
This is the code, thanks you and sorry for my bad English.
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import javax.swing.JFileChooser;
import org.apache.commons.io.FileUtils;
public class jfile {
public static void main (String[] args) throws IOException{
System.out.println("Creado por: MarcosCT7");
if (new File(System.getProperty("user.home"), "\\AppData\\Roaming\\.minecraft\\mods").exists());{
System.out.println("Seleccione el mod a instalar:");
JFileChooser chooser = new JFileChooser();
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
chooser.setMultiSelectionEnabled(true);
int returnVal = chooser.showOpenDialog(chooser);
if(returnVal == JFileChooser.APPROVE_OPTION) {
System.out.println("Se está instalando " + chooser.getSelectedFile().getName());
File fuente = new File(chooser.getSelectedFile().getAbsolutePath());
File destino = new File(System.getProperty("user.home"), "\\AppData\\Roaming\\.minecraft\\mods");
File[] files = fuente.listFiles(); //thats new added
for (int i = 0; i < files.length; i++) {
File destFile = new File(destino.getAbsolutePath()+File.separator+files[i].getName().replace(",", "")
.replace("[", "")
.replace("]", "")
.replace(" ", "")); //until here its new added
FileUtils.moveFileToDirectory(files[i], destFile, true); //changed to multiple move, before it was: FileUtils.moveFileToDirectory(fuente, destino, true);
}
}
else {
if(returnVal == JFileChooser.CANCEL_OPTION) {
System.out.println("No se ha seleccionado ningun mod. Adios.");
}
}
}
}
}
NullPointerException means that the variable doesn't hold any reference to a object. What I mean by reference is, For ex:
String path="";
File f=new File(path);
if(f.exists()) {
// do something
}
f is a variable of type File which holds a reference to a object File defined by path
and now you can use variable f just like any other variable call methods on that variable etc.
Another example
File f;
if(f.exists()) {
// do something
}
Now you will get NullPointerException in line if(f.exists()) because f doesn't hold any reference.
In JAVA new keyword is used to assign new reference. JVM will take care of all the low level details. It is similar to pointers in c and c++. In JAVA you don't have to explicitly delete the objects. JVM garbage collector will take care of these things. Java is object oriented language
Do read and understand OOP comcepts
Before you iterate through files using the loop, check using an if statement:
if(files==null){
System.out.println("Files not found");
}
else{
for (int i = 0; i < files.length; i++) {
File destFile = new File(destino.getAbsolutePath()+File.separator+files[i].getName().replace(",", "")
.replace("[", "")
.replace("]", "")
.replace(" ", "")); //until here its new added
FileUtils.moveFileToDirectory(files[i], destFile, true); //changed to multiple move, before it was: FileUtils.moveFileToDirectory(fuente, destino, true);
}
}
I'm trying to allow the user to either select an already created .ser file and save over it, or create a new .ser file by typing in a new name in the JFileChooser textfield. As you can see from the code below, I used a if/else statement to determine which of the two the user is doing. The problem I'm experiencing is that no matter how I rearrange things, or use different if conditions, the JFileChooser always chooses the latter option (create a new .ser file by typing in a new name). This wouldn't be a big problem, but it always adds ".ser" to the file.
For example: If I create a new file in JFC called mySERObject, it will be saved as "mySERObject.ser." Now when I open JFC again, and I select with my mouse mySERObject.ser, to save over, it instead creates a new file called "mySERObject.ser.ser."
I uses the System.out.println to see which statement gets exected, and it's always the "First one printed." Here's my code:
private void addSaveAsListener(JMenuItem item) {
item.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
JFileChooser fc = new JFileChooser();
FileNameExtensionFilter filter = new FileNameExtensionFilter(
"Serialized Object Files", "ser", ".ser");
fc.setFileFilter(filter);
final JTextField textField = getTextField(fc); //gets text from JFC textfield
int returnVal = fc.showSaveDialog(null);
String fileName = textField.getText();
if (returnVal == JFileChooser.APPROVE_OPTION) {
if (!(fc.getSelectedFile().length() > 0)) {
System.out.println("first one printed");
File file = new File(fc.getCurrentDirectory(), fileName
+ ".ser");
try {
file.createNewFile();
fileSystem.saveAs(addressbook.getCopyList(), file.getAbsolutePath()); //serializes arraylist
} catch (IOException e) {
JOptionPane.showMessageDialog(null,
"File unable to be created.");
}
} else {
String path = fc.getSelectedFile().getAbsolutePath();
fileSystem.saveAs(addressbook.getCopyList(), path); //serializes arraylist
System.out.println("2nd one printed");
}
}
}
});
}
I was wondering if you could help me with what's wrong or by offering solutions, thank you.
Question 1: There is always another suffix added, what can I do?
Look at the following code from your example. You will see, that you get the textfield from the fc, then get the string from that (aka "mySERObject.ser") and then you gone save again, with ".ser" appendig. You can maybe use some String opperations on fileName to get rid of the suffix before further processing (for example with fileName.replace(".ser", "")).
final JTextField textField = getTextField(fc);
String fileName = textField.getText();
//fileName.replace(".ser", "")
File file = new File(fc.getCurrentDirectory(), fileName + ".ser");
Question 2: In my if/else block only if clause will be selected. Why?
I personally don't know much about JFileChooser, but fc.getSelectedFile().length() seems not to work like you think, since it always returns 0. But you can just use fileName.length(), can't you?
I am trying to open a video file with xuggle like this:
if (container.open(in, null) < 0) {
throw new IllegalArgumentException("could not open file: ");
}
The problem happened when i use mp4 file and i passed to open a InputStream:
InputStream in = new FileInputStream(filename);
In this case IContainer.open remains blocked and does not return anything.
However if I pass a file name to the open method or I use the flv format, it works fine.
I have to use InputStream with an mp4 file.
Can someone help me to find the problem?
In case some other person runs across this issue, I'll say what I did that fixed my problem:
Instead of opening from an InputStream, I opened the file directly used
if (container.open(filename, IContainer.Type.READ, null) < 0)
{
throw new IllegalArgumentException("Could not open file: " + filename);
}
I hope this helps somebody that encounters this problem later. Cheers.
you need to use InputOutputStreamHandler
e.g.
File initialFile = new File(filename);
InputStream is = new FileInputStream(initialFile);
InputOutputStreamHandler handler = new InputOutputStreamHandler(is);
int result = container.open(handler, IContainer.Type.READ, null);
if (result < 0)
throw new IllegalArgumentException("could not open file: "
+ filename);