I want to print the objects within an ArrayList (projects) to a file as a string. They are currently stored as 'Projects' which is defined in a different class.
When I use System.out.print rather than outputStream.print, it works fine, and the information appears as expected. As soon as I want it in a file, the file doesn't appear.
import java.io.PrintWriter;
import java.util.ArrayList;
import java.io.FileOutputStream;
import java.io.FileNotFoundException;
public class FileController
{
public static void finish(ArrayList<Project> projects)
{
PrintWriter outputStream = null;
try
{
outputStream = new PrintWriter(new FileOutputStream("project.txt"));
}
catch (FileNotFoundException e)
{
System.out.println("Error opening the file stuff.txt.");
System.exit(0);
}
System.out.println("Writing to file");
for(int i = 0; i < projects.size(); i++)
{
//System.out.print(projects.get(i) + "," + projects.get(i).teamVotes);
outputStream.println(projects.get(i) + "," + projects.get(i).teamVotes);
}
outputStream.close();
System.out.println("End of Program");
}
}
I'm sure the file is somewhere, your code has no errors. At least, I don't see any. Maybe you need to call outputStream.flush() since the constructor you are using uses automatic line flushing from the given OutputStream, see the documentation. But afaik closing the stream will flush automatically.
Your path "project.txt" is relative, so the file will be placed where your code is being executed. Usually, that is near the .class files, check all folders around there in your project.
You can also try an absolute path like
System.getProperty("user.home") + "/Desktop/projects.txt"
then you will easily find the file.
Anyways, you should use Javas NIO for writing and reading files now. It revolves around the classes Files, Paths and Path. The code may then look like
// Prepare the lines to write
List<String> lines = projects.stream()
.map(p -> p + "," + p.teamVotes)
.collect(Collectors.toList());
// Write it to file
Path path = Paths.get("project.txt");
Files.write(path, lines);
and that's it, easy.
Related
I have a homework to do and I don't know how to get started. I have to read from an external text file the paths of some random folders. I must make the paths for this folders available even I change the computer.
Then I have to output in the console the number of mp3 files found in every each folder.
My big problem is that I don't know how to make those paths work for every computer on which I run the program and also I don't know how the filter the content.
LATER EDIT: I've managed to write some code. I can search now for the mp3, but... can someone help me with this: how can i add a new path to the txt file from keyboard and also how can i remove an entire line from it?
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
String ext = ".mp3";
BufferedReader br = new BufferedReader(new FileReader("Monitor.txt"));
for (String line; (line = br.readLine()) != null;) {
findFiles(line, ext);
}
br.close();
}
private static void findFiles(String dir, String ext) {
File file = new File(dir);
if (!file.exists())
System.out.println(dir + " No such folder folder");
File[] listFiles = file.listFiles(new FiltruTxt(ext));
if (listFiles.length == 0) {
System.out.println(dir + " no file with extension " + ext);
} else {
for (File f : listFiles)
System.out.println("Fisier: " + f.getAbsolutePath());
}
}
}
import java.io.File;
import java.io.FilenameFilter;
public class FiltruTxt implements FilenameFilter{
private String ext;
public FiltruTxt(String ext){
this.ext = ext.toLowerCase();
}
#Override
public boolean accept(File dir, String name) {
return name.toLowerCase().endsWith(ext);
}
}
I think that with "available even I change the computer" mean that you need to read the path from the file and not hard code it on your program so if you run in other computer you only need to change the text file and not the program.
But as #André Stannek had said in his comment, you must add to your question what have you tried and what is the exact programming problem you are facing.
When you face a problem, try to divide it in individual and more small problems. For example:
How to read a line from the console?
How to write a new line to a file?
Then try to search for a solution (if you can't think in one). For example in stack overflow, google and of course in the official documentation.
The official documentation:
http://docs.oracle.com/javase/tutorial/essential/io/index.html
Some questions in stackoverflow:
Read multiple lines from console and store it in array list in Java?
Read string line from console
How do I add / delete a line from a text file?
How to add a new line of text to an existing file in Java?
Or this links from Internet:
http://www.msccomputerscience.com/2013/01/write-java-program-to-get-input-from.html
This is the portal of the Java tutorials that you will found very useful when you are learning: http://docs.oracle.com/javase/tutorial/index.html
When I run this as a jar, this .properties file is created on the desktop. For the sake of keeping things clean, how can I set the path to save this file somewhere else, like a folder? Or even the jar itself but I was having trouble getting that to work. I plan on giving this to someone and wouldn't want their desktop cluttered in .properties files..
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Properties;
public class DataFile {
public static void main(String[] args) {
Properties prop = new Properties();
OutputStream output = null;
try {
output = new FileOutputStream("config.properties");
prop.setProperty("prop1", "000");
prop.setProperty("prop2", "000");
prop.setProperty("prop3", "000");
prop.store(output, null);
} catch (IOException io) {
io.printStackTrace();
} finally {
if (output != null) {
try {
output.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
Since you are using the file name without a path, the file you creates ends in the CWD. That is the Current working directory the process inherits from the OS.
That is is you execute your jar file from the Desktop directory any files that use relative paths will end in the Desktop or any of it sub directories.
To control the absolute location of the file you must use absolute paths.
An absolute path always starts with a slash '/'.
Absolute path:
/etc/config.properties
Relative path:
sub_dir/config.properties
The simplest way is to hard code some path into the file path string.
output = new FileOutputStream("/etc/config.properties");
You can of course setup the path in a property which you can pass using the command line instead of hard coding it. The you concat the path name and the file name together.
String path = "/etc";
String full_path = "/etc" + "/" + "config.properties";
output = new FileOutputStream(full_path);
Please note that windows paths in java use a forward slash instead of back slash.
Check this for more details
file path Windows format to java format
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'.
I am using the following java code in NetBeans to read and write to a file.
import java.io.*;
import java.util.*;
public class FileReadWrite {
StringTokenizer tokenizer;
BufferedReader inFile;
PrintWriter outFile;
File myFile;
private int[] highscores = new int[3];
public FileReadWrite() throws IOException, FileNotFoundException {
}
public int[] ReadFromSave() throws IOException, FileNotFoundException {
inFile = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream("/files/highscores.txt" )));
tokenizer = new StringTokenizer(inFile.readLine());
int i = 0;
while (tokenizer.hasMoreTokens()) {
highscores[i] = Integer.parseInt(tokenizer.nextToken());
i++;
}
inFile.close();
return highscores;
}
public void SaveFile(int score) throws IOException, FileNotFoundException {
if (score >= highscores[0]){
highscores[2] = highscores[1];
highscores[1] = highscores[0];
highscores[0] = score;
}
else if (score >= highscores[1]){
highscores[2] = highscores[1];
highscores[1] = score;
}
else if (score >= highscores[2]){
highscores[2] = score;
}
PrintWriter outFile = new PrintWriter(new FileWriter("/files/highscores.txt"));
String line = highscores[0] + " " + highscores[1] + " " + highscores[2];
outFile.println(line);
outFile.close();
}
}
I have coded a tetris program and want to save the highscores after each game. And when the user opens up the app next time they are shown the top 3 scores. The ReadFromSave() method started to work fine after I aded "getClass().getResourceAsStream". However I can't get the SaveFile() method working. I gives error "path/file not found". How should I use the PrintWriter in NetBeans so that it saves into the source packages and thus updating the jar. So when the app is fully closed and reopened it has the recent scores printed in. If this is not possible where can I save data so its not lost?
Thank you!!
If you want to be able to save the scores again, using getResourceAsStream isn't really a good idea - that's meant for resources which are bundled with the application, often within a jar file, and often read-only.
You might want to consider using the Java preferences API or work out some specific location for the file to use to store the high scores. Then just write to that file when saving, and read from it while loading. I wouldn't personally use PrintWriter (it swallows exceptions) or FileWriter (you can't specify the character encoding), but both should work. You just need to make sure you load the scores from the same file as you save it to. (It's not clear whether /files/highscores.txt is really an appropriate file to save to... do you have a /files directory? Were you expecting this to be relative to your application's working directory?)
(Also, it's a good idea to start following Java naming conventions, using camelCasing for method names... and use a try-with-resources statement to close writers, streams etc when you're finished with them, instead of manually calling close.)
You are mixing two things here. You are saving to an absolute path '/files/highscores.txt', but you are reading from the classpath, instead of the file system path. You'd have to choose one approach, but I'd stay away from absolute paths here.
However, a better approach might be to use the Preferences API, or Properties.load / store here. And if you're going to do IO operations, it might be better to look into Apache Commons IO, in which reading a file can be as trivial as doing FileUtils.readLines(file, "UTF-8");
I am trying to read 2 files after i read the files i want to get their contents and manipulate the contents of the two files then update a new file which is the output. The files are in the same folder as the program but the program always throws a FileNotFoundException.
Below is my code:-
import java.io.*;
import java.util.Scanner;
public class UpdateMaster {
public static void main(String[] args)
{
String master = "Customer.dat";
String trans = "Transactns.dat";
String newMaster = "Temp.txt";
Scanner inputStreamMaster = null;
Scanner inputStreamTrans = null;
PrintWriter inputStreamNewMaster = null;
try
{
inputStreamMaster = new Scanner(new File(master));
inputStreamTrans = new Scanner(new File(trans));
inputStreamNewMaster = new PrintWriter(newMaster);
}
catch(FileNotFoundException e)
{
System.out.println("Error: you opend a file that does not exist.");
System.exit(0);
}
catch(IOException e)
{
System.out.println("Error.");
System.exit(0);
}
do
{
String transLine = inputStreamTrans.nextLine();
String masterLine = inputStreamMaster.nextLine();
String[] transLineArr = transLine.split(",");
String[] masterLineArr = masterLine.split(",");
int trAccNo = Integer.parseInt(transLineArr[0]);
int sales = Integer.parseInt(transLineArr[1]);
int masterAccNo = Integer.parseInt(masterLineArr[0]);
int balance = Integer.parseInt(masterLineArr[1]);
while(masterAccNo== trAccNo){
inputStreamNewMaster.println(trAccNo+ " , "+masterAccNo);
masterLine = inputStreamMaster.nextLine();
masterLineArr = masterLine.split(",");
masterAccNo = Integer.parseInt(masterLineArr[0]);
balance = Integer.parseInt(masterLineArr[1]);
}
balance = balance + sales;
inputStreamNewMaster.println(masterAccNo+ " , "+balance);
}while(inputStreamTrans.hasNextLine());
inputStreamMaster.close();
inputStreamTrans.close();
inputStreamNewMaster.close();
//System.out.println(" the line were written to "+ newMaster);
}
}
Like #Ankit Rustagi said in the comments, you need the full path of the files if you want to keep the current implementation.
However, there is a solution where you only need the file names: use BufferedReader / BufferedWriter. See here an example on how to use these classes (in the example it uses the full path but it works without it too).
Use absolute path
String master = "C:/Data/Customer.dat";
String trans = "C:/Data/Transactns.dat";
String newMaster = "C:/Data/Temp.txt";
The code works for me, i guess you misspelled some filename(s) or your files are in the wrong folder. I created your files on the same level as the src or the project. Also this is the folder where the files are exspected.
There's nothing wrong with using relative paths like tihis. What's happening is that your program is looking for the files in the directory where you execute the program, which doesn't have to be the folder of the program. You can confirm this by logging the absolute path of the files before you try to read them. For example:
File masterFile = new File(master);
System.out.printf("Using master file '%s'%n", masterFile.getAbsolutePath());
inputStreamMaster = new Scanner(masterFile);
In general you should not hardcode file paths but allow the user to specify them in someway, for example using command line arguments, a configuration file with a well known path, or an interactive user interface.
There is a way to locate the program's class file but it's a little tricky because Java allows classes to be loaded from compressed archives that may be located in remote systems. It's better to solve this problem in some other manner.
Try this:
String current = new java.io.File( "." ).getCanonicalPath();
System.out.println("I look for files in:"+current);
To see what directory your program expects to find its input files. If it shows the correct directory, check spelling of filenames. Otherwise, you have a clue as to what's gone wrong.