I have a simple txt file that will save only 1 word, but whenever I restart the program everything inside the data.txt is deleted - I don't know why?
The whole class code:
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
public class InfoSaver {
File data = new File("data.txt");
FileOutputStream fos;
PrintStream writer;
FileInputStream fis;
DataInputStream reader;
public void init() throws IOException{
fos = new FileOutputStream(data);
writer = new PrintStream(fos);
fis = new FileInputStream(data);
reader = new DataInputStream(fis);
}
public void writeData(String info) {
writer.println(info);
}
public String readData() throws IOException{
return reader.readLine();
}
public void close() throws IOException{
writer.close();
reader.close();
}
}
To add to an existing file instead of overwriting it, use FileOutputStream's constructor that lets you open it in append mode.
fos = new FileOutputStream(data, true);
Because of this line:
fos = new FileOutputStream(data);
This version of the constructor of FileOutputStream will overwite the file, but you could use this version:
public FileOutputStream(File file,
boolean append)
throws FileNotFoundException
You'd have to specify that you want to append to the file by setting the append field to true.
You're not appending new information to the file, you're overwriting it.
Anytime you just open it in the
fos = new FileOutputStream(data);
command, it gets emptied, no matter if you have saved anything inside it or not.
Your FileOutputStream is overwriting your file. If you want to append to the end of the file you need to specify that:
fos = new FileOutputStream(data, true);
When you encounter unexpected behavior it's a good idea to check the API to ensure the functions you're calling are doing what you expect. Here is the API for the FileOutputStream constructor.
Related
I need to copy a .jar file (which is a resource in my project) from a separate runnable jar to the startup folder in windows. Here's the code I have so far.
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class Installer {
public static void main(String[] args) throws IOException
{
InputStream source = Installer.class.getResourceAsStream("prank.jar");
byte[] buffer = new byte[source.available()];
source.read(buffer);
File targetFile = new File(System.getProperty("user.home") + File.separator + "AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\prank.jar");
OutputStream outStream = new FileOutputStream(targetFile);
outStream.write(buffer);
outStream.close();
}
}
My problem is that after the jar file is copied, it is corrupt (although the size of the original and the copy are the same.) Any thoughts on how to do this and have a runnable jar at the end of the process?
Refer to InputStream#available does not work.
The following line
byte[] buffer = new byte[source.available()];
is not correct, as available only return estimate of the size, the jar will be corrupted when estimate is different with actual. (Example from Java – Write an InputStream to a File) seems incorrect as I can't find any reference that guarantee correctness of available for FileInputStream.
Solution from How to convert InputStream to File in Java is more robust,
private static void copyInputStreamToFile(InputStream inputStream, File file)
throws IOException {
try (FileOutputStream outputStream = new FileOutputStream(file)) {
int read;
byte[] bytes = new byte[1024];
while ((read = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, read);
}
// commons-io
//IOUtils.copy(inputStream, outputStream);
}
}
You can consider to use
IOUtils#copy(InputStream, OutputStream)
Files#copy(InputStream, Path, CopyOption...) suggested by Holger for jdk 1.7 or above
Try this -
Path source = Paths.get("location1/abc.jar");
Path destination = Paths.get("location2/abc.jar");
try {
Files.copy(source, destination);
} catch(FileAlreadyExistsException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
So, when I write to a file using FileOutputStream, it does change the file's contents, seen as when I read it with an InputStream I get exactly what I wrote. However, when I open the file in the resources directory, it remains the same as before, despite it being changed.
My code:
import java.io.*;
import java.net.URISyntaxException;
import java.net.URL;
public class Program {
public static void main(String[] args) throws URISyntaxException, IOException {
String edit = "Edit2";
String fileName = "/File.txt";
URL url = Object.class.getResource(fileName);
try (FileOutputStream fos = new FileOutputStream(new File(url.toURI()))) {
fos.write(edit.getBytes());
}
try(InputStream is = Object.class.getResourceAsStream(fileName)) {
StringBuilder sb = new StringBuilder();
int read = is.read();
while (read != -1) {
sb.append((char) read);
read = is.read();
}
System.out.println(sb.toString());
}
}
}
By the way, I am using IntelliJ IDEA, and have this file on the resources folder. It's just a .txt file with contents Not changed, so I can know if it was overwritten.
I would want to know whether this problem is related to code or not, and if it is, how can I fix it?
Sounds silly, but try refreshing the folder before opening the file.
Turns out that I shouldn't be using Object.class.getResource(fileName) to open the file from the classpath, but instead directly instantiating a File object.
import java.io.*;
public class Program {
public static void main(String[] args) throws IOException {
String edit = "Edit";
String fileName = "resources/File.txt";
File file = new File(fileName);
try (FileOutputStream fos = new FileOutputStream(file)) {
fos.write(edit.getBytes());
}
try (InputStream is = new FileInputStream(file)) {
StringBuilder sb = new StringBuilder();
int read = is.read();
while (read != -1) {
sb.append((char) read);
read = is.read();
}
System.out.println(sb.toString());
}
}
}
I believed it's related to the path, as CHN pointed out.
I Have 3 objects of Person type and i write them to my file Person.person and than i read them one by one but when i run my program again i get the same 3 objets written as when i run it for the firts time.How to add those 3 objects to my file again and again every time i run my program.I want from it to be the same 3 objects or some other objects but they need to be added to the end of my file.
And how to get that data when i want to read that file?
package pisanjeUFajl;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.List;
public class Serilizacija {
public static void main(String[] args) throws IOException,
ClassNotFoundException {
Person person = new Person("Jovan", "Dukic");
Person person2 = new Person("Stanko", "Maca");
Person person3 = new Person("Tole", "Lopove");
File file = new File("C:\\Users\\Jovan\\Desktop\\Person.person");
if (!(file.exists())) {
file.createNewFile();
}
ObjectOutputStream outputStream = null;
outputStream = new ObjectOutputStream(new BufferedOutputStream(new
FileOutputStream(file)));
outputStream.writeObject(person);
outputStream.reset();
outputStream.writeObject(person2);
outputStream.reset();
outputStream.writeObject(person3);
outputStream.reset();
outputStream.close();
ObjectInputStream inputStream = null;
inputStream = new ObjectInputStream(new BufferedInputStream(new
FileInputStream(file)));
int count = 0;
Person object = null;
I added more objects to my file but when i wanted to read them i got and error:
Exception in thread "main" java.io.StreamCorruptedException:
invalid typecode:AC
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at pisanjeUFajl.Serilizacija.main(Serilizacija.java:46)
It read just the first 3 objects which were added the first to my file.
try {
while (true) {
object = (Person) inputStream.readObject();
count++;
System.out.println(object);
}
} catch (EOFException error) {
System.out.println("\nEnd of file reacher - objects read = " +
count);
}
inputStream.close();
}
}
Use for writing object
ObjectOutputStream outputStream = new ObjectOutputStream(new
FileOutputStream(new File("test")));
Use it for appending object at end of file
ObjectOutputStream outputStream2 = new ObjectOutputStream(new FileOutputStream("test", true)) {
protected void writeStreamHeader() throws IOException {
reset();
}
};
for reading
ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream("test"));
Use the Constructor of FileOutputStream that accepts a boolean as a parameter.
If its set to true, everything written to file through this Stream is appended to the existing content. Constructor looks like this:
FileOutputStream(File file, boolean append)
I have a program that is suppose to read all the files in my folder and combine the files into on file and place them into a new folder. Some of the files are not being pulled in and I do not know why.
The file names are wonder1.txt, wonder2.txt, wonder3.txt, and wonder4.txt and the folder name is Alice, but only a few of the files are actually in the new folder.
import java.io.*;
import java.util.Scanner;
import java.util.*;
import java.lang.*;
import java.io.PrintWriter;
public class alice {
public static void main(String[] args) throws FileNotFoundException, IOException {
File folder = new File("/Users/DAndre/Desktop/Alice");
//Reads in all the files in that folder
for (final File fileEntry : folder.listFiles()) {
String fileName = fileEntry.getAbsolutePath();
BufferedReader br = new BufferedReader(new FileReader(fileName));
try {
StringBuilder stringBuilder = new StringBuilder();
String line = br.readLine();
while (line != null) {
stringBuilder.append(line);
stringBuilder.append("\n");
line = br.readLine();
}
/**
* Pass original file content as string to another method which
* creates new file with same content.
*/
newFile(stringBuilder.toString());
} finally {
br.close();
}
}
}
public static void newFile(String fileContent) {
try {
String newFileLocation = "/Users/DAndre/Desktop/final/final_copy.txt";
PrintWriter writer = new PrintWriter(newFileLocation);
writer.write(fileContent);//Writes original file content into new file
writer.close();
System.out.println("File Created");
} catch (Exception e) {
e.printStackTrace();
}
}
}
The problem with your solution is that you haven't initialize PrintWriter in append mode, because of which the new file gets overwritten with the content of the last file that was written.
public static void newFile(String fileContent) {
try {
String newFileLocation = "C:\\Users\\Shayan\\Desktop\\files2\\final_copy.txt";
PrintWriter writer = new PrintWriter(new FileOutputStream(new File(newFileLocation), true /* append = true */));
writer.write(fileContent);//Writes original file content into new file
writer.close();
System.out.println("File Created");
} catch (Exception e) {
e.printStackTrace();
}
}
The last argument in the constructor of FileOututStream is set to true, indicating that it should be opened in append mode.
You need to change
PrintWriter writer = new PrintWriter(newFileLocation);
to
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(newFileLocation, true)))
Little explanation: append meant to write it additively, on the contrary write overrides the existing file. In your code you are creating a new file including one of your wonders, but on next iteration the file is recreated. So the content of previous wonder is gone.
With the change PrintWriter object is not recreating the file, instead it writes content to a BufferedWriter which also transfers the stream to an append able FileWriter object.
Little suggest: do not create a PrintWriter object on each iteration.
Second little suggest: You don't need PrintWriter. BufferedWriter itself is good enough as far as I see.
I need to read a file from a specified path. E.g: I have a file called abc.txt and it resides inside /dev/user/assets/data/abc.png.
If one has to read from a Zip file we do something like
Zipfile zipFile = new ZipFile("test.zip");
ZipEntry entry = zipFile.getEntry(imagePath); // where image path is /dev/user/assets/data/abc.png.
Is there a code something similar to the above for reading from a folder?
Like
File folder = new Folder("Users");
and give the path "/dev/user/assets/data/abc.png" to the above and read the image.
Yes, File has two-args constructor File(File parent, String child) that does exactly what you describe (you may just have to throw the leading '/' of the child). Take a look at the JavaDoc
I'm not sure if I understand exactly what you want to do. But if what you want to do is simply to read the contents of a file with a given path, then you should'nt use the File API.
Instead you should use a new FileReader(textFilePath); or a new FileInputStream(imageFilePath);
Look at the following example, taken from the java tutorials.
import java.io.FileReader;
import java.io.FileWriter;
import java.io.BufferedReader;
import java.io.PrintWriter;
import java.io.IOException;
public class CopyLines {
public static void main(String[] args) throws IOException {
BufferedReader inputStream = null;
PrintWriter outputStream = null;
try {
inputStream = new BufferedReader(new FileReader("xanadu.txt"));
outputStream = new PrintWriter(new FileWriter("characteroutput.txt"));
String l;
while ((l = inputStream.readLine()) != null) {
outputStream.println(l);
}
} finally {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
}
}
}