views:

363

answers:

2

Okay, so I'm working on a project where I use a Java program to initiate a socket connection between two classes (a FileSender and FileReceiver). My basic idea was that the FileSender would look like this:

  try {
 writer = new DataOutputStream(connect.getOutputStream());
} catch (IOException e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
}

 //While we have bytes to send
 while(filein.available() >0){
 //We write them out to our buffer
writer.write(filein.read(outBuffer));
writer.flush();
 }
 //Then close our filein
 filein.close();
 //And then our socket;
 connect.close();
} catch (IOException e) {
 // TODO Auto-generated catch block
 e.printStackTrace();

The constructor contains code that checks to see if the file exists, and that the socket is connected, and so on. Inside my FileReader is this though:

 input = recvSocket.accept();
 BufferedReader br = new BufferedReader(new InputStreamReader(input.getInputStream()));
 FileOutputStream fOut= new FileOutputStream(filename);
 String line = br.readLine();
 while(line != null){
  fOut.write(line.getBytes());
  fOut.flush();
  line = br.readLine();
 }
 System.out.println("Before RECV close statements");
 fOut.close();
 input.close();
 recvSocket.close();
 System.out.println("After RECV clsoe statements");

All inside a try-catch block. So, what I'm trying to do is have the FileSender reading in the file, converting to bytes, sending and flushing it out. FileReceiver, then reads in the bytes, writes to the fileOut, flushes, and continues waiting for more. I make sure to close all the things that I open, so... here comes the weird part.

When I try and open the created text file in Eclipse, it tells me "An SWT error has occured ... recommended to exit the workbench... see .log for more details.". Another window pops up saying "Unhandled event loop exception, (no more handles)". However, if I try to open the sent text file in notepad2, I get

ThisIsASentTextfile

Which is good (well, minus the fact that there should be line breaks, but I'm working on that...). Does anyone know why this is happening? And while we're checking, how to add the line breaks?

(And is this a particularly bad way to transfer files over java without getting some other libraries?)

Edit: An update: I changed my code to the following (FileReceiver), without changing the sender:

    try {
        input = recvSocket.accept();
        //InputStream br = new InputStream(input.getInputStream());
        FileWriter fOut= new FileWriter(filename);
        //BufferedWriter out = new BufferedWriter(fOut);
        //String line = br.
        byte info = (byte) input.getInputStream().read();
        while((int)info != 0){
            fOut.write(info);
            fOut.flush();
            info = (byte) input.getInputStream().read();
        }
        fOut.flush();
        System.out.println("Before RECV close statements");
        fOut.close();
        //input.close();
        recvSocket.close();
        System.out.println("After RECV clsoe statements");
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

This works. I get a text file that is the right size in bytes (before I was getting 4Kb standard size), and has the right formatting. I'm going to try it on an image next, and keep you updated.

A: 

From a first glance: Why are you using a DataOutputStream ? Totally inadequate for your goal. Just use your provided outputstream:

writer = connect.getOutputStream();

BTW, it's dubious practice to call "writer" that variable, Java makes a clear conceptual difference between readers/writers (char oriented) and streams (byte oriented).

UPDATE: Another bad practice, which calls for trouble: you are mixing readers/writers (char oriented) and streams (byte oriented) unnecessarily - and without a specifyng a charset encoding.

BufferedReader br = new BufferedReader(new InputStreamReader(input.getInputStream()));

You must use a Reader when you are dealing with text (in a know encoding), use a InputStream if your are just dealing with bytes.

leonbloy
Habit. I'm using DOSs in the rest of my program (where they're working fine), so I just used one here as well. *goes to look up the differences... the more you know, right?*
Althane
@Althane, +1 for that italicized bit
Lord Torgamus
So, leonbloy, some clarification that I require. Does that mean that in both classes (the FileSender and the FileReceiver) I should be using the same input/output devices (readers/writers or streams?). Because right now the way I'm working with it, it seems like it would read in a text file's contents, and print it out to the "copy of" file. But I'm not sure how that would change with the streams.Sorry, I'm confused and this is a topic I've never seen before.. so yeah..
Althane
If you want to read the content of the file and "copy" it to other file/place, you generally don't bother if its text or not, just consider it a bunch of bytes - and hence use only streams (but NOT a DataStream - that is for very special use, as serializing java objects)If you want/need to treat them as text (char[], String) you must convert them, by using Reader/Writers (or explicitly converting from bytes[] to String); but then you MUST know the encoding (ISO 8859-1, UTF-8, whatever). Read a bit about this, they are very important concepts for java developers.
leonbloy
Okay, I get the idea (just shipping the bytes from one end to the other, and letting the OS make sense of the bytes we've plunked down into the new file, or am I wrong again?). Thanks for the help, leonbloy.
Althane
Basically, yes - but actually in that scenario nobody (nor Java nor the OS) is "making sense" of the bytes, they are just copied, regardless of their contents.
leonbloy
Ah. Cool. As you may have guessed, I am a student, so I don't really have the experience in java development outside of massive projects like this.One final thing: I've recently sent a .jpg image over this link, and it's come out with all 78.2KB. The only problem is, no image editing software will open it (not even paint!). Any idea why this is caused? I'm figuring damage to the header of the file or something, but I couldn't say.
Althane
Hard to say. Check if original and destination files have exactly the same size.
leonbloy
Exactly the same size. Also, I've tried it with several different text files, and it works fine. Code is as it is up above.. and images don't work. Oh well... wonder if I could disguise an image as a text file, send it, then change it back?
Althane
DataOutputStream is *not 'totally inadequate for your goal'.* It exports all the OutputStream methods, plus more, and it doesn't superimpose a protocol like ObjectOutputStream. It may not be *necessary* but it is certainly not *inadequate.*
EJP
DataOutputStream is at least conceptually inadequate - and many people use in just because of its name, thinking that 'Data' just means 'any data', i.e. any sequencue of bytes.
leonbloy
A: 

Regarding line breaks, BufferedReader.readLine() reads data, terminated by a line feed, but it doesn't return the line feed. So, when you write it back out, you'll want to write a line feed. Alternatively, you can read and write bytes, so you don't end up mistakenly converting line feed characters or corrupting binary files that include the ascii values for line feed or carriage return.

Marcus Adams