0

I am new to file handling. I tried reading a file using fileinputstream and file channel. I could not find out the bug in the following code. It runs successfully but file has not been transferred. New file is created with zero bytes. Please have a look at the code and check what went wrong

public class FileTest
{
    public static void main(String[] args)
    {   
        try {
            File file = new File("sss.jpg");
            FileChannel inChannel=new FileInputStream(file).getChannel();
            //FileChannel inChannel = in.getChannel();
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            while(inChannel.read(buffer) > 0) {
                FileChannel outChannel=new FileOutputStream("sss1.jpg",true).getChannel();
                outChannel.write(buffer);
            }
        }
        catch(IOException ex) {}
    }
}

3 Answers 3

1

I'd do something like this,

import java.io.IOException;
import java.nio.channels.FileChannel;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

public class Test_Stuff {

    public static void main(String[] args) throws FileNotFoundException, IOException {

        String thisFile = "Test.java";
        FileInputStream source = new FileInputStream(thisFile);
        FileOutputStream destination = new FileOutputStream("Output.java");
        FileChannel sourceFileChannel = source.getChannel();
        FileChannel destinationFileChannel = destination.getChannel();
        long size = sourceFileChannel.size();
        sourceFileChannel.transferTo(0, size, destinationFileChannel);
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

transferTo() needs to be called in a loop. It isn't guaranteed to complete the entire transfer in a single operation.
1
while(inChannel.read(buffer) > 0) {
    FileChannel outChannel=new FileOutputStream("sss1.jpg",true).getChannel();
    outChannel.write(buffer);
}
  1. You're creating a new file each time around the loop. OK you're appending but this is not efficient, and you're never closing it.
  2. You forgot to flip and compact the buffer.

    FileChannel outChannel = new FileOutputStream("sss1.jpg").getChannel();
    while(inChannel.read(buffer) > 0) {
        buffer.flip();
        outChannel.write(buffer);
        buffer.compact();
    }
    outChannel.close();
    inChannel.close();
    

3 Comments

Thank you. The buffer is bytebuffer but flip is the method of class buffer. Does it go well with bytebuffer class?. Is it even possible? can u explain?
@Struse look at the javadoc and/or the source code. there's a relationship between ByteBuffer and Buffer. look at the class signatures first.
@djeikyb I saw them. Sorry i missed the listed inherited method from buffer class right at the bottom. Thank you anyways
0

You should absolutely follow EJP's or Achintha Gunasekara's answer. You are doing multiple things poorly (eg, creating many output channels, not using FileChannel::open, etc). But I believe the essential problem is not calling flip. From the javadoc:

Flips this buffer. The limit is set to the current position and then the position is set to zero. If the mark is defined then it is discarded. After a sequence of channel-read or put operations, invoke this method to prepare for a sequence of channel-write or relative get operations. For example:

 buf.put(magic);    // Prepend header
 in.read(buf);      // Read data into rest of buffer
 buf.flip();        // Flip buffer
 out.write(buf);    // Write header + data to channel

This method is often used in conjunction with the compact method when transferring data from one place to another.

2 Comments

Nothing wrong with checking via > 0 in blocking mode: read() can't return zero unless there is no space in the buffer, which would be a programming error you wouldn't want to spin-loop on. Using the Files object isn't compulsory.
@EJP that's a fair point, hadn't thought of it, thanks. i wasn't thinking of it as an error, per se, more just that the javadoc says -1 signals end of stream, so should use that. but now i'll use > 0 with your comment in mind.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.