FileOutputStream is reducing the file size to 0 - java

I have created a file using RandomAccessFile with preallocated size. But when I am using FileOutputStream to write into the same it is changing the size of the file. Is there any way to stop this using FileOutputStream
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.RandomAccessFile;
import java.io.Serializable;
public class testFileSize {
public static class Status implements Serializable {
}
public static void preAllocate(String path, long maxSize, boolean preAllocate)
throws IOException {
RandomAccessFile raf = new RandomAccessFile(path, "rw");
try {
raf.setLength(maxSize);
} finally {
raf.close();
}
}
/**
* #param args
* #throws IOException
*/
public static void main(String[] args) throws IOException {
FileOutputStream fileOutput = null;
ObjectOutputStream objectOutput = null;
try {
final File f = new File("/tmp/test.bin");
preBlow(f.getAbsolutePath(), 2048, false);
Status s = new Status();
fileOutput = new FileOutputStream(f);
objectOutput = new ObjectOutputStream(fileOutput);
objectOutput.writeObject(new Status());
objectOutput.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
objectOutput.close();
fileOutput.close();
}
}
}

Looks like your file is changing size because you're opening the file on create mode, so the previous contents are lost
fileOutput = new FileOutputStream(f);
Try opening your file in append mode, using an extra boolean flag while constructing your FileOutputStream
fileOutput = new FileOutputStream(f, true);

Related

Java - Writing Object in res folder will instead of writing it in bin

Im having problems writing/reading object as resources on file.
I run code from the Main.java Class, and I want to write/read an object to the users.txt file.
The object that I want to write/read is the TryStructure Object, which just incapsulates a 1 element array and implements the Serializable interface, needed for object writing.
package Main;
import java.io.Serializable;
import java.util.ArrayList;
public class TryStructure implements Serializable
{
private static final long serialVersionUID = 1L;
private ArrayList<Integer> a = new ArrayList<Integer>();
public TryStructure()
{
a.add(5);
}
public String getStructure()
{
return a.toString();
}
}
The Main.java class writes and reads the obj from the users.txt file.
package Main;
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.net.URISyntaxException;
import java.net.URL;
public class Main
{
public static void main(String[] args)
{
String res = "/res/users.txt";
write(res);
read(res);
}
private static void write(String resName)
{
TryStructure list = new TryStructure();
FileOutputStream fos;
ObjectOutputStream oos;
URL resource = Main.class.getClass().getResource(resName);
File file = null;
try
{
file = new File(resource.toURI());
fos = new FileOutputStream(file);
oos = new ObjectOutputStream(fos);
System.out.println("WRITING: " + list.getStructure());
oos.writeObject(list);
oos.close();
fos.close();
}
catch (IOException e)
{
System.err.println("users.txt not found !");
}
catch (URISyntaxException e)
{
e.printStackTrace();
}
}
private static void read(String resName)
{
FileInputStream fos;
ObjectInputStream oos;
URL resource = Main.class.getClass().getResource(resName);
File file = null;
try
{
file = new File(resource.toURI());
fos = new FileInputStream(file);
oos = new ObjectInputStream(fos);
System.out.println("READING: " + ((TryStructure) oos.readObject()).getStructure());
oos.close();
fos.close();
}
catch (IOException e)
{
System.err.println("users.txt not found !");
}
catch (ClassNotFoundException e)
{
System.out.println("AA");
}
catch (URISyntaxException e)
{
e.printStackTrace();
}
}
}
If I run the code I get the following output:
WRITING: [5]
READING: [5]
If I then check the user.txt file I find it empty, and I find the information in bin/res/user.txt.
I dont understand why it only updates the file in bin folder and not also the one in res folder, why is this happening? I would like to write to that specific file.
Thank you.

about closing BufferedOutputStream

I'm trying to develop a simple Java file transfer application using TCP.
My current server code is as follows:
package tcp.ftp;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class FTPServer {
public static void main(String[] args) {
new FTPServer().go();
}
void go() {
try {
ServerSocket server = new ServerSocket(2015);
System.out.println("server is running ....!");
while (true) {
Socket socket = server.accept();
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String file = reader.readLine();
System.out.println("file to be downloaded is : " + file);
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
while (true) {
int octet = bis.read();
if (octet == -1) {
break;
}
bos.write(octet);
}
bos.flush();
//bos.close();
}
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
}
}
Using my current server code above, the downlloding does not work as expected. the above code sends part of the file to the client , not the entire file. Note that I used the flush method to flush the buffer. but when I replace the flush () method by the close () method, the file is fully sent to the client whithout any loss. Could anyone please explain this behavior!
UPDATE: Here is the code of my client:
package tcp.ftp;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
/**
*
* #author aaa
*/
public class FTPClient {
public static void main(String[] args) {
String file = "JasperReports-Ultimate-Guide-3.pdf";
try {
InetAddress address = InetAddress.getLocalHost();
Socket socket = new Socket(address, 2015);
System.out.println("connection successfully established ....!");
PrintWriter pw = new PrintWriter(socket.getOutputStream());
pw.println(file);
pw.flush();
BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("copy" + file));
while (true) {
int octet = bis.read();
if (octet == -1) {
break;
}
bos.write(octet);
}
bos.flush();
System.out.println("file download is complete ...!");
} catch (UnknownHostException ex) {
System.out.println(ex.getMessage());
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
}
}
Another behavior without the use of Socket. take the following code that copy a file from a source to a destination:
public class CopieFile {
static void fastCopy(String source, String destination) {
try {
FileInputStream fis = new FileInputStream(source);
BufferedInputStream bis = new BufferedInputStream(fis);
FileOutputStream fos = new FileOutputStream(destination);
BufferedOutputStream bos = new BufferedOutputStream(fos);
while (true) {
int octet = bis.read();
if (octet == -1) {
break;
}
bos.write(octet);
}
bos.flush();
} catch (FileNotFoundException ex) {
System.out.println(ex.getMessage());
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
}
public static void main(String[] args) throws IOException {
String source = "...";
String destination = "...";
fastCopy(source, destination);
}// end main
}// end class
the above code to copy a file from one location to another without any loss. Note well that I did not close the stream.
If you never close the stream the client wil never get end of stream so it will never exit the read loop.
In any case the stream and the socket are about to go out of scope, so if you don't close them you have a resource leak.

Why BufferedOutputStream doesn't output data?

I try to create my own class to output system out stream to console and to the file at the same time using BufferedStream. But data doesn't appear from the BufferedOutputStream. How should I fix this problem?
package com.library.stream;
import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class DoubleEndedStream {
InputStream theInput;
OutputStream theOutput;
public static void main(String[] args) throws IOException, FileNotFoundException {
DoubleEndedStream sr = new DoubleEndedStream(System.in, System.out);
sr.doublingTheStream();
}
public DoubleEndedStream(InputStream in, OutputStream out) {
theInput = in;
theOutput = out;
}
public void doublingTheStream() throws IOException, FileNotFoundException {
try {
FileOutputStream fos = new FileOutputStream("C:\\log.txt");
BufferedOutputStream bout1 = new BufferedOutputStream(fos);
BufferedOutputStream bout2 = new BufferedOutputStream(theOutput);
try {
while (true) {
int datum = theInput.read();
if (datum == -1) break;
bout1.write(datum);
bout2.write(datum);
}
bout1.flush();
bout2.flush();
} catch (IOException e) {
System.err.println("Couldn't read from System.in!");
}
bout1.close();
bout2.close();
fos.close();
} catch (FileNotFoundException e) {
System.err.println("Couldn't find log.txt");
}
}
}
Since theInput is System.in, as long as you don't close it, (ctrl-d in unix), it will not return -1, but hang and wait for input. Since you perform flush() only when received -1, you never get to this point. Try flushing after the write() instead.

Reading video data and writing to another file java

I am reading a video file data in bytes and sending to another file but the received video file is not playing properly and is chattered.
Can anyone explain me why this is happening and a solution is appreciated.
My code is as follows
import java.io.*;
public class convert {
public static void main(String[] args) {
//create file object
File file = new File("B:/music/Billa.mp4");
try
{
//create FileInputStream object
FileInputStream fin = new FileInputStream(file);
byte fileContent[] = new byte[(int)file.length()];
fin.read(fileContent);
//create string from byte array
String strFileContent = new String(fileContent);
System.out.println("File content : ");
System.out.println(strFileContent);
File dest=new File("B://music//a.mp4");
BufferedWriter bw=new BufferedWriter(new FileWriter(dest));
bw.write(strFileContent+"\n");
bw.flush();
}
catch(FileNotFoundException e)
{
System.out.println("File not found" + e);
}
catch(IOException ioe)
{
System.out.println("Exception while reading the file " + ioe);
}
}
}
This question might be dead but someone might find this useful.
You can't handle video as string. This is the correct way to read and write (copy) any file using Java 7 or higher.
Please note that size of buffer is processor-dependent and usually should be a power of 2. See this answer for more details.
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class FileCopy {
public static void main(String args[]) {
final int BUFFERSIZE = 4 * 1024;
String sourceFilePath = "D:\\MyFolder\\MyVideo.avi";
String outputFilePath = "D:\\OtherFolder\\MyVideo.avi";
try(
FileInputStream fin = new FileInputStream(new File(sourceFilePath));
FileOutputStream fout = new FileOutputStream(new File(outputFilePath));
){
byte[] buffer = new byte[BUFFERSIZE];
while(fin.available() != 0) {
bytesRead = fin.read(buffer);
fout.write(buffer, 0, bytesRead);
}
}
catch(Exception e) {
System.out.println("Something went wrong! Reason: " + e.getMessage());
}
}
}
Hope this also helpful for you - This can read and write a file into another file (You can use any file type to do that)
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class Copy {
public static void main(String[] args) throws Exception {
FileInputStream input = new FileInputStream("input.mp4"); //input file
byte[] data = input.readAllBytes();
FileOutputStream output = new FileOutputStream("output.mp4"); //output file
output.write(data);
output.close();
}
}
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import javax.imageio.ImageIO;
public class Reader {
public Reader() throws Exception{
File file = new File("C:/Users/Digilog/Downloads/Test.mp4");
FileInputStream fin = new FileInputStream(file);
byte b[] = new byte[(int)file.length()];
fin.read(b);
File nf = new File("D:/K.mp4");
FileOutputStream fw = new FileOutputStream(nf);
fw.write(b);
fw.flush();
fw.close();
}
}
In addition to Jakub Orsula's answer, one needs to check the result of read operation to prevent garbage being written to end of file in last iteration.
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class FileCopy {
public static void main(String args[]) {
final int BUFFERSIZE = 4 * 1024;
String sourceFilePath = "D:\\MyFolder\\MyVideo.avi";
String outputFilePath = "D:\\OtherFolder\\MyVideo.avi";
try(
FileInputStream fin = new FileInputStream(new File(sourceFilePath));
FileOutputStream fout = new FileOutputStream(new File(outputFilePath));
){
byte[] buffer = new byte[BUFFERSIZE];
int bytesRead;
while(fin.available() != 0) {
bytesRead = fin.read(buffer);
fout.write(buffer, 0, bytesRead);
}
}
catch(Exception e) {
System.out.println("Something went wrong! Reason: " + e.getMessage());
}
}
}

java: keep tracking of file size on the run?

I wrote a code that writes compressed objects into a file, My questions is: is there a way that I could keep track of the increment of size of my file as the object being wrote in? here is my code:
public static void storeCompressedObjs(File outFile, ArrayList<Object[]> obj) {
FileOutputStream fos = null;
GZIPOutputStream gz = null;
ObjectOutputStream oos = null;
try {
fos = new FileOutputStream(outFile);
gz = new GZIPOutputStream(fos);
oos = new ObjectOutputStream(gz);
for (Object str : obj) {
oos.writeObject(str);
oos.flush();
//I was hoping to print outFile.length() here, but it doesn't work
}
} catch (IOException e) {
e.printStackTrace();
} finally {
oos.close();
gz.close();
fos.close();
}
}
I tried to use flush after every oos.writeObject(str); and then get the file size by using outFile.length(), but no matter how much I flush it, the file size remain unchanged until the last jump to its final size. Anyway that I could fix it? Thanks
The Apache Commons project provides a class CountingOutputStream, which you can put into your chain of OutputStreams. You can even have two of them:
package so5997784;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.util.zip.GZIPOutputStream;
import org.apache.commons.io.output.CountingOutputStream;
public class CountBytes {
private static void dump(File outFile, Object... objs) throws IOException {
FileOutputStream fos = new FileOutputStream(outFile);
try {
CountingOutputStream compressedCounter = new CountingOutputStream(fos);
OutputStream gz = new GZIPOutputStream(compressedCounter);
CountingOutputStream uncompressedCounter = new CountingOutputStream(gz);
ObjectOutputStream oos = new ObjectOutputStream(uncompressedCounter);
for (Object obj : objs) {
oos.writeObject(obj);
oos.flush();
System.out.println(uncompressedCounter.getByteCount() + " -> " + compressedCounter.getByteCount());
}
oos.close();
System.out.println(uncompressedCounter.getByteCount() + " -> " + compressedCounter.getByteCount());
} finally {
fos.close();
}
}
public static void main(String[] args) throws IOException {
File outFile = new File("objects.out.gz");
dump(outFile, "a", "b", "cde", "hello", "world");
}
}

Categories