I am writing a notepad app and I'm making a create a password screen pop up until you've created one, and then a log in screen will pop up from then on.
Here is some sample code:
File myFile = new File(getFilesDir() + "pass.txt");
if (!myFile.exists()) // if "pass.txt" DOESN'T exist, make them create a password
{
try {
// this writes the password to the "pass.txt" file
// which is the one that is checked to exist.
// after it is written to, it should always exist.
FileOutputStream fos = openFileOutput("pass.txt", Context.MODE_PRIVATE);
fos.write(pass.getBytes());
// this writes the security question to a different file.
fos = openFileOutput("securityQ.txt", Context.MODE_PRIVATE);
fos.write(secQ.getBytes());
// this writes the security answer to a different file.
fos = openFileOutput("securityAnswer.txt", Context.MODE_PRIVATE);
fos.write(secAns.getBytes());
fos.close();
} catch(Exception e) {}
^ That is in one method. Then, in another I do this:
try { // input the right password to the String data
char[] inputBuffer = new char[1024];
fIn = openFileInput("pass.txt");
isr = new InputStreamReader(fIn);
isr.read(inputBuffer);
data = new String(inputBuffer);
isr.close();
fIn.close();
}catch(IOException e){}
if (password.getText().toString().equals(data)) // if password is right, log in.
{
loggedin();
}
else // if the password entered is wrong, display the right one.
{
TextView scr = (TextView)findViewById(R.id.display);
scr.setText("." + data + "."+'\n'+"." + password.getText().toString() + ".");
}
The problem is that the user can't log in even though the password is entered correctly and the display proves that.
The other problem is that whenever I run the app again, it goes to the create screen, which means that it is recognizes the file to NOT exist (even though I just wrote to it).
I've dealt with files this whole project and it can keep track of entered text so that when you press a button, it reads the file back to you. Even if you close it, it keeps track of what you input. For some reason though, the password thing doesn't work.
Here is an image of what happens (the first .k. is the data read from the "pass.txt" file and the second .k. is the user inputted String from the EditText):
SOLUTION to the logging in problem:
String values look the same but don't ".equals()" each other
Had to simply use the .trim() method on the password user input.
I'll pass on commenting about saving passwords in a file called "pass.txt", and just focus on the technical part.
File myFile = new File(getFilesDir() + "pass.txt");
myFile will never be a valid file. You don't have a separator / between the path and the file name. Since that will never be vaild, the next line will say it doesn't exist and go through the whole block.
You can easily fix this one of two ways:
File myFile = new File(getFilesDir() + "/pass.txt");
That simply adds the separator to the file name.
File myFile = new File(getFilesDir(), "pass.txt");
This is probably the better option, since it uses the explicit path, file constructor. Either one is fine, though.
You can also just use context.openFileInput("pass.txt"); and catch if FileNotFoundException occurs, at which point you can "assume" the file actually doesn't exist.
Related
#
SOLVED 20170607 -It turns out this was an IDE installation error. I system restored to when I was using an older Eclipse and Java 6. I then installed the latest Eclipse and Java 8 and the file saved with no errors.
#
What's going on here? Google as well as many sites such as this do not seem to enlighten me.
I using Eclipse 4, Windows 7 SP 1 and Java 8 (121 64 bit)
I have looked at Access is denied java.io.FileNotFoundException
It says the issue is due to file permissions. I can read txt files with no trouble and I can write to new or existing files as long as they do not have .txt as their extension. This is explained in the v1 of my question. Even so, I gave admin and the currently logged on user (me), full permissions to the director and the exception's still thrown. I can load files with no problems (see the question section titled #####LOADING FILES#####)
I'm trying to work out how to save files. The code I have created works with the extensions .exe, .mp3, .foo, .doc, .exe.
When I use .txt. and IOExcepton, access denied is thrown. link to image: http://design.paulyeatman.net/wp-content/uploads/2017/04/IOException-savefile-20170602.png
Here's the program code. I've included everything (so methods not yet written etc, the one I'm interesting in is "private void saveFile(String fileName, String sample)"
/* This program is to teach myself to save a file using as an example, a program that maintains a list of DVD's along with release date and whether or not has been watched (so a DVD name and and 2 associated variables I'll probably track with an ArrayList).
* Where a DVD has been watched, user should be able to modify existing entry to this effect.
* The list of DVD's, release date and watch state are all saved into a persistent file for future editing.
*
*
* might be insightful http://alvinalexander.com/java/java-file-utilities-open-read-write-copy-files as has some pre coded classes
*/
import acm.program.*;
import java.util.*;
import java.io.*;
import java.nio.*; // not used
import java.nio.charset.Charset; // not used
public class saveData extends ConsoleProgram implements saveDataConstants {
public void run() {
// guts of program here
chooseFile();
addToDataList();
// saveFile(fileName, text);s
}
/* this asks the user if the have a file or if they want to create a new file */
private void chooseFile() {
println ("Choose your file type");
println("1. You want to create a new file.");
println("2. You want to open an existing file.");
int fileChoice = readInt ("");
println("You chose: " + fileChoice);
if (fileChoice == 1) {
createNewFile();
}
if (fileChoice == 2) {
existingFile();
}
}
/* an existing file is read into a bufferedReader */
private void existingFile() {
println("existingFile method launched");
}
/* a new file is created by assigning it a file name which is held in memory until the save option is launched */
private void createNewFile() {
fileName = readLine ("Enter in you filename: ");
fileName = fileName + FILE_EXTENSION;
}
/* this add to the file in active memory */
private void addToDataList() {
println("This is the addToDataList method");
println("We want arrays to handle Movie Title, Release Date, Watched (or not)");
// println("A sentinel of Q is planned to be used to enter the saveFile method");
//the next line throws an IOException. Why, file path? something else??? Nah, the .txt extension. .doc, .mp3. foo. exe. .png all used and work with no IOEx
saveFile(fileName, sample);
// saveFile();
}
/* this has test string for the file */
private String testString(String text) {
String sample = "This should text should wind up in the text file the program should create";
return (sample);
}
/* this saves the new data to the file (hopefully, just appends, will it overwrite? who cares?)
*
* The fileName is remembered as it should be. Here we assume it will save to some default location.
*
* The test string is correctly gathered from the testString(String text) method.
* */
private void saveFile(String fileName, String sample) // adapted from http://alvinalexander.com/java/java-file-save-write-text-binary-data
// throws IOException
{
String textToSave = testString(sample);
Charset charset = Charset.forName("US-ASCII");
println("This is the saveFile method. Presumably it saves the file.");
println("");
println("the filename is remembered as: " + fileName);
println("");
println("the text to save is: " + textToSave);
println("");
File fileNameSaved = new File (fileName);
try{
BufferedWriter file = new BufferedWriter(new FileWriter (fileNameSaved)); // true will add to the file and not overwrite
// BufferedWriter out = new BufferedWriter(new FileWriter (file, true)); // true will add to the file and not overwrite
// #############################
// Note, the BufferedWriter line saves the file name as "file". and the txt is put into it.
// When I remove the quotes, an IOException results despite file = the correct name. Since tracked error down to extension on .txt
// see if this helps: https://docs.oracle.com/javase/tutorial/essential/io/file.html
file.write(textToSave);
file.close();
}
catch (IOException ex) {
ex.printStackTrace(); // from https://www.tutorialspoint.com/java/io/bufferedreader_readline.htm
System.err.println();
}
println("The file has saved if the program gets this far."); // even if IOEx thrown, this displays.
}
/* Private variables follow */
String fileName;
String textToSave;
String sample;
}
File 2 just has the constants and they are feed into the methods correctly.
LOADING FILES
I created a file called existing.txt. That is read into the program by a buffered reader with no problem at all. Calling
println("Should be x1 Element, so the ref 0 element is: " + workingData.get(0));
Gives the output as "Should be x1 Element, so the ref 0 element is: This has been loaded from an existing text file called "existing.txt" "
What I'm really asking
Should my code work and Windows has an issue with Eclipse saving text files (seems to not be the case as not the same as Access is denied java.io.FileNotFoundException ), is there something else I need to learn about this function of Java or is my code lacking something?
/\ Based on my testing, Windows must have had an issue with Eclipse trying to save files, so yes in the end permission errors.
I am trying to change a program I wrote a while ago. Currently the program handles a few BufferedReader and BufferedWriters with some logic built in. Let me explain how it used to work.
Class used to upload a file:
public void getFile(){//Used to upload the ACH file.
while(uploadApproval==false){//While upload approval has not been given..
JFileChooser chooser = new JFileChooser();//Creates a new object of the JFileChooser class.
uploadFile = chooser;//Saves the upload file variable as the chooser response.
FileNameExtensionFilter filter = new FileNameExtensionFilter("ACH Files", "ach");
//Sets the allowed file formats for upload.
chooser.setFileFilter(filter);//Activates the created file filter.
chooser.setDialogTitle("Please choose ACH file to upload");//Sets the title bar text.
//Completes once the user clicks ok.
int returnVal = chooser.showOpenDialog(chooser);//
if(returnVal == JFileChooser.APPROVE_OPTION){
uploadApproval=true;
}else{
System.exit(0);
}
}
}
Class used to set directory
public void setDirectory(){//Used to set the directory.
while(saveApproval==false){//While the user does not have approval of the save location..
JFileChooser chooser2 = new JFileChooser();//Creates a new JFileChooser object.
saveFile = chooser2;//Sets the save file location to chooser2.
chooser2.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);//User is only able to scan for
//directories.
//Completes once the user clicks okay.
int returnValue2 = chooser2.showDialog(chooser2, "Directory to save");
if(returnValue2 == JFileChooser.APPROVE_OPTION){
saveApproval=true;
}else{
System.exit(0);
}
}
}
Then later I begin the actual buffered reader/writer process which involves a lot of logic here:
location = "//NachaOutput"+randomNumber+".ACH";
try{
String sCurrentLine;//String representing the current line.
//Pulls the uploaded file.
br = new BufferedReader(new FileReader(NachaMain.uploadFile.getSelectedFile()));
bw = new BufferedWriter(new FileWriter(NachaMain.saveFile.getSelectedFile()+location));
Now here is what I need to do. I have been asked to remove the screen where the user selects the directory from the beginning. Instead, the user will select the save directory in the end of the process.
This means that the "SetDirectory" method won't be called at all, therefore this line of code:
bw = new BufferedWriter(new FileWriter(NachaMain.saveFile.getSelectedFile()+location));
obviously won't work. I need to find some way to replace that file writer location with a generic location that would be the same for all users regardless of their setup. Something along the lines of documents.
I tried doing this:
bw = new BufferedWriter(new FileWriter("Libraries\\Documents"+location));
but got an exception about an invalid path.
So please help me out and let me know a good path that I could save the file to automatically. That saved file will basically be a "dummy" file. Later in the end of the program I will copy that dummy file to the location the user specifies then delete it, so the location really doesn't matter too much.
Thanks in advance!
You could create a temporary file using File.createTempFile(). It might make cleanup easier if you called deleteOnExit() for the created temporary file.
I am trying to send Files in fragments using DatagramPackets in Java (part of an assignemt.) When I am trying to save the incoming File I get access denied error, but I believe that it is not a permissions issue.
Here is the brunt of it:
I let the user sending the file to choose it using FileChooser. And create a new Message object.
//....
File f = content.showFileChooser();
byte type = Byte.parseByte("4");
Message m;
try {
if (mode == 1){
m = new Message(f, content.getServerData().getFragmentSize(), (short) (sentMessages.size()+1), type);
serverThread.send(m);
}
//...
During Message creation the file gets split up into byte arrays, where the size of each array is predetermined by the user. The code is quite lengthy so I am not going to post the chopping process, but this is how I convert the File object into a big byte[] which then gets chopped up
Path p = Paths.get(file.getAbsolutePath());
this.rawData = Files.readAllBytes(p);
After the Message is created and chopped up into byte arrays I send them using DatagramPackets. The other side then uses those to create a new Message object. Once all fragments arrive rawData is extracted from the Message object again. The problem believe lies here:
Message m = receivedMessages.get(msgIndex-1);
byte[] fileData = m.getFile();
if (fileData != null){
System.out.println("All file fragments received.");
content.append("Received a file in" + m.getFragmentCount()+" fragments. Choose directory. " ,1);
//I BELIEVE THIS TO BE THE CRITICAL POINT
String filePath = content.chooseDirectory();
if (filePath == null)
return;
FileOutputStream fos;
try {
fos = new FileOutputStream(filePath);
fos.write(fileData);
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Once all fragments arrive I let the user select a directory using FileChooser with DIRECTORY_ONLY choice mode. As I understand, FileOutputStream requires a full path for the new File. Do I have to send the file name and extension separately or can it be extracted from the received File data?
You are writing directory path to filePath, then try to open that directory with FileOutputStream. No wonder that doesn't work, you have to specify the filename too.
String filename = "myfile.txt"; //Or receive and set this some other way
File outFile = new File(filePath, filename);
fos = new FileOutputStream(outFile);
I don't see you sending/receiving the filename anywhere, though. You'll need to either make it constant or transfer it along with file contents.
I have this piece of code in my project:
String readFile() {
String pathname = saveDirectory + fileName + ".txt";
String content = "";
File f = new File(pathname);
if (f.exists() && !f.isDirectory()) {
try {
content = new String(Files.readAllBytes(Paths.get(pathname)));
}
catch (IOException e) { }
}
return content;
}
There are no errors, the aplication runs just right, but the content variable never has any text in it and I'm sure that the txt file has text in it!
I've already tried different ways to read the text file (with BufferedReader, Scanner, FileInputStream and FileReader) but none of them worked.
Ps. I'm almost sure that the problem isn't in the pathname variable since I've tried to open the file via code (with Runtime) and it opened the right file normally.
Ok, I tried adding the e.printStackTrace(); but there is still no errors, and it's not missing a / between the directory and the fileName, i've already added in the \\ in the directory variable.
Could you be forgetting the / between the directory and the file name? Print the content of pathname and see.
Or better: debug your code and see what happens.
It looks like you're opening the file once (File f = new File(pathname);), then trying to read it without using the file object you created. You're probably getting an IOException because Files.readAllBytes(Paths.get(pathname)) can't open the file while f has it open.
I have a java application that processes the contents of a file, and then I need to move it to another location.
This is how I read the file:
String filePath = new String("foo.bar");
String fileContents = new String("");
char[] myBuffer = new char[chunkSize];
int bytesRead = 0;
BufferedReader in;
try {
FileReader fr = new FileReader(filePath);
in = new BufferedReader(fr);
try {
while ((bytesRead = in.read(myBuffer,0,chunkSize)) != -1)
{
//System.out.println("Read " + bytesRead + " bytes. They were: " + new String(myBuffer));
fileContents+= new String(myBuffer).substring(0, bytesRead);
}
// close the stream as I don't need it anymore. (If I don't close it, then java would hold the file open thus preventing the subsequent move of the file)
in.close();
fr.close();
} catch (IOException e) {
e.printStackTrace();
return null;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
}
the file should be closed as I close both input stream and file reader.
Then after this I try to move the file to another directory using File.renameTo(newFileName); but this fails (under unix!, under windows it works fine)
Right after the move fails, I test whether I can create a file called newFileName and whether I can delete the original file. The new file gets to be created, while the original file fails to delete.
Interestingly enough I can delete the original file from command line while the application is running (right after the failure).
Any idea why is that or any alternative?
More details: I am working under unix and I'm bound to use java 1.6 for legacy reasons (thus I can not revert to Files.move() which is supported starting from java 1.7).
I found what was the problem in my java application.
Basically I extract a list of files from a directory using a custom FileFilter. This gives me an array File[] foundFiles.
What I do afterwards is reading each file in a while loop using the snippet of code in the question.
Right after the file is read for some reason I created a new File object using the i-th file from the array as parameter for the constructor
File file = new File(foundFiles[i].getName()); // File to be moved
and then I tried to rename this one.
Now for some reason this works under windows while it doesn't under unix (the file is somehow locked I think by the foundFiles[i] object).
In fact if I print the results of these lines
System.out.println("I can read foundFiles[i]: " +foundFiles[i].canRead());// DEBUG
System.out.println("I can write foundFiles[i]: " +foundFiles[i].canWrite());// DEBUG
System.out.println("I can read file : " +file.canRead());// DEBUG
System.out.println("I can write file : " +file.canWrite());// DEBUG
I get
I can read foundFiles[i]: True
I can write foundFiles[i]: True
I can read file: False
I can write file: False
It was simply enough to use renameTo() directly on the foundFiles[i] objects to make it work fine.
Hope this helps, but I don't know why the first version would work under windows and not under unix.
Let's analyze the above observation...
I can read foundFiles[i]: True
I can write foundFiles[i]: True
I can read file: False
I can write file: False
The result is normal, because the file object has been produced via new File(foundFiles[i].getName()) but the method getName provides only the name of the file, WITHOUT its filepath !
By creating the file via new File(foundFiles[i].getParent() + File.separator + foundFiles[i].getName()), the results would then be :
I can read foundFiles[i]: True
I can write foundFiles[i]: True
I can read file: True
I can write file: True