i am using the following code to write an array to the file:
FileWriter fstream1=new FileWriter("outx.txt");
BufferedWriter out1= new BufferedWriter(fstream1);
FileWriter fstream2=new FileWriter("outy.txt");
BufferedWriter out2= new BufferedWriter(fstream2);
for(int i=0;i<320*240;i++)
{
out1.write(0+System.getProperty("line.separator"));//
// out1.write("\n");
out2.write(0+System.getProperty("line.separator"));
//out2.write("\n");
}
: here in the above code i am putting all zeros
the file should be containing 76800 lines( 0s) but my file is having only 69932 lines.
what is the problem and if you can suggest some other way to do this.
Did you remember to close the output streams? Your example doesn't list the calls to close(), which should flush the streams as well. BufferedWriter's default behavior is to flush (write) its remaining contents before closing the stream it is buffering.
You should probably add:
out1.close();
out2.close();
It is a very common case when the end of a file is being cut off that you forgot to close the writer used to create the file, especially when you have used a BufferedOutputStream or BufferedWriter that may not flush its buffer (write it to the file) until it has been explicitly flushed (or more commonly, closed).
It is a very good habit to get into to immediately write the close() call after opening the stream, and then write all of your code for working with the stream between the calls. Taking exceptions into account, the standard calls use the following idiom:
Writer myOutWriter = null;
try {
myOutWriter = new BufferedWriter(new FileWriter("..."));
// Write to myOutWriter here
} catch (IOException ioe) {
// Handle any exceptions here
} finally {
try {
if (myOutWriter != null) {
myOutWriter.close();
}
} catch (IOException ioe) {
// Not much you can do here
}
}
The Apache Commons IO Project (http://commons.apache.org/io/) has a nice utility called IOUtils.closeQuietly() that cleans up the finally block by including the try catch, null check, and call to close into one method call. An example using that library would look like this:
Writer myOutWriter = null;
try {
myOutWriter = new BufferedWriter(new FileWriter("..."));
// Write to myOutWriter here
} catch (IOException ioe) {
// Handle any exceptions here
} finally {
IOUtils.closeQuietly(myOutWriter);
}
Add:
out1.flush();
out2.flush();
After the for loop.
It is likely that your program is exiting before the buffers in the BufferedReader have been flushed, a common problem with working with buffered output.
Edit: The more correct solution would be:
public static void main(String[] args) throws IOException {
final String outputString = "0" + System.getProperty("line.separator");
BufferedWriter out1 = null;
BufferedWriter out2 = null;
try {
out1 = new BufferedWriter(new FileWriter("outx.txt"));
out2 = new BufferedWriter(new FileWriter("outy.txt"));
for(int i = 0; i < 320 * 240; i++) {
out1.write(outputString);
out2.write(outputString);
}
out1.flush(); // Not really needed as close will flush, but it is
out2.flush(); // useful for describing the intent of the code
} finally {
closeQuietly(out1);
closeQuietly(out2);
}
}
private static void closeQuietly(Closeable c) {
try {
if (c != null) {
c.close();
}
} catch (Exception e) {
// No-op
}
}
As others have pointed out, it is likely that there is unflushed data in your buffers.
An acceptable way to rewrite your code would be like this:
Writer out1 = new FileWriter("outx.txt");
try {
out1 = new BufferedWriter(out1);
Writer out2 = new FileWriter("outy.txt");
try {
out2 = new BufferedWriter(out2);
for (int i = 0; i < 320 * 240; i++) {
out1.write(0 + System.getProperty("line.separator"));
out2.write(0 + System.getProperty("line.separator"));
}
} finally {
out2.close();
}
} finally {
out1.close();
}
This code:
will flush data via close
will always release file handles via close, even if an error occurs (by using finally)
obeys the contract for the Closeable classes
doesn't muck around with null or swallow exceptions
Related
I've had this error in the past but never fully understood it. After closing an OutputStream, regardless of the location of the java file or the manner in which it is called, completely screws up all sequential runs or attempts to write to another file, even if a different method of writing to a file is used. For this reason I avoid closing streams even though it is a horrible habit not to. In my program, I created was trying a test case that had a close statement which destroyed all of my previous streams, making it for some reason that they only write to files after the program has been terminated.
I kept the file location open and it writes the Text in the text file at the appropriate time, however the "Preview" panel in Windows does not detect it (which used to happen). Note that this all worked perfectly before the stream was accidentally closed. Is there a manner to reset the stream? I've tried flushing it during the process but is still does not run as it did prior.
Here is the method used to create the file:
protected void createFile(String fileName, String content) {
try {
String fileLoc = PATH + fileName + ".txt";
File f = new File(fileLoc);
if(!f.isFile())
f.createNewFile();
FileOutputStream outputStream = new FileOutputStream(fileLoc);
byte[] strToBytes = content.getBytes();
outputStream.write(strToBytes);
} catch (IOException e) {
e.printStackTrace();
return;
}
}
as well as the method used to read the file:
protected String readFile(String fileName) {
try {
StringBuilder sb = new StringBuilder("");
String fileLoc = PATH + fileName + ".txt";
File f = new File(fileLoc);
if(!f.exists())
return "null";
Scanner s = new Scanner(f);
int c = 0;
while(s.hasNext()) {
String str = s.nextLine();
sb.append(str);
if(s.hasNext())
sb.append("\n");
}
return sb.toString();
} catch(Exception e) {
e.printStackTrace();
return "null";
}
}
I'd be happy to answer any clarification questions if needed. Thank you for the assistance.
without try-resource, you need close in final clause to make sure no leak. Or use Stream.flush() if you need more 'in-time' update.
} catch (IOException e) {
e.printStackTrace();
return;
} finally {
outputStream.close();
}
You need to call flush() on the stream to write the bytes to the stream.
You're currently calling write() by itself, like this:
FileOutputStream outputStream = new FileOutputStream(fileLoc);
outputStream.write(content.getBytes());
What you want to do is this:
FileOutputStream outputStream = new FileOutputStream(fileLoc);
outputStream.write(content.getBytes());
outputStream.flush();
From the Javadoc (https://docs.oracle.com/javase/8/docs/api/java/io/OutputStream.html#flush--) for OutputStream (where FileOutputStream is an OutputStream), this is what it says for flush():
Flushes this output stream and forces any buffered output bytes to be written out. The general contract of flush is that calling it is an indication that, if any bytes previously written have been buffered by the implementation of the output stream, such bytes should immediately be written to their intended destination.
Even better would be to close the stream in a finally block, so that no matter what your code always tries to free up any open resources, like this:
FileOutputStream outputStream = null;
try {
outputStream = new FileOutputStream(fileLoc);
outputStream.write(content.getBytes());
outputStream.flush();
} finally {
if (outputStream != null) {
outputStream.close();
}
}
or use automatic resource management, like this:
try (FileOutputStream outputStream = new FileOutputStream(fileLoc)) {
outputStream.write(content.getBytes());
outputStream.flush();
}
I have the following code where I'm trying to create two different types of outputstreams. This doesn't seem to work. What would be the correct way to create two outputstreams? Specifically, one dataoutputstream and one objectoutputstream?
connect();
try (DataOutputStream outputStream = new DataOutputStream(socket.getOutputStream())) {
try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream)) {
outputStream.writeUTF("saveFile");
outputStream.writeUTF(serverName);
File fileToSave = new File(localName);
byte[] fileContent = Files.readAllBytes(fileToSave.toPath());
objectOutputStream.writeObject(fileContent);
return true;
}
} catch (IOException e) {
return false;
} finally {
disconnect();
}
After doing some debugging it seems just like the outputstream isn't working. If I only have one of the two, the two "writeUTF" statements will execute.
If I keep both of the outputstreams, the message never reaches the server.
The solution was to move the two "writeUTF" statements above the second try block.
connect();
try (DataOutputStream outputStream = new DataOutputStream(socket.getOutputStream())) {
outputStream.writeUTF("saveFile");
outputStream.writeUTF(serverName);
try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream)) {
File fileToSave = new File(localName);
byte[] fileContent = Files.readAllBytes(fileToSave.toPath());
objectOutputStream.writeObject(fileContent);
return true;
}
} catch (IOException e) {
return false;
} finally {
disconnect();
}
Now the code executes properly.
The problem with your code is that new ObjectOutputStream(...) writes a header to the stream, and evidently your reading code isn't symmetrical with this code, i.e. it does the readUTF() steps before constructing the ObjectInputStream, so the header isn't consumed yet, so the readUTF() steps see it, and barf.
The solution is that you don't need to do this at all. The DataOutputStream is completely pointless here. ObjectOutputStream has all the methods of DatataOutputStream, and more, and similarly for the input streams.
In general this kind of thing is not possible when one or more of the streams is buffered, as ObjectInputStream is.
I'm trying to develop client-server connection between phone and pc using sockets. During the developing i met a problem and cannnot fix it yet. The problem is with outputstream. I use an ObjectoutputStream to send a String array to client and it works when I use this code:
try
{
// отправка пакета с файлами
DataInputStream dir = new DataInputStream(conn.getInputStream());
OutputStream dos = conn.getOutputStream();
ObjectOutputStream objectOutput = new ObjectOutputStream(dos);
byte messageType = dir.readByte();
switch(messageType) {
case 1:
try {
textArea.append("\nClient sends a command: " + dir.readUTF());
objectOutput.writeObject(results);
objectOutput.close();
} catch(Exception e) {
e.printStackTrace();
}
}
dir.close();
} catch (IOException e) {
......
but when I move ObjectOutputStream to the switcher:
try
{
// отправка пакета с файлами
DataInputStream dir = new DataInputStream(conn.getInputStream());
OutputStream dos = conn.getOutputStream();
byte messageType = dir.readByte();
switch(messageType) {
case 1:
try {
ObjectOutputStream objectOutput = new ObjectOutputStream(dos);
textArea.append("\nClient sends a command: " + dir.readUTF());
objectOutput.writeObject(results);
objectOutput.close();
} catch(Exception e) {
e.printStackTrace();
}
}
dir.close();
} catch (IOException e) {
....
my program freezes. I need to do like this, because i also need to do another commands, like sending and receiving files. Any solutions for this problem?
I've solved a problem. I just use BufferedReader & Writer for it, because it will be also used for transferring files.
So now code works fine and looks like this:
// отправка пакета с файлами
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream(), ENCODING));
String messageType = br.readLine();
switch(messageType) {
case "connect": {
List<String> results = new ArrayList<String>();
File[] files = new File("C:/Tenzor_Denis/ServerFiles/").listFiles();
//If this pathname does not denote a directory, then listFiles() returns null.
for (File file : files) {
if (file.toString().endsWith(".txt")) {
results.add(file.getName());
}
}
try {
for(int i = 0; i < results.size(); i++) {
bw.write(results.get(i));
bw.newLine();
//textArea.append(" " + results.get(i));
}
textArea.append("\nClient sends a command: " + messageType);
} catch(Exception e) {
e.printStackTrace();
}
bw.close();
br.close();
}
break;
}
}
Thx to all for answers.
Which line does it freeze on? It seems like reading from the input stream causes the output stream to block until everything is consumed. Look at the documentation for your conn object. What class is this? Perhaps moving the dir.readUTF() call before creating the ObjectOutputStream might solve it.
You can't do it either way. Closing the ObjectOutputStream will close the socket. You need to keep it open for the life of the socket. So moving it inside the case is futile anyway.
But your code doesn't make sense. You're writing with ObjectOutputStream, yet all you're reading from the peer is a single byte. If you're writing objects, you need to read objects, with an ObjectInputStream, not a DataInputStream, and when using both object input and output streams you must always construct the ObjectOutputStream first, at both ends to be safe.
I want to write a file but mixture of 3 bellow feature. how?
BufferedWriter , high volume data write needed
can append to exist text file
can set charset like "cp1256"
How mix all these features to open write file?
What you would do first is, Initiate your BufferedWriter :
`
String fileName = METHOD ARGUMENT, OR REGULAR STRING ("Output.txt");
BufferedWriter writer = null;
try {
File outFile = new File(fileName);
writer = new BufferedWriter(new FileWriter(OUTPUT NAME OF THE FILE YOU ARE WRITING. , true));
writer.write(WHAT YOU WANT TO WRITE TO THE FILE);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
// Close the writer regardless of what happens...
writer.close();
} catch (Exception e) {
}
Now to explain the code so I'm not just spoon feeding it to you.
When we declare the BufferedWriter writer = null; , we are setting it to null so that we don't write anything without setting a Try/Catch Exception Handler around it.
Once we are within our exception handled, we initiate a File called outFile. This will be the file we are outputting. The Argument we give it is the name of the file name. (A String Value such as, "Output.txt") NOTE: You MUST add the extension or else it won't work the way you are hoping it does.
Next, when we reference our BufferedWriter again, we initiate a new one in the try/catch handler, and inside we initiate a FileWriter (What will be doing the writing to the file). We give it two arguments. The name of the Output File("Output.txt"), and we also supply a true argument. What this does is makes the File Appendable! When we write true, we are saying we want the file to be appendable.
Finally, we write to the file, whatever it is you want to write.
As for the third feature, I don't think that FileWriter's will allow you to choose the Character Encoding that you want to write with, so unless you aren't using UTF-8, then you may want to use a PrintWriter
To do this, you would simply replace our `writer = new BufferedWriter(new FileWriter(OUTPUT NAME OF THE FILE YOU ARE WRITING. , true));
writer = new BufferedWriter(new PrintWriter(outputName, "UTF-8"));
I THINK this should work, if not, please let me know, I'll find a working solution.
public class WriteFile {
BufferedWriter out;
public void openFile(String file){
try {
out = new BufferedWriter(new FileWriter("data.txt"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void writeInts(int[] ints){
try {
for(int i : ints) out.write(i+" ");
out.newLine();
out.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void closeFile(){
try {
if (out!=null)out.close();
} catch (IOException e) {
}
}
}
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class Test {
public static void main(String[] args) throws IOException {
WriteFile wf = new WriteFile();
wf.openFile("test.txt");
wf.writeInts(new int[]{1,2,3,4,5});
wf.writeInts(new int[]{5,4,3,2,1});
wf.closeFile();
BufferedReader bf = new BufferedReader(new FileReader("test.txt"));
System.out.println(bf.readLine());
System.out.println(bf.readLine());
}
}
Output:
Line1: 1 2 3 4 5
Line2: 5 4 3 2 1
I am reading a file in.txt and writing the numbers to a file out.txt until 42 is found.But in out.txt I am getting blank file.Instead if I write System.out.println(num) instead of out.write(num) I get correct result.It means that the problem is with the statement of BufferedReader.Where I am wrong?
import java.io.*;
class Numbers
{
public static void main(String args[])
{
try{
String num;
BufferedReader in=new BufferedReader(new FileReader("in.txt"));
BufferedWriter out=new BufferedWriter(new FileWriter("out.txt"));
while((num=in.readLine())!=null)
{
if(Integer.parseInt(num)==42)
break;
else
out.write(num);
}
}catch(Exception e)
{
System.out.println("File not found");
}
}
}
The problem is the you are not closing the out stream. Change it to:
BufferedReader in = null;
BufferedReader out = null;
try{
String num;
in = new BufferedReader(new FileReader("in.txt"));
out = new BufferedWriter(new FileWriter("out.txt"));
while((num=in.readLine())!=null)
{
if(Integer.parseInt(num)==42)
break;
else
out.write(num);
}
out.close()
}catch(Exception e)
{
System.out.println("File not found");
}finally{
try{
if(in!=null) in.close();
if(out!=null) out.close();
}catch(Exception ex) {ex.printStackTrace();}
}
This is because, your OutputStream buffers your data and periodically flushes it. Closing the stream not only flushes it but also makes it safe for other applications to use the file.
In your case you might expect a weird behavior (with sometimes complete write and sometimes not). This is due to the fact that BufferedWriter() tries closing it in its finalize method (which may or may not be called)
You need to close your FileWriter:
while((num=in.readLine())!=null)
{
if(Integer.parseInt(num)==42)
break;
else{
out.write(num);
out.flush();
}
}
out.close();
Contents always need to be flushed. close() by itself will flush the stream for you, but it's good practice to flush() anyway.
You should close the stream after stop using it. Closing it will, firstly, flush the stream (all buffered data will be printed) and secondly, will release all resources the stream is using.
make sure you have out.close() at the end of try block.
if you have in.txt as a very big file, then you will see some data in out.txt.
BufferedWriter writes only when it has enough data to flush, which is approximately equal to one block size.