I get a resource leak warning in return new ArrayList<>();. The file is not writing in the friends.txt which I am trying to save list in a text file. Please help.
import java.io.*;
import java.util.ArrayList;
public class ReadWrite {
public void writeFriends(ArrayList<Friend> friends) {
FileOutputStream friendFile;
ObjectOutputStream friendWriter;
try {
friendFile = new FileOutputStream(new File("C:\\Users\\aa\\Desktop\\src\\friends.txt"));
friendWriter = new ObjectOutputStream(friendFile);
if(friends.size() >0) {
friendWriter.writeInt(friends.size());
for (Friend friend : friends) {
friendWriter.writeObject(friend);
}
}
else {
System.out.println("No data to write");
}
friendWriter.close();
friendFile.close();
} catch (FileNotFoundException e) {
System.out.println("File Not Found. Retry after creating File 'Friends.txt'");
} catch (IOException e) {
System.out.println("Stream cannot be initialized.");
}
}
public ArrayList<Friend> readFriends() {
FileInputStream friendFile;
ObjectInputStream friendReader;
ArrayList<Friend> friends = new ArrayList<>();
try {
friendFile = new FileInputStream(new File("C:\\Users\\aa\\Desktop\\src\\friends.txt"));
friendReader = new ObjectInputStream(friendFile);
int size = friendReader.readInt();
if(size > 0){
for (int i = 0; i < friendReader.readInt(); i++) {
friends.add((Friend) friendReader.readObject());
}
}
else{
System.out.println("Empty File");
return new ArrayList<>();
}
friendReader.close();
friendFile.close();
} catch (FileNotFoundException e) {
System.out.println("File Not Found. Retry after creating File 'Friends.txt'");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
System.out.println("Stream cannot be inititalized");
}
return friends;
}
}
I am trying to save a list of friends in the friends.txt file. I see no output in the friends.txt file. Is it something to do with my location or FileOutputStream ?
You have two problems in your code.
There is a bug in the for loop in method readFriends of class ReadWrite.
The file friends.txt may not be closed.
Here is the corrected code. Note that I could not find the code for class Friend in your question so I wrote a minimal class. Since you are using serialization, I assume that class Friend implements interface Serializable.
Notes after the code.
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
public class ReadWrite {
public void writeFriends(ArrayList<Friend> friends) {
try (OutputStream friendFile = Files.newOutputStream(Paths.get("C:", "Users", "aa", "Desktop", "src", "friends.dat"));
ObjectOutputStream friendWriter = new ObjectOutputStream(friendFile)) {
if (friends.size() > 0) {
friendWriter.writeInt(friends.size());
for (Friend friend : friends) {
friendWriter.writeObject(friend);
}
}
else {
System.out.println("No data to write");
}
}
catch (FileNotFoundException e) {
System.out.println("File Not Found. Retry after creating File 'friends.dat'");
e.printStackTrace();
}
catch (IOException e) {
System.out.println("Stream cannot be initialized.");
e.printStackTrace();
}
}
public ArrayList<Friend> readFriends() {
ArrayList<Friend> friends = new ArrayList<>();
try (InputStream friendFile = Files.newInputStream(Paths.get("C:", "Users", "aa", "Desktop", "src", "friends.dat"));
ObjectInputStream friendReader = new ObjectInputStream(friendFile)) {
int size = friendReader.readInt();
if (size > 0) {
for (int i = 0; i < size; i++) {
friends.add((Friend) friendReader.readObject());
}
}
else {
System.out.println("Empty File");
return new ArrayList<>();
}
}
catch (FileNotFoundException e) {
System.out.println("File Not Found. Retry after creating File 'friends.dat'");
e.printStackTrace();
}
catch (ClassNotFoundException e) {
e.printStackTrace();
}
catch (IOException e) {
System.out.println("Stream cannot be inititalized");
e.printStackTrace();
}
return friends;
}
public static void main(String[] args) {
ArrayList<Friend> friends = new ArrayList<>();
Friend friend = new Friend("Jane");
friends.add(friend);
ReadWrite rw = new ReadWrite();
rw.writeFriends(friends);
ArrayList<Friend> newFriends = rw.readFriends();
System.out.println(newFriends);
}
}
class Friend implements Serializable {
private String name;
public Friend(String name) {
this.name = name;
}
public String toString() {
return name;
}
}
In the for loop condition in method readFriends you have the following:
friendReader.readInt()
This means that in every loop iteration, you are trying to read another int from the file friends.txt. This call fails since there is only one int in the file. Hence you need to use size which is the variable that contains the only int in file friends.txt which you read before the for loop.
Since you are using serialization, it is recommended to give the file name an extension of .dat rather than .txt since the file is not a text file.
I always write printStackTrace() in my catch blocks since that helps me to locate the cause of the exception. You actually should not get a FileNotFoundException since Java will create the file if it doesn't exist. If Java fails to create the file, then it is probably because the user has no permission to create a file, so displaying an error message saying to create the file before running your code probably won't help.
Your code may successfully open the file and write some data to it and crash before you have written all the data. In that case, your code does not close the file. If you are using at least Java 7, then you should use try-with-resources to ensure that the files are always closed.
Java 7 also introduced NIO.2 as a better API for interacting with the computer's file system from Java code. I suggest that you use it as I have shown in the code, above.
Related
So I'm trying to write in a text file, nothing too complicated, but for some reason the new text that i want to add doesn't change lines, it keeps going on the same line, and I can't figure out why. The irrelevant parts are being commented so don't worry about them.
import java.util.List;
import java.util.ArrayList;
import java.util.Collections;
import java.io.File;
import java.io.IOException;
import java.io.FileWriter;
public class Main {
public static void main( String args[]) {
int a = 32;
int b=12;
int c=33;
List<Integer> myList = new ArrayList();
myList.add(a);
myList.add(b);
myList.add(c);
/* for(int s:myList)
{
System.out.println(s);
}
*/
//Om ar= new Om("Alex",21,185);
//System.out.println(ar);
try{
File myObj = new File("filename.txt");
if(myObj.createNewFile()){
System.out.println("File created " + myObj.getName());
}
else
{
System.out.println("File already exists");
}
}
catch (IOException e)
{
System.out.println("An error has occurred");
e.printStackTrace();
}
try {
FileWriter myWriter = new FileWriter("filename.txt");
for(int i=1;i<10;i++)
{
myWriter.append("This is a new file, nothing sus here."+i + " ");
}
myWriter.close();
System.out.println("Successfully wrote to the file.");
} catch (IOException e) {
System.out.println("An error occurred.");
e.printStackTrace();
}
}
}
Wrap your FileWriter in a BufferedWriter to make writing to the file more efficient.
Then you can use the newLine() method of the BufferedWriter to add a newline String to the file as you require. The newLine() method will write out the appropriate string for your current platform.
So I have a real strange bug, I get my objects into a arraylist, write them out to see if everything is there, everything checks out, i write them down into a file, eveything is there when I open the file, but when i go on to read them some objects are for unknow reasons not read, like that entry isnt exisitng in the file, but I can see in the file that they are there. Anyone know that I'm missing here?
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
public class ReadWriteTD {
public static void write(ArrayList<Tokendata> list) {
try {
FileOutputStream f = new FileOutputStream(new File("src/resources/TokenProfiles"));
ObjectOutputStream o = new ObjectOutputStream(f);
// Write objects to file
list.forEach(a -> {
try {
o.writeObject(a);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
});
o.close();
f.close();
} catch (FileNotFoundException e) {
System.out.println("File not found");
} catch (IOException e) {
System.out.println("Error initializing stream");
}
}
public static ArrayList<Tokendata> read() {
ArrayList<Tokendata> list = new ArrayList<Tokendata>();
try {
FileInputStream fi = new FileInputStream(new File("src/resources/TokenProfiles"));
ObjectInputStream oi = new ObjectInputStream(fi);
Boolean cond = true;
while(cond){
if(oi.readObject() != null)
list.add((Tokendata) oi.readObject());
else cond=false;
}
oi.close();
fi.close();
}catch(Exception e){
}
//list.forEach(a -> System.out.print(a.toString()));
return list;
}
}
This is the problem:
if(oi.readObject() != null)
list.add((Tokendata) oi.readObject());
That's calling readObject() twice per iteration. The result of the first call is ignored other than to check whether or not it's null. You just want something like:
Object obj;
while ((obj = oi.readObject()) != null) {
list.add((Tokendata) obj);
}
No need for your cond variable, and now you're only calling readObject once per iteration.
I am not sure why file , BankAccount.ser is empty after successful run of below code. BankAccount.ser file is a class path resource. After successful run of SuccessfulSerializationTestDriver , BankAccount.ser is zero bytes on disk and has no contents.
public class SuccessfulSerializationTestDriver {
public static void main(String[] args) {
long accountNumber=12033456;
String bankName="SBI";
String branch="NOIDA";
SerializableBankAccount sBankAccount = new SerializableBankAccount();
sBankAccount.setAccountNumber(accountNumber);
sBankAccount.setBankName(bankName);
sBankAccount.setBranch(branch);
try(FileOutputStream fileOut =new FileOutputStream("BankAccount.ser")){
ObjectOutputStream out= new ObjectOutputStream(fileOut);
out.writeObject(sBankAccount);
out.flush();
out.close();
System.out.println("Bank Account is successfully serialized");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Serializable class is ,
public class SerializableBankAccount implements Serializable {
private static final long serialVersionUID = 1L;
private long accountNumber;
private String bankName;
private String branch;
public long getAccountNumber() {
return accountNumber;
}
public void setAccountNumber(long accountNumber) {
this.accountNumber = accountNumber;
}
public String getBankName() {
return bankName;
}
public void setBankName(String bankName) {
this.bankName = bankName;
}
public String getBranch() {
return branch;
}
public void setBranch(String branch) {
this.branch = branch;
}
#Override
public String toString(){
return accountNumber+","+bankName+","+branch;
}
}
EDIT : I wrote deserializer and I am getting object successfully - so it just seems a visibility issue. Somehow file is shown of zero bytes.
public class SuccessfulDeSerializationTestDriver {
public static void main(String[] args) {
SerializableBankAccount sBankAccount = null;
try(FileInputStream fileIn =new FileInputStream("BankAccount.ser")){
ObjectInputStream inStream= new ObjectInputStream(fileIn);
sBankAccount= (SerializableBankAccount) inStream.readObject();
inStream.close();
System.out.println("Successfully Deserialized Object is "+sBankAccount);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
Successfully Deserialized Object is 12033456,SBI,NOIDA
If the file you're looking at is zero bytes, but it deserializes successfully, it sounds like the file is being created elsewhere. Perhaps specify the path explicitly when you create the file name for a start. The file with size 0, may be from an older run - delete that on disk, and see if it gets created again.
I am not able to recreate the problem you're having. When I run your code the BankAccount.ser file is created and is not empty. In fact I wrote a deserialization test to see if I could get the object back by reading the file and it works fine.
Here is the deserializing class in case you want it:
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
public class DeserializationTestDriver {
public static void main(String[] args) {
try(FileInputStream fileInput =new FileInputStream("BankAccount.ser")){
ObjectInputStream input = new ObjectInputStream(fileInput);
SerializableBankAccount sBankAccount = (SerializableBankAccount) input.readObject();
input.close();
System.out.println("Bank Account is successfully deserialized: "+sBankAccount.toString());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
I also added a toString method to your SerializableBankAccount:
#Override
public String toString() {
return "SerializableBankAccount [accountNumber=" + accountNumber
+ ", bankName=" + bankName + ", branch=" + branch + "]";
}
After running your serialization code and then running the above deserialization I get this output:
Bank Account is successfully deserialized: SerializableBankAccount [accountNumber=12033456, bankName=SBI, branch=NOIDA]
So clearly the code is fine, which means it has to be something to do with the environment. I suggest checking whether you're running the program with correct privileges, permissions, etc. It seems that something external to your code is preventing you from writing to the file. Either that or perhaps you're looking at the wrong file, verify you have the correct path and check the file creation and modification dates.
I've found answers to various questions on here before, but this is my first time asking one. I'm kicking around an idea for my final project in my computer programming class, and I'm working on a few proof of concept programs in Java, working in Eclipse. I don't need anything more than to get the filepaths of the contents of a directory and write them to a .txt file. Thanks in advance!
Edit: I am posting my code below. I found a snippet of code to use for getting the contents and print them to the screen, but the print command is a placeholder that I'll replace with a write to folder command when I can.
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
public class ScanFolder {
public static void main(String[] args) throws IOException {
Files.walk(Paths.get("C:/Users/Joe/Desktop/test")).forEach(filePath -> {
if (Files.isRegularFile(filePath)) {
System.out.println(filePath);
}
});
}
}
EDIT: I've enclosed the OutputStreamWriter in a BufferedWriter
public static void main(String[] args) {
FileOutputStream fos = null;
try {
fos = new FileOutputStream("txt.txt");
} catch (FileNotFoundException e) {
e.printStackTrace();
return;
}
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(fos));
writeContentsOfFileToAFile(new File("."), out, true); // change true to
// false if you
// don't want to
// recursively
// list the
// files
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
static void writeContentsOfFileToAFile(File parent, BufferedWriter out, boolean enterIntoDirectory) {
for (File file : parent.listFiles()) {
try {
out.write(file.toString() + "\r\n");
} catch (IOException e) {
e.printStackTrace();
}
if (enterIntoDirectory && file.isDirectory())
writeContentsOfFileToAFile(file, out, enterIntoDirectory);
}
}
Is this what you need?
I have written the code bellow to check if a properties file exists and has the required properties. If it exists it prints the message that the file exists and is intact, if not then it creates the properties file with the required properties.
What I wanted to know is, is there a more elegant way of doing this or is my way pretty much the best way? Also the minor problem that I'm having is that with this way it doesn't check for extra properties that should not be there, is there a way to do that?
Summary of my requirements:
Check if the file exists
Check if it has the required properties
Check if it has extra properties
Create the file with the required properties if it doesn't exist or if there are extra or missing properties
Source files and Netbeans Project download
Source:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Properties;
public class TestClass {
public static void main(String[] args) {
File propertiesFile = new File("config.properties");
if (propertiesFile.exists() && propertiesExist(propertiesFile)) {
System.out.println("Properties file was found and is intact");
} else {
System.out.println("Properties file is being created");
createProperties(propertiesFile);
System.out.println("Properties was created!");
}
}
public static boolean propertiesExist(File propertiesFile) {
Properties prop = new Properties();
InputStream input = null;
boolean exists = false;
try {
input = new FileInputStream(propertiesFile);
prop.load(input);
exists = prop.getProperty("user") != null
&& prop.getProperty("pass") != null;
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return exists;
}
public static void createProperties(File propertiesFile)
{
Properties prop = new Properties();
OutputStream output = null;
try {
output = new FileOutputStream(propertiesFile);
prop.setProperty("user", "username");
prop.setProperty("pass", "password");
// save properties to project root folder
prop.store(output, null);
} catch (IOException io) {
io.printStackTrace();
} finally {
if (output != null) {
try {
output.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
this is my way. (not sure if more elegant, but it can be an inspiration/different aproach)
Try/catch should be enough to see if the file exists or not
try {
loading files etc...
} catch (FileNotFoundException e) {
throw new MojoExecutionException( "[ERROR] File not found", e );
} catch (IOException e) {
throw new MojoExecutionException( "[ERROR] Error reading properties", e );
}
Code that checks your loaded prop:
Properties tmp = new Properties();
for(String key : prop.stringPropertyNames()) {
if(tmp.containsKey(key)){
whatever you want to do...
}
}
I use tmp, a new properties variable, to compare with ,but the key variable will hold a string so in the if statement you can compare it to array of strings and the way you do it is up to you.