Here I have this code shortened to show the most important methods in question: The method void writeToFile(string filename) is in my superclass called "Words"
public void writeToFile(String filename) throws IOException {
FileWriter out = null;
try {
File outFile = new File(filename);
out = new FileWriter(outFile);
out.write("Writing to a text file");
}
catch(IOException e) {
System.err.println(e.getMessage());
}
finally {
if(out != null) { out.close(); }
}
}
I also have this method below in my concrete sub class which creates a file with a given name:
public Vowels makeVowels(String filename) throws IOException, InvalidSequenceException {
writeToFile("vowels.txt");
Vowels vowel = new Vowels(this.getDescription("vowels.txt"), this.getContent("vowels.txt"));
return vowel;
}
If I call the method writeToFile("vowels.txt") from my subclass to create a new file this does not create the file ? How can I call the writeToFile method from my subclass to create this vowels.txt file ?
I found the solution was to move the writeToFile("vowels.txt") from my vowels method to a different place such as in my constructor or creating a new method and calling this writeToFile("vowels.txt") works. Also as suggested by Robertos Attias using System.out.println(System.getProperty("user.dir")); showed the current directory.
Related
I'm trying to get this to work but it doesn't and I don't get why,
It's supposed to be a script where I enter an argument file and it replaces it with the correct replaced characters in it.
It doesn't replace the file I entered as argument.
I can get it to work If I place the whole code in the main function without calling a method.
Thanks.
public class Rename
{
public static void main(String[] args) throws IOException{
File origine = new File(args[0]);
renameFile(origine);
}
public static void renameFile(File fileOriginal) throws IOException
{
try
{
File tempFile = File.createTempFile("buffer", ".tmp");
FileWriter fw = new FileWriter(tempFile);
Reader fr = new FileReader(fileOriginal);
BufferedReader br = new BufferedReader(fr);
while (br.ready())
{
fw.write(br.readLine().replace("#/A#" , "Á"));
}
fw.close();
br.close();
fr.close();
tempFile.renameTo(fileOriginal);
} catch (IOException e) {
e.printStackTrace();
}
}
}
renameTo() returns a value. You are ignoring it.
You can't rename a file to the name of an existing file. You have to ensure the target name doesn't exist.
ready() is not a test for end of stream: see the Javadoc.
A method that modifies the content of a file should not be called renameFile().
I have been trying to compare the file content with user input. The program is reading from a specific file and it checks against the user's string input. I am having trouble comparing the ArrayList with the user input.
public class btnLoginListener implements Listener
{
#Override
public void handleEvent(Event arg0)
{
//variables for the class
username = txtUsername.getText();
password = txtPassword.getText();
MessageBox messageBox = new MessageBox(shell, SWT.OK);
try {
writeFile();
messageBox.setMessage("Success Writing the File!");
} catch (IOException x)
{
messageBox.setMessage("Something bad happened when writing the file!");
}
try {
readFile("in.txt");
} catch (IOException x)
{
messageBox.setMessage("Something bad happened when reading the file!" + x);
}
if (username.equals(names))
{
messageBox.setMessage("Correct");
}
else
{
messageBox.setMessage("Wrong");
}
messageBox.open();
}
}
private static void readFile(String fileName) throws IOException
{
//use . to get current directory
File dir = new File(".");
File fin = new File(dir.getCanonicalPath() + File.separator + fileName);
// Construct BufferedReader from FileReader
BufferedReader br = new BufferedReader(new FileReader(fin));
String line = null;
while ((line = br.readLine()) != null)
{
Collections.addAll(names, line);
}
br.close();
}
I am assuming you are trying to check whether an element exists in the list. If yes, then you need to use contains method, here's the Javadoc.
So, instead of using if (username.equals(names)), you can use if (names.contains(username)).
Apart from this, you should make the following changes:
Don't read the file every time an event is called. As you are reading a static file, you can read it once and store it in an ArrayList.
Make variables username and password local.
Remove writeFile() call unless it's appending/writing dynamic values on each event.
I'm using JDK 7. I've got a class with a method that creates a html-file using PrintStream. Another method in the same class is supposed to use the created file and do stuff with it. The problem is that once i use new File("path/to/file.html), the file lenght is reduced to 0. My code:
public class CreatePDFServiceImpl {
private final PrintStream printStream;
public CreatePDFServiceImpl() throws IOException {
printStream = new PrintStream("/mnt/test.html", "UTF-8");
}
public void createHtmlFile() throws IncorporationException {
try {
StringBuilder html = new StringBuilder();
HtmlFragments htmlFragments = new HtmlFragments();
html.append(htmlFragments.getHtmlTop())
.append(htmlFragments.getHeading())
.append(htmlFragments.buildBody())
.append(htmlFragments.buildFooter());
printStream.print(html.toString());
} finally {
if(printStream != null) {
printStream.close();
}
}
}
This next method is supposed to use the html file created in "createHtmlFile()":
public void convertHtmlToPdf() {
PrintStream out = null;
try {
File file = new File("/mnt/test.html");
/** this code added just for debug **/
if (file.createNewFile()){
System.out.println("File is created!");
} else {
System.out.println("File already exists. size: " + file.length());
}
/* PDF generation commented out. */
//out = new PrintStream("/mnt/testfs.pdf", "UTF-8");
//defaultFileWriter.writeFile(file, out, iTextRenderer);
} catch (IOException e) {
throw new IncorporationException("Could not save pdf file", e);
} finally {
if(out != null) {
out.close();
}
}
My junit integration test class:
#Category(IntegrationTest.class)
public class CreatePDFServiceIntegrationTest {
private static CreatePDFServiceImpl createPDFService;
#BeforeClass
public static void init() throws IOException {
createPDFService = new CreatePDFServiceImpl();
}
#Test
public void testCreateHtmlFile() throws IncorporationException {
createPDFService.createHtmlFile();
File createdFile = new File("/mnt/test.html");
System.out.println("createdFile.length() = " + createdFile.length());
Assert.assertTrue(createdFile.length() > 1);
}
#Test
public void testCreatePDF() throws Exception {
File fileThatShouldExist = new File("/mnt/testfs.pdf");
createPDFService.convertHtml2Pdf();
Assert.assertTrue(fileThatShouldExist.exists());
}
}
The first test passes, output:
"createdFile.length() = 3440".
I checked the file system, there is the file. size 3,44kb.
Second test fails, output from CreatePDFServiceImpl:
"File already exists. size: 0"
Looking in the file system, the file now is actually 0 bytes.
I'm stumped. The new File("path") should only create a reference to that file and not empty it?
I doubt there's an error in File.createNewFile(). I don't yet fully grasp in which order you run your code, but are you aware that this sets the file size to zero?
out = new PrintStream("/mnt/testfs.pdf", "UTF-8");
From the PrintStream(File file) Javadoc:
file - The file to use as the destination of this print stream. If the
file exists, then it will be truncated to zero size; otherwise, a new
file will be created. The output will be written to the file and is
buffered.
I think that's the culprit - but in your code that line is commented out. Am I right you have run your tests with that line commented in?
I am writing a program in Java which displays a range of afterschool clubs (E.G. Football, Hockey - entered by user). The clubs are added into the following ArrayList:
private ArrayList<Club> clubs = new ArrayList<Club>();
By the followng Method:
public void addClub(String clubName) {
Club club = findClub(clubName);
if (club == null)
clubs.add(new Club(clubName));
}
'Club' is a class with a constructor - name:
public class Club {
private String name;
public Club(String name) {
this.name = name;
}
//There are more methods in my program but don't affect my query..
}
My program is working - it lets me add a new Club Object into my arraylist, i can view the arraylist, and i can delete any that i want etc.
However, I now want to save that arrayList (clubs) to a file, and then i want to be able to load the file up later and the same arraylist is there again.
I have two methods for this (see below), and have been trying to get it working but havent had anyluck, any help or advice would be appreciated.
Save Method (fileName is chosen by user)
public void save(String fileName) throws FileNotFoundException {
String tmp = clubs.toString();
PrintWriter pw = new PrintWriter(new FileOutputStream(fileName));
pw.write(tmp);
pw.close();
}
Load method (Current code wont run - File is a string but needs to be Club?
public void load(String fileName) throws FileNotFoundException {
FileInputStream fileIn = new FileInputStream(fileName);
Scanner scan = new Scanner(fileIn);
String loadedClubs = scan.next();
clubs.add(loadedClubs);
}
I am also using a GUI to run the application, and at the moment, i can click my Save button which then allows me to type a name and location and save it. The file appears and can be opened up in Notepad but displays as something like Club#c5d8jdj (for each Club in my list)
You should use Java's built in serialization mechanism.
To use it, you need to do the following:
Declare the Club class as implementing Serializable:
public class Club implements Serializable {
...
}
This tells the JVM that the class can be serialized to a stream. You don't have to implement any method, since this is a marker interface.
To write your list to a file do the following:
FileOutputStream fos = new FileOutputStream("t.tmp");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(clubs);
oos.close();
To read the list from a file, do the following:
FileInputStream fis = new FileInputStream("t.tmp");
ObjectInputStream ois = new ObjectInputStream(fis);
List<Club> clubs = (List<Club>) ois.readObject();
ois.close();
As an exercise, I would suggest doing the following:
public void save(String fileName) throws FileNotFoundException {
PrintWriter pw = new PrintWriter(new FileOutputStream(fileName));
for (Club club : clubs)
pw.println(club.getName());
pw.close();
}
This will write the name of each club on a new line in your file.
Soccer
Chess
Football
Volleyball
...
I'll leave the loading to you. Hint: You wrote one line at a time, you can then read one line at a time.
Every class in Java extends the Object class. As such you can override its methods. In this case, you should be interested by the toString() method. In your Club class, you can override it to print some message about the class in any format you'd like.
public String toString() {
return "Club:" + name;
}
You could then change the above code to:
public void save(String fileName) throws FileNotFoundException {
PrintWriter pw = new PrintWriter(new FileOutputStream(fileName));
for (Club club : clubs)
pw.println(club); // call toString() on club, like club.toString()
pw.close();
}
In Java 8 you can use Files.write() method with two arguments: Path and List<String>, something like this:
List<String> clubNames = clubs.stream()
.map(Club::getName)
.collect(Collectors.toList())
try {
Files.write(Paths.get(fileName), clubNames);
} catch (IOException e) {
log.error("Unable to write out names", e);
}
This might work for you
public void save(String fileName) throws FileNotFoundException {
FileOutputStream fout= new FileOutputStream (fileName);
ObjectOutputStream oos = new ObjectOutputStream(fout);
oos.writeObject(clubs);
fout.close();
}
To read back you can have
public void read(String fileName) throws FileNotFoundException {
FileInputStream fin= new FileInputStream (fileName);
ObjectInputStream ois = new ObjectInputStream(fin);
clubs= (ArrayList<Clubs>)ois.readObject();
fin.close();
}
ObjectOutputStream.writeObject(clubs)
ObjectInputStream.readObject();
Also, you 'add' logic is logically equivalent to using a Set instead of a List. Lists can have duplicates and Sets cannot. You should consider using a set. After all, can you really have 2 chess clubs in the same school?
To save and load an arraylist of
public static ArrayList data = new ArrayList ();
I used (to write)...
static void saveDatabase() {
try {
FileOutputStream fos = new FileOutputStream("mydb.fil");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(data);
oos.close();
databaseIsSaved = true;
}
catch (IOException e) {
e.printStackTrace();
}
} // End of saveDatabase
And used (to read) ...
static void loadDatabase() {
try {
FileInputStream fis = new FileInputStream("mydb.fil");
ObjectInputStream ois = new ObjectInputStream(fis);
data = (ArrayList<User>)ois.readObject();
ois.close();
}
catch (IOException e) {
System.out.println("***catch ERROR***");
e.printStackTrace();
}
catch (ClassNotFoundException e) {
System.out.println("***catch ERROR***");
e.printStackTrace();
}
} // End of loadDatabase
I'm using org.apache.commons.net.ftp to download files in a remote machine.
There is a method, that reads the files to a FileOutputStream object.
ftpClient.retrieveFile("/" + ftpFile.getName(), fos);
Problem, here is, i've another method that accepts a File object. So, i need to create a File object file the FileOutputStream. I think, i need to create an InputStream to be able to create a file object from the FileOutputStream. is this correct? I might be missing something and there should be an easy way to create a File from a FileOutputStream?
FileOutputStream has a constructor that takes a File object.
The following should do what you need it to do:
File f = new File("path/to/my/file");
if(f.createNewFile()) { // may not be necessary
FileOutputStream fos = new FileOutputStream(f); // create a file output stream around f
ftpClient.retrieveFile("/" + ftpFile.getName(), fos);
otherMethod(f); // pass the file to your other method
}
Note that in addition to the answer of mcfinnigan, you must know that when you use the code:
FileOutputStream fos = new FileOutputStream(f); // create a file output stream around f
ftpClient.retrieveFile("/" + ftpFile.getName(), fos);
Then an empty file will be created on your filesystem on the first line. Then if the 2nd line throws an exception, because no remote file exist for path "/" + ftpFile.getName(), the empty file will still be on your filesystem.
So I've done a little LazyInitOutputStream with Guava to handle that:
public class LazyInitOutputStream extends OutputStream {
private final Supplier<OutputStream> lazyInitOutputStreamSupplier;
public LazyInitOutputStream(Supplier<OutputStream> outputStreamSupplier) {
this.lazyInitOutputStreamSupplier = Suppliers.memoize(outputStreamSupplier);
}
#Override
public void write(int b) throws IOException {
lazyInitOutputStreamSupplier.get().write(b);
}
#Override
public void write(byte b[]) throws IOException {
lazyInitOutputStreamSupplier.get().write(b);
}
#Override
public void write(byte b[], int off, int len) throws IOException {
lazyInitOutputStreamSupplier.get().write(b,off,len);
}
public static LazyInitOutputStream lazyFileOutputStream(final File file) {
return lazyFileOutputStream(file,false);
}
public static LazyInitOutputStream lazyFileOutputStream(final File file,final boolean append) {
return new LazyInitOutputStream(new Supplier<OutputStream>() {
#Override
public OutputStream get() {
try {
return new FileOutputStream(file,append);
} catch (FileNotFoundException e) {
throw Throwables.propagate(e);
}
}
});
}
I've encoutered this problem while using Spring integration remote.file packages, with the FTP/SFTP file download features. I use it like that to solve this empty file problem:
try ( OutputStream downloadedFileStream = LazyInitOutputStream.lazyFileOutputStream(destinationfilePath.toFile()) ) {
remoteFileSession.read(source, downloadedFileStream);
}