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) {}
    }
}
frasertweedale
  • 5,424
  • 3
  • 26
  • 38
Struse
  • 75
  • 3
  • 13

3 Answers3

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);
    }
}
Achintha Gunasekara
  • 1,165
  • 1
  • 15
  • 29
  • 2
    `transferTo()` needs to be called in a loop. It isn't guaranteed to complete the entire transfer in a single operation. – user207421 Nov 09 '15 at 04:04
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();
    
user207421
  • 305,947
  • 44
  • 307
  • 483
  • 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 Nov 09 '15 at 05:10
  • @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 Nov 09 '15 at 18:16
  • @djeikyb I saw them. Sorry i missed the listed inherited method from buffer class right at the bottom. Thank you anyways – Struse Nov 09 '15 at 18:45
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.

Community
  • 1
  • 1
djeikyb
  • 4,470
  • 3
  • 35
  • 42
  • 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. – user207421 Nov 09 '15 at 04:10
  • @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. – djeikyb Nov 09 '15 at 04:15