I have a method like this:
public int getIncrement() {
String extractFolder = "/mnt/sdcard/MyFolder";
boolean newFolder = new File(extractFolder).mkdir();
int counter = 0;
try {
File root = new File(extractFolder);
if (root.canWrite()){
File gpxfile = new File(root, "gpxfile.txt");
FileWriter gpxwriter = new FileWriter(gpxfile);
BufferedWriter out = new BufferedWriter(gpxwriter);
Scanner scanner = new Scanner(new FileInputStream(gpxfile.getAbsolutePath()), "UTF-8");
Log.i("PATH: ", extractFolder + "/gpxfile.txt");
while(scanner.hasNextLine()) {
String inc = scanner.nextLine();
counter = Integer.parseInt(inc);
Log.i("INSIDE WHILE: ", Integer.toString(counter));
}
counter++;
out.write(Integer.toString(counter));
out.close();
}
} catch (IOException e) {
Log.e("GEN_PCN: ", "Could not write file " + e.getMessage());
}
return counter;
}
What I am trying to accomplish is returning the content of this file, and increment the integer by 1. But it seems that I can't get in the while loop, because LogCat doesn't print out anything. Yes, am sure that the path is correct.
I guess the constructor of FileWriter gpxwriter has already blanked out the file by the time the Scanner is created, so the file is empty and hasNextLine returns false. Why do you open a file for writing when you want to read it?
From what I can tell the file doesn't exist. Try adding gpxfile.createNewFile()
To get a little more in depth, creating a File instance, does not create a file on the file system.
So, this line -> File gpxfile = new File(path, filename);
is not sufficient to create the file on the sd card. You must follow it with
gpxfile.createNewFile() which quoting the docs says:
Atomically creates a new, empty file named by this abstract pathname if and only if a file with this name does not yet exist. The check for the existence of the file and the creation of the file if it does not exist are a single operation that is atomic with respect to all other filesystem activities that might affect the file.
OK I MARK YOUR FILE NAME
Just add a BACKSLASH in extractFolder at END
v
v
v
String extractFolder = "/mnt/sdcard/MyFolder/";
^ // <--- HERE
^
^
Because File gpxfile = new File(root, "gpxfile.txt"); doesn't have BackSlash / as Log have
Just try Once Following:
while(scanner.hasNextLine()) {
String inc = scanner.nextLine();
// // counter = Integer.parseInt(inc);
Log.i("INSIDE WHILE: ", inc);
System.out.println("Next Line ::"+inc); // Also check this
}
Related
I used BufferedReader and FileReader to read a file but everytime I read it, it just displays no name found. Thanks in advance.
BufferedReader ifile = new BufferedReader (new FileReader ("data.txt"));
String N;
while(true)
{
N=ifile.readLine();
if (N == null){
System.out.print("\fNo name found\n");
break;
}
number = Integer.parseInt(ifile.readLine());
house = ifile.readLine();
form = ifile.readLine();
dob = ifile.readLine();
System.out.println("Name: " + N + "\nNumber: " + number + "\nHouse: " + house + "\nForm: " + form + "\nDate of Birth: " + dob);
}
ifile.close();
Answer might have already been given in another topic like: Read all lines with BufferedReader
So it might be a duplicate.
However when you read a file via BufferedReader it is recommended you do it like
FileReader filereader = new FileReader("data.txt");
BufferedReader ifile = new BufferedReader(filereader);
String N;
ArrayList<String> file_contents= new ArrayList<String>();
//List will now contain the whole txt
try {
while((N = input.readLine()) != null) {
file_contents.add(N);
}
ifile.close();
}
catch(IOException e){
e.printStackTrace();
}
And then break the list's contents to get what you want.
Using a try/catch block can avoid the error of not knowing how to handle that the file "data.txt" cannot be read.
Your way of doing it (while(true)) doesn't pass the name in any variable so it can be printed out and also just checks if the 1st line of your data.txt file is empty or not and does nothing with the remaining lines if that condition is true.
In addition to the above check if the source of your problem is in the txt file.
For example if its structure is the way you want it to be.
I am trying to complete a simple program that uses the command line to replace a specified String in a file. Command line entry would be java ReplaceText textToReplace filename
The code completes, but the file does not replace the specified string. I have Googled similar situations but I cannot figure out why my code is not working.
import java.io.*;
import java.util.*;
public class ReplaceText{
public static void main(String[] args)throws IOException{
if(args.length != 2){
System.out.println("Incorrect format. Use java ClassName textToReplace filename");
System.exit(1);
}
File source = new File(args[1]);
if(!source.exists()){
System.out.println("Source file " + args[1] + " does not exist.");
System.exit(2);
}
File temp = new File("temp.txt");
try(
Scanner input = new Scanner(source);
PrintWriter output = new PrintWriter(temp);
){
while(input.hasNext()){
String s1 = input.nextLine();
String s2 = s1.replace(args[0], "a");
output.println(s2);
}
temp.renameTo(source);
source.delete();
}
}
}
Edit: edited the code so I am not reading and writing to the file at the same time, but it still does not work.
First of all you have a problem with your logic. You are renaming your temporary file then immediately deleting it. Delete the old one first, then rename the temporary file.
Another problem is that you are attempting to do perform the delete and rename within your try block:
try(
Scanner input = new Scanner(source);
PrintWriter output = new PrintWriter(temp);
){
...
temp.renameTo(source);
source.delete();
}
Your streams are not automatically closed until the try block ends. You will not be able to rename or delete while the stream is open. Both delete and renameTo return a boolean to indicate whether they were successful so it may be prudent to check those values.
Correct code may look something like:
try(
Scanner input = new Scanner(source);
PrintWriter output = new PrintWriter(temp);
){
while(...)
{
...
}
}
// Try block finished, resources now auto-closed
if (!source.delete())
{
throw new RuntimeException("Couldn't delete file!");
}
if (!temp.renameTo(source))
{
throw new RuntimeException("Couldn't rename file!");
}
You can't replace strings a file in general. You need to read the input line by line, replace each line as necessary, and write each line to a new file. Then delete the old file and rename the new one.
I have a .txt file in ExternalStorageDirectory() in Android. This file contains 10 sentence line by line. I want to read each sentence one by one. And then show it on EditText when every button click. I found only all file reading codes. I don't want this. How can I do that? Here is my little code:
enter cod private String Load() {
String result = null;;
String FILE_NAME = "counter.txt";
//if (isExternalStorageAvailable() && isExternalStorageReadOnly()) {
String baseDir = Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + "Records";
File file = new File(baseDir, FILE_NAME);
String line = "";
StringBuilder text = new StringBuilder();
try {
FileReader fReader = new FileReader(file);
BufferedReader bReader = new BufferedReader(fReader);
while( (line = bReader.readLine()) != null ){
text.append(line+"\n");
}
result = String.valueOf(text);
} catch (IOException e) {
e.printStackTrace();
}
//}
return result;
}
All Load() does is reads the file and returns it as a String. From here, you have a few options.
1).
Convert the result to an array of Strings using String.split('\n'), and grab the next value when you click the button. Here's a quick example:
int counter = 0;
String file = Load();
String[] lines = file.split("\n");
button.onClicked() {
editText.setText(lines[counter++]);
}
2).
Declare the buffered reader as a class member, so you can call readLine() inside the button's onClicked() method. This way, it will only read one line of the file when someone clicks the button, instead of reading the whole file in Load().
public static String getFilename(Scanner getFile) throws FileNotFoundException {
System.out.print("\nEnter file name: ");
String filename = getFile.next();
File f = new File(filename);
if (f.exists()) {
System.out.println(filename + " exists.");
} else {
System.out.println(filename + " does not exist.");
getFilename(getFile);
}
return filename;
}
This is my current code. It asks me to type some text, then checks if my typed input is a file.
If the file exists, I want it to return the String that the filename is stored as, back to my main method.
If it doesn't exist, I want my method to restart(?). How do I loop it? My current method just re-calls the entire method but if I run this code, any input/filename that doesn't exist as a File will come up as an error.
File f = new File([filename]);
while(!f.exists()) {
f = new File([newFilename]);
}
// Do what you want to do with the file.
This also allows you to directly return the file instead of a filename, but you could return the filename like so:
String s = [filename];
File f = new File(s);
while(!f.exists()) {
s = [newFilename];
f = new File(s);
}
return s;
Keep in mind that this will infinitely loop if you don't ever provide a real file.
A loop is exactly what you need. Inside your method:
String fileName = "";
File f = new File(fileName);
while(!f.exists()) {
System.out.println("Enter file name: ");
fileName = getFile.next();
f = new File(fileName);
}
return f;
Basically, the code will prompt you for a file until you enter a file name that exists.
This should do the trick
String filename = null;
do{
System.out.print("Enter file name: ");
filename = getFile.nextLine();
} while (!new File(filename).exists());
after this loop you are sure filename refers to file which exists.
I have a question about txt file in the Java
When I have to read the text file, i have to point out the path.
However, txt file is in the same folder.
What need to do is...
testing readingoption filename.
testing : class name
readoption : option for reading file
filename: file name that same folder.
However, I don't want to use path to pointing out the file which means that I want to read the text file without using "C:/Users/myname/Desktop/myfolder/" in my code.
does anybody know how to do it ?
thanks.
public class testing{
private static boolean debug = true;
public static void main(String args [])
{
if(args.length == 0)
{// if you do nothing
if(debug == true)
{
System.out.println(args);
}
System.err.println("Error: Missing Keywords");
return;
}
else if(args.length == 1)
{// if you miss key word
if(debug == true)
{
System.out.println(args);
}
System.err.println("Error: Missing filename");
return;
}
else
{// if it is fine
String pathes = "C:/Users/myname/Desktop/myfolder/";// dont want to use this part
if(debug == true)
{
System.out.println("Everthing is fine");
System.out.println("Keyword :" + args[0]);
System.out.println("File name :" + args[1]);
}
try{
// Open the file that is the first
// command line parameter
FileInputStream fstream = new FileInputStream(pathes + "bob.txt");
// Get the object of DataInputStream
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strLine;
//Read File Line By Line
while ((strLine = br.readLine()) != null) {
// Print the content on the console
System.out.println (strLine);
}
//Close the input stream
in.close();
}catch (Exception e){//Catch exception if any
System.err.println("Error: " + e.getMessage());
}
}
}
}
Change this line String pathes = "C:/Users/myname/Desktop/myfolder/"; to:
String pathes = args[1];
and this line FileInputStream fstream = new FileInputStream(pathes + "bob.txt"); to:
FileInputStream fstream = new FileInputStream(pathes);
If you put text file into i.e. "myfolder" in your java project your path should be like this:
String pathes = "/myfolder/bob.txt";
FileInputStream fstream = new FileInputStream(pathes);
Load the path of the file from a .properties file (use the java.util.Properties class), or pass it as a parameter from commandline (in your main String[] argument).
Either way, your code that processes the file must not do it, it must be done in the outside. Your processing code receives the file path from the method calling it, so you do not need to change if you decide to use another method (v.g., a GUI).
You can use "." for the actual Path and add the system dependend file seperator like:
FileInputStream fstream = new FileInputStream("."+System.getProperty("file.separator")+"bob.txt");