FTP File Transfer; file contents getting changed ?

S

Sriram

Hi,
I have wriiten a program to transfer a binary file.

After transfer. The file contents in the destination machine is getting
changed.

Please Help.


Please advice if i am doing any wrong. The number of bytes getting transfered
is correct. only some of the bytes in the file (in the destination machine)
are different.

I dont know why is this happening.


I have appened code segment.

{

Socket ds = new Socket(serverName, dataPort);

if ( f.sendCommand("type I" + f.eol, true) ) {
System.out.println("Main: bi");
System.out.println("bi results: " + f.cmdResponse );
String filePath="C:\\sri.bin";
int line = 0;

File f = new File(filePath);
FileInputStream srcFile = new FileInputStream(f);
BufferedInputStream bufFile = new BufferedInputStream(srcFile);
DataInputStream inData = new DataInputStream(bufFile);

OUT = new PrintWriter( ds.getOutputStream(), true );
OUT.write("TYPE I"); /* setting transfer mode = BINARY */
while ((line=inData.read()) != -1 ){
OUT.write(line);
}
OUT.flush();
OUT.close() ;

}

Regards,
Ram
 
T

Tor Iver Wilhelmsen

OUT = new PrintWriter( ds.getOutputStream(), true );

This creates a character-oriented Writer, not a binary OutputStream.
OUT.write("TYPE I"); /* setting transfer mode = BINARY */

No, it doesn't. It just puts these 16-bit characters in the beginning
of the file. Writing to a file is not the same as doing FTP.
while ((line=inData.read()) != -1 ){
OUT.write(line);

It's INCREDIBLY wasteful to read bytes one by one. Use a byte[] and
the associated read/write methods.
 
C

Chris Uppal

Tor said:
while ((line=inData.read()) != -1 ){
OUT.write(line);

It's INCREDIBLY wasteful to read bytes one by one. Use a byte[] and
the associated read/write methods.

Umm... it's not, you know. It is a /little/ wasteful, but not hugely so, and
not enough to worry about in many situations. The key is that the original
code is using a buffered reader.

The write(), now, /is/ "INCREDIBLY wasteful", since there doesn't seem to be a
buffered writer in use, but I assume that's just an oversight.

-- chris
 
S

steve

Tor said:
while ((line=inData.read()) != -1 ){
OUT.write(line);

It's INCREDIBLY wasteful to read bytes one by one. Use a byte[] and
the associated read/write methods.

Umm... it's not, you know. It is a /little/ wasteful, but not hugely so, and
not enough to worry about in many situations. The key is that the original
code is using a buffered reader.

The write(), now, /is/ "INCREDIBLY wasteful", since there doesn't seem to be a
buffered writer in use, but I assume that's just an oversight.

-- chris
er it is Very wasteful

as much as 30 seconds difference for the following.

try
static final int MAXBUFSIZE = 1;
or
static final int MAXBUFSIZE = 4095;
or
static final int MAXBUFSIZE = 32767;

for the following.

FileDescriptor fd = null;

if (blob != null) {
file =
new FileOutputStream(outputPath + File.separator +
my_vars.TempExtension + filename);
fd = file.getFD();

bis = new BufferedInputStream(blob.getBinaryStream());

while ((n = bis.read(buf, 0, MAXBUFSIZE)) != -1) {
file.write(buf, 0, n);
}

goodLoad = true; // flag to state the above routine
finished correctly.
}



setup a timer and take a look.
 
C

Chris Uppal

steve said:
It's INCREDIBLY wasteful to read bytes one by one. Use a byte[] and
the associated read/write methods.

Umm... it's not, you know. It is a /little/ wasteful, but not hugely
so, and not enough to worry about in many situations. The key is that
the original code is using a buffered reader.
[...]
er it is Very wasteful

as much as 30 seconds difference for the following.

You surprise me immensely. This is not what my previous tests have indicated
(yes, I have measured it before ;-), nor is it what logic would indicate.

The principle drags on IO are the size of the block written to or read from the
/real/ output device (raw disk, network, whatever) (which will be subject to
buffering in the OS, anyway) and the number of context switches into the kernel
(or whatever) to push the data through the OS. Both of these drags should be
minimised by buffering, whether it is implemented by a buffering wrapper or
explicitly in client code.

What's left is the copying overhead, and the shear number of method calls
(plus, I suspect, read() and write() may be creating a temporary 1 byte array
on each call). But that should be trivial compared with the above drags.

There may be effects to do with the memory mapping based implementation of file
IO. If so then it'll show up in a qualitative difference in the performance of
the standard buffer classes between file IO and network IO.

Obviously I should (re)run some tests, but I'm not in the mood for hacking Java
on a Sunday afternoon. I'll investigate further and report back later...

-- chris
 
C

Chris Uppal

I said:
It's INCREDIBLY wasteful to read bytes one by one. Use a byte[] and
the associated read/write methods.

Umm... it's not, you know. It is a /little/ wasteful, but not hugely
so, and not enough to worry about in many situations. The key is that
the original code is using a buffered reader.
[...]
er it is Very wasteful

as much as 30 seconds difference for the following.

You surprise me immensely. This is not what my previous tests have
indicated (yes, I have measured it before ;-), nor is it what logic would
indicate. [...]
Obviously I should (re)run some tests, but I'm not in the mood for
hacking Java on a Sunday afternoon. I'll investigate further and report
back later...

OK, it's later now, so here I am again.

Testing reading and writing to file or to the LAN. The test involves reading
or writing 1GB either bytewise, or using a 1K, 8K, or 64K buffer.
Incidentally the size of the test is very important for file read/writes
otherwise OS buffering will invalidate the test. The test machine has 512Mb
RAM, of which most is free during the test, but the 1Gb is large enough that
just about all the data will have to be read/written in each case, and the
machine's OS caches are only (and legitimately) being used for
read-ahead/write-behind.

My test is running on a WinXP Pro laptop, using Sun's 1.4.2 JVM.

The network tests connect to a server that either reads or writes data as fast
as it can. In my test the server was running Sun's 1.4.1 on Win2K -- not that
it matters much, the only important thing is that the server machine can both
produce and consume data faster than the test machine can.

I'll add the code for the test and server process at the end of this post.

Here are the results. The last columns is the time in seconds, the numbers in
[square brackets] are the size of the array used for the read(byte[]) or
write(byte[]) calls.

File write bytewise: 1073741824 bytes: 86.464
File write[1024]: 1073741824 bytes: 92.713
File write[8192]: 1073741824 bytes: 81.377
File write[65536]: 1073741824 bytes: 73.215

Network write bytewise: 1073741824 bytes: 118.88
Network write[1024]: 1073741824 bytes: 94.015
Network write[8192]: 1073741824 bytes: 91.812
Network write[65536]: 1073741824 bytes: 91.151

File read bytewise: 1073741824 bytes: 45.385
File read[1024]: 1073741824 bytes: 45.105
File read[8192]: 1073741824 bytes: 45.135
File read[65536]: 1073741824 bytes: 45.065

Network read bytewise: 1073741824 bytes: 94.766
Network read[1024]: 1073741824 bytes: 90.861
Network read[8192]: 1073741824 bytes: 90.84
Network read[65536]: 1073741824 bytes: 90.791

In general the use of bytewise IO is costing very little -- at least not on my
system. Still, I'd expect similar results on other systems.

Note that these tests don't actually do anything with the data they read, or
take time creating the data to write. So in the real world most applications
more complicated than a simple file-copy would expect to see relatively less
benefit from using the array forms.

Another note is that both the array and the bytewise tests are using a buffered
stream. That may be putting the array forms at a slight disadvantage compared
to a raw stream (since there's more complex code path, to no real advantage).
I expect that effect to be pretty small, but admit I haven't measured it.

-- chris

Rather manky code follows. Main takes the number of Mbytes to read/write as
its single agument. Server takes no arguments at all.

============= Main.java ============
import java.io.*;
import java.net.Socket;

public class Main
{
private static byte[] buffer1 = new byte[1024 * 1];
private static byte[] buffer8 = new byte[1024 * 8];
private static byte[] buffer64 = new byte[1024 * 64];

private static final String FILENAME = "C:/temp/crud.dat";
private static final String SERVER = "**THE OTHER MACHINE**";

public static void
main(String args[])
throws NumberFormatException
{
int todo = args.length > 0
? Integer.parseInt(args[0])
: 1; // deliberately tiny for testing
todo *= 1024 * 1024; // but not /that/ tiny...

initialiseBuffers();

timeWritesToFile(todo);
timeWritesToNetwork(todo);
timeReadsFromFile(todo);
timeReadsFromNetwork(todo);
}

private static void
initialiseBuffers()
{
initialiseBuffer(buffer1);
initialiseBuffer(buffer8);
initialiseBuffer(buffer64);
}

private static void
initialiseBuffer(byte[] buffer)
{
for (int i = 0; i < buffer.length; i++)
buffer = (byte)(i-128);
}

private static void
timeWritesToFile(int todo)
{
timeWriteToFile(todo);
timeWriteToFile(todo, buffer1);
timeWriteToFile(todo, buffer8);
timeWriteToFile(todo, buffer64);
}

private static void
timeWritesToNetwork(int todo)
{
timeWriteToNetwork(todo);
timeWriteToNetwork(todo, buffer1);
timeWriteToNetwork(todo, buffer8);
timeWriteToNetwork(todo, buffer64);
}

private static void
timeWriteToFile(int todo)
{
try
{
OutputStream stream = openFileOutputStream();
timeWriteStream("File", stream, todo);
stream.close();
}
catch (Exception e)
{
reportError(e, "timeWriteToFile(" + todo + ")");
}
}

private static void
timeWriteToFile(int todo, byte[] buffer)
{
try
{
OutputStream stream = openFileOutputStream();
timeWriteStream("File", stream, todo, buffer);
stream.close();
}
catch (Exception e)
{
reportError(e, "timeWriteToFile(" + todo + ", " + buffer.length + ")");;
}
}

private static void
timeWriteToNetwork(int todo)
{
try
{
OutputStream stream = openNetworkOutputStream();
timeWriteStream("Network", stream, todo);
stream.close();
}
catch (Exception e)
{
reportError(e, "timeWriteToNetwork(" + todo + ")");;
}
}

private static void
timeWriteToNetwork(int todo, byte[] buffer)
{
try
{
OutputStream stream = openNetworkOutputStream();
timeWriteStream("Network", stream, todo, buffer);
stream.close();
}
catch (Exception e)
{
reportError(e, "timeWriteToNetwork(" + todo + ", " + buffer.length + ")");;
}
}

private static void
timeWriteStream(String name, OutputStream stream, int todo)
throws IOException
{
int done = 0;
long start = now();
while (done < todo)
{
stream.write((byte)(done-128));
done++;
}
stream.flush();
reportTime("write bytewise", done, name, now()-start);
}

private static void
timeWriteStream(String name, OutputStream stream, int todo, byte[] buffer)
throws IOException
{
int done = 0;
long start = now();
while (done < todo)
{
int write = Math.min(todo-done, buffer.length);
stream.write(buffer, 0, write);
done += write;
}
stream.flush();
reportTime("write[" + buffer.length + "]", done, name, now()-start);
}


private static void
timeReadsFromFile(int todo)
{
timeReadFromFile(todo);
timeReadFromFile(todo, buffer1);
timeReadFromFile(todo, buffer8);
timeReadFromFile(todo, buffer64);
}

private static void
timeReadsFromNetwork(int todo)
{
timeReadFromNetwork(todo);
timeReadFromNetwork(todo, buffer1);
timeReadFromNetwork(todo, buffer8);
timeReadFromNetwork(todo, buffer64);
}

private static void
timeReadFromFile(int todo)
{
try
{
InputStream stream = openFileInputStream();
timeReadStream("File", stream, todo);
stream.close();
}
catch (Exception e)
{
System.out.println("Did not test timeReadFromFile(" + todo + ")");;
}
}

private static void
timeReadFromFile(int todo, byte[] buffer)
{
try
{
InputStream stream = openFileInputStream();
timeReadStream("File", stream, todo, buffer);
stream.close();
}
catch (Exception e)
{
reportError(e, "timeReadFromFile(" + todo + ", " + buffer.length + ")");;
}
}

private static void
timeReadFromNetwork(int todo)
{
try
{
InputStream stream = openNetworkInputStream();
timeReadStream("Network", stream, todo);
stream.close();
}
catch (Exception e)
{
reportError(e, "timeReadFromNetwork(" + todo + ")");;
}
}

private static void
timeReadFromNetwork(int todo, byte[] buffer)
{
try
{
InputStream stream = openNetworkInputStream();
timeReadStream("Network", stream, todo, buffer);
stream.close();
}
catch (Exception e)
{
reportError(e, "timeReadFromNetwork(" + todo + ", " + buffer.length + ")");;
}
}

private static void
timeReadStream(String name, InputStream stream, int todo)
throws IOException
{
int done = 0;
long start = now();
while (done < todo)
{
// not actually interested in EOF or value read
stream.read();
done++;
}
reportTime("read bytewise", done, name, now()-start);
}

private static void
timeReadStream(String name, InputStream stream, int todo, byte[] buffer)
throws IOException
{
int done = 0;
long start = now();
while (done < todo)
{
// just overwrite buffer contents and ignore possible EOF
done += stream.read(buffer, 0, Math.min(todo-done, buffer.length));
}
reportTime("read[" + buffer.length + "]", done, name, now()-start);
}

private static OutputStream
openNetworkOutputStream()
throws IOException
{
return new BufferedOutputStream(
new Socket(SERVER, Server.WRITE_PORT)
.getOutputStream());
}

private static OutputStream
openFileOutputStream()
throws IOException
{
return new BufferedOutputStream(
new FileOutputStream(
FILENAME));
}

private static InputStream
openNetworkInputStream()
throws IOException
{
return new BufferedInputStream(
new Socket(SERVER, Server.READ_PORT)
.getInputStream());
}

private static InputStream
openFileInputStream()
throws IOException
{
return new BufferedInputStream(
new FileInputStream(
FILENAME));
}

private static long
now()
{
return System.currentTimeMillis();
}

private static void
reportTime(String test, int size, String name, long time)
{
System.out.print(name + " " + test + ":\t");
System.out.print(size + " bytes:\t");
System.out.println(time / 1000.0);
}

private static void
reportError(Exception e, String test)
{
System.err.print("Did not test ");
System.err.println(test);
e.printStackTrace();
}
}
========== end of Main.java ==========


============= Server.java ============
import java.io.*;
import java.net.Socket;

import java.net.*;
import java.io.*;

public abstract class Server
implements Runnable
{
public static final int READ_PORT = 3344; // port CLIENTS read from
public static final int WRITE_PORT = 4433; // port CLIENTS write to

protected final byte[] buffer = new byte[1024 * 256];

public static void
main(String[] args)
{
new Thread(new Reader()).start();
new Thread(new Writer()).start();
}

public void
run()
{
ServerSocket socket = null;
try
{
socket = new ServerSocket(serverPort());
}
catch (IOException e)
{
System.err.println(e);
return;
}

for (;;)
{
try
{
System.err.println("waiting on " + socket);
Socket client = socket.accept();
System.err.println("got " + client);
handle(client);
client.close();
System.err.println("finished with " + client);
}
catch (IOException e)
{
System.err.println(e);
}
}
}

protected abstract int serverPort();
protected abstract void handle(Socket client) throws IOException;
}

class Reader
extends Server
{
protected int serverPort()
{
return WRITE_PORT;
}

protected void
handle(Socket client)
throws IOException
{
InputStream in = client.getInputStream();

while (in.read(buffer) != -1)
;

in.close();
}
}

class Writer
extends Server
{
protected int serverPort()
{
return READ_PORT;
}

protected void
handle(Socket client)
throws IOException
{
OutputStream out = client.getOutputStream();

try
{
for (;;)
out.write(buffer);
}
catch (IOException e)
{
}

out.close();
}
}
========== end of Server.java ==========
 
S

steve

I said:
It's INCREDIBLY wasteful to read bytes one by one. Use a byte[] and
the associated read/write methods.

Umm... it's not, you know. It is a /little/ wasteful, but not hugely
so, and not enough to worry about in many situations. The key is that
the original code is using a buffered reader.
[...]
er it is Very wasteful

as much as 30 seconds difference for the following.

You surprise me immensely. This is not what my previous tests have
indicated (yes, I have measured it before ;-), nor is it what logic would
indicate. [...]
Obviously I should (re)run some tests, but I'm not in the mood for
hacking Java on a Sunday afternoon. I'll investigate further and report
back later...

OK, it's later now, so here I am again.

Testing reading and writing to file or to the LAN. The test involves reading
or writing 1GB either bytewise, or using a 1K, 8K, or 64K buffer.
Incidentally the size of the test is very important for file read/writes
otherwise OS buffering will invalidate the test. The test machine has 512Mb
RAM, of which most is free during the test, but the 1Gb is large enough that
just about all the data will have to be read/written in each case, and the
machine's OS caches are only (and legitimately) being used for
read-ahead/write-behind.

My test is running on a WinXP Pro laptop, using Sun's 1.4.2 JVM.

The network tests connect to a server that either reads or writes data as fast
as it can. In my test the server was running Sun's 1.4.1 on Win2K -- not that
it matters much, the only important thing is that the server machine can both
produce and consume data faster than the test machine can.

I'll add the code for the test and server process at the end of this post.

Here are the results. The last columns is the time in seconds, the numbers in
[square brackets] are the size of the array used for the read(byte[]) or
write(byte[]) calls.

File write bytewise: 1073741824 bytes: 86.464
File write[1024]: 1073741824 bytes: 92.713
File write[8192]: 1073741824 bytes: 81.377
File write[65536]: 1073741824 bytes: 73.215

Network write bytewise: 1073741824 bytes: 118.88
Network write[1024]: 1073741824 bytes: 94.015
Network write[8192]: 1073741824 bytes: 91.812
Network write[65536]: 1073741824 bytes: 91.151

File read bytewise: 1073741824 bytes: 45.385
File read[1024]: 1073741824 bytes: 45.105
File read[8192]: 1073741824 bytes: 45.135
File read[65536]: 1073741824 bytes: 45.065

Network read bytewise: 1073741824 bytes: 94.766
Network read[1024]: 1073741824 bytes: 90.861
Network read[8192]: 1073741824 bytes: 90.84
Network read[65536]: 1073741824 bytes: 90.791

In general the use of bytewise IO is costing very little -- at least not on my
system. Still, I'd expect similar results on other systems.

Note that these tests don't actually do anything with the data they read, or
take time creating the data to write. So in the real world most applications
more complicated than a simple file-copy would expect to see relatively less
benefit from using the array forms.

Another note is that both the array and the bytewise tests are using a
buffered
stream. That may be putting the array forms at a slight disadvantage compared
to a raw stream (since there's more complex code path, to no real advantage).
I expect that effect to be pretty small, but admit I haven't measured it.

-- chris

Rather manky code follows. Main takes the number of Mbytes to read/write as
its single agument. Server takes no arguments at all.

============= Main.java ============
import java.io.*;
import java.net.Socket;

public class Main
{
private static byte[] buffer1 = new byte[1024 * 1];
private static byte[] buffer8 = new byte[1024 * 8];
private static byte[] buffer64 = new byte[1024 * 64];

private static final String FILENAME = "C:/temp/crud.dat";
private static final String SERVER = "**THE OTHER MACHINE**";

public static void
main(String args[])
throws NumberFormatException
{
int todo = args.length > 0
? Integer.parseInt(args[0])
: 1; // deliberately tiny for testing
todo *= 1024 * 1024; // but not /that/ tiny...

initialiseBuffers();

timeWritesToFile(todo);
timeWritesToNetwork(todo);
timeReadsFromFile(todo);
timeReadsFromNetwork(todo);
}

private static void
initialiseBuffers()
{
initialiseBuffer(buffer1);
initialiseBuffer(buffer8);
initialiseBuffer(buffer64);
}

private static void
initialiseBuffer(byte[] buffer)
{
for (int i = 0; i < buffer.length; i++)
buffer = (byte)(i-128);
}

private static void
timeWritesToFile(int todo)
{
timeWriteToFile(todo);
timeWriteToFile(todo, buffer1);
timeWriteToFile(todo, buffer8);
timeWriteToFile(todo, buffer64);
}

private static void
timeWritesToNetwork(int todo)
{
timeWriteToNetwork(todo);
timeWriteToNetwork(todo, buffer1);
timeWriteToNetwork(todo, buffer8);
timeWriteToNetwork(todo, buffer64);
}

private static void
timeWriteToFile(int todo)
{
try
{
OutputStream stream = openFileOutputStream();
timeWriteStream("File", stream, todo);
stream.close();
}
catch (Exception e)
{
reportError(e, "timeWriteToFile(" + todo + ")");
}
}

private static void
timeWriteToFile(int todo, byte[] buffer)
{
try
{
OutputStream stream = openFileOutputStream();
timeWriteStream("File", stream, todo, buffer);
stream.close();
}
catch (Exception e)
{
reportError(e, "timeWriteToFile(" + todo + ", " + buffer.length + ")");;
}
}

private static void
timeWriteToNetwork(int todo)
{
try
{
OutputStream stream = openNetworkOutputStream();
timeWriteStream("Network", stream, todo);
stream.close();
}
catch (Exception e)
{
reportError(e, "timeWriteToNetwork(" + todo + ")");;
}
}

private static void
timeWriteToNetwork(int todo, byte[] buffer)
{
try
{
OutputStream stream = openNetworkOutputStream();
timeWriteStream("Network", stream, todo, buffer);
stream.close();
}
catch (Exception e)
{
reportError(e, "timeWriteToNetwork(" + todo + ", " + buffer.length + ")");;
}
}

private static void
timeWriteStream(String name, OutputStream stream, int todo)
throws IOException
{
int done = 0;
long start = now();
while (done < todo)
{
stream.write((byte)(done-128));
done++;
}
stream.flush();
reportTime("write bytewise", done, name, now()-start);
}

private static void
timeWriteStream(String name, OutputStream stream, int todo, byte[] buffer)
throws IOException
{
int done = 0;
long start = now();
while (done < todo)
{
int write = Math.min(todo-done, buffer.length);
stream.write(buffer, 0, write);
done += write;
}
stream.flush();
reportTime("write[" + buffer.length + "]", done, name, now()-start);
}


private static void
timeReadsFromFile(int todo)
{
timeReadFromFile(todo);
timeReadFromFile(todo, buffer1);
timeReadFromFile(todo, buffer8);
timeReadFromFile(todo, buffer64);
}

private static void
timeReadsFromNetwork(int todo)
{
timeReadFromNetwork(todo);
timeReadFromNetwork(todo, buffer1);
timeReadFromNetwork(todo, buffer8);
timeReadFromNetwork(todo, buffer64);
}

private static void
timeReadFromFile(int todo)
{
try
{
InputStream stream = openFileInputStream();
timeReadStream("File", stream, todo);
stream.close();
}
catch (Exception e)
{
System.out.println("Did not test timeReadFromFile(" + todo + ")");;
}
}

private static void
timeReadFromFile(int todo, byte[] buffer)
{
try
{
InputStream stream = openFileInputStream();
timeReadStream("File", stream, todo, buffer);
stream.close();
}
catch (Exception e)
{
reportError(e, "timeReadFromFile(" + todo + ", " + buffer.length + ")");;
}
}

private static void
timeReadFromNetwork(int todo)
{
try
{
InputStream stream = openNetworkInputStream();
timeReadStream("Network", stream, todo);
stream.close();
}
catch (Exception e)
{
reportError(e, "timeReadFromNetwork(" + todo + ")");;
}
}

private static void
timeReadFromNetwork(int todo, byte[] buffer)
{
try
{
InputStream stream = openNetworkInputStream();
timeReadStream("Network", stream, todo, buffer);
stream.close();
}
catch (Exception e)
{
reportError(e, "timeReadFromNetwork(" + todo + ", " + buffer.length +
")");;
}
}

private static void
timeReadStream(String name, InputStream stream, int todo)
throws IOException
{
int done = 0;
long start = now();
while (done < todo)
{
// not actually interested in EOF or value read
stream.read();
done++;
}
reportTime("read bytewise", done, name, now()-start);
}

private static void
timeReadStream(String name, InputStream stream, int todo, byte[] buffer)
throws IOException
{
int done = 0;
long start = now();
while (done < todo)
{
// just overwrite buffer contents and ignore possible EOF
done += stream.read(buffer, 0, Math.min(todo-done, buffer.length));
}
reportTime("read[" + buffer.length + "]", done, name, now()-start);
}

private static OutputStream
openNetworkOutputStream()
throws IOException
{
return new BufferedOutputStream(
new Socket(SERVER, Server.WRITE_PORT)
.getOutputStream());
}

private static OutputStream
openFileOutputStream()
throws IOException
{
return new BufferedOutputStream(
new FileOutputStream(
FILENAME));
}

private static InputStream
openNetworkInputStream()
throws IOException
{
return new BufferedInputStream(
new Socket(SERVER, Server.READ_PORT)
.getInputStream());
}

private static InputStream
openFileInputStream()
throws IOException
{
return new BufferedInputStream(
new FileInputStream(
FILENAME));
}

private static long
now()
{
return System.currentTimeMillis();
}

private static void
reportTime(String test, int size, String name, long time)
{
System.out.print(name + " " + test + ":\t");
System.out.print(size + " bytes:\t");
System.out.println(time / 1000.0);
}

private static void
reportError(Exception e, String test)
{
System.err.print("Did not test ");
System.err.println(test);
e.printStackTrace();
}
}
========== end of Main.java ==========


============= Server.java ============
import java.io.*;
import java.net.Socket;

import java.net.*;
import java.io.*;

public abstract class Server
implements Runnable
{
public static final int READ_PORT = 3344; // port CLIENTS read from
public static final int WRITE_PORT = 4433; // port CLIENTS write to

protected final byte[] buffer = new byte[1024 * 256];

public static void
main(String[] args)
{
new Thread(new Reader()).start();
new Thread(new Writer()).start();
}

public void
run()
{
ServerSocket socket = null;
try
{
socket = new ServerSocket(serverPort());
}
catch (IOException e)
{
System.err.println(e);
return;
}

for (;;)
{
try
{
System.err.println("waiting on " + socket);
Socket client = socket.accept();
System.err.println("got " + client);
handle(client);
client.close();
System.err.println("finished with " + client);
}
catch (IOException e)
{
System.err.println(e);
}
}
}

protected abstract int serverPort();
protected abstract void handle(Socket client) throws IOException;
}

class Reader
extends Server
{
protected int serverPort()
{
return WRITE_PORT;
}

protected void
handle(Socket client)
throws IOException
{
InputStream in = client.getInputStream();

while (in.read(buffer) != -1)
;

in.close();
}
}

class Writer
extends Server
{
protected int serverPort()
{
return READ_PORT;
}

protected void
handle(Socket client)
throws IOException
{
OutputStream out = client.getOutputStream();

try
{
for (;;)
out.write(buffer);
}
catch (IOException e)
{
}

out.close();
}
}
========== end of Server.java ==========


thats odd!!

I'm going to run that on my systems to see what results i get.
steve
 
C

Carl Howells

steve said:
thats odd!!

I'm going to run that on my systems to see what results i get.
steve

You quoted over 500 lines just for that? Please trim the text you are
replying to down to the relevant amount.
 
S

steve

You quoted over 500 lines just for that? Please trim the text you are
replying to down to the relevant amount.

sorry Mr policeman. is there something you want to say.
Perhaps you can go play in another news group.

may i recommend alt.wankers.
 
S

steve

OK, it's later now, so here I am again.

Testing reading and writing to file or to the LAN. The test involves reading
or writing 1GB either bytewise, or using a 1K, 8K, or 64K buffer.
Incidentally the size of the test is very important for file read/writes
otherwise OS buffering will invalidate the test. The test machine has 512Mb
RAM, of which most is free during the test, but the 1Gb is large enough that
just about all the data will have to be read/written in each case, and the
machine's OS caches are only (and legitimately) being used for
read-ahead/write-behind.

My test is running on a WinXP Pro laptop, using Sun's 1.4.2 JVM.

The network tests connect to a server that either reads or writes data as fast
as it can. In my test the server was running Sun's 1.4.1 on Win2K -- not that
it matters much, the only important thing is that the server machine can both
produce and consume data faster than the test machine can.

I'll add the code for the test and server process at the end of this post.

Here are the results. The last columns is the time in seconds, the numbers in
[square brackets] are the size of the array used for the read(byte[]) or
write(byte[]) calls.

File write bytewise: 1073741824 bytes: 86.464
File write[1024]: 1073741824 bytes: 92.713
File write[8192]: 1073741824 bytes: 81.377
File write[65536]: 1073741824 bytes: 73.215

Network write bytewise: 1073741824 bytes: 118.88
Network write[1024]: 1073741824 bytes: 94.015
Network write[8192]: 1073741824 bytes: 91.812
Network write[65536]: 1073741824 bytes: 91.151

File read bytewise: 1073741824 bytes: 45.385
File read[1024]: 1073741824 bytes: 45.105
File read[8192]: 1073741824 bytes: 45.135
File read[65536]: 1073741824 bytes: 45.065

Network read bytewise: 1073741824 bytes: 94.766
Network read[1024]: 1073741824 bytes: 90.861
Network read[8192]: 1073741824 bytes: 90.84
Network read[65536]: 1073741824 bytes: 90.791

In general the use of bytewise IO is costing very little -- at least not on my
system. Still, I'd expect similar results on other systems.

Note that these tests don't actually do anything with the data they read, or
take time creating the data to write. So in the real world most applications
more complicated than a simple file-copy would expect to see relatively less
benefit from using the array forms.

Another note is that both the array and the bytewise tests are using a
buffered
stream. That may be putting the array forms at a slight disadvantage compared
to a raw stream (since there's more complex code path, to no real advantage).
I expect that effect to be pretty small, but admit I haven't measured it.

-- chris

Rather manky code follows. Main takes the number of Mbytes to read/write as
its single agument. Server takes no arguments at all.

============= Main.java ============
import java.io.*;
import java.net.Socket;

public class Main
{
private static byte[] buffer1 = new byte[1024 * 1];
private static byte[] buffer8 = new byte[1024 * 8];
private static byte[] buffer64 = new byte[1024 * 64];

private static final String FILENAME = "C:/temp/crud.dat";
private static final String SERVER = "**THE OTHER MACHINE**";

public static void
main(String args[])
throws NumberFormatException
{
int todo = args.length > 0
? Integer.parseInt(args[0])
: 1; // deliberately tiny for testing
todo *= 1024 * 1024; // but not /that/ tiny...

initialiseBuffers();

timeWritesToFile(todo);
timeWritesToNetwork(todo);
timeReadsFromFile(todo);
timeReadsFromNetwork(todo);
}

private static void
initialiseBuffers()
{
initialiseBuffer(buffer1);
initialiseBuffer(buffer8);
initialiseBuffer(buffer64);
}

private static void
initialiseBuffer(byte[] buffer)
{
for (int i = 0; i < buffer.length; i++)
buffer = (byte)(i-128);
}

private static void
timeWritesToFile(int todo)
{
timeWriteToFile(todo);
timeWriteToFile(todo, buffer1);
timeWriteToFile(todo, buffer8);
timeWriteToFile(todo, buffer64);
}

private static void
timeWritesToNetwork(int todo)
{
timeWriteToNetwork(todo);
timeWriteToNetwork(todo, buffer1);
timeWriteToNetwork(todo, buffer8);
timeWriteToNetwork(todo, buffer64);
}

private static void
timeWriteToFile(int todo)
{
try
{
OutputStream stream = openFileOutputStream();
timeWriteStream("File", stream, todo);
stream.close();
}
catch (Exception e)
{
reportError(e, "timeWriteToFile(" + todo + ")");
}
}

private static void
timeWriteToFile(int todo, byte[] buffer)
{
try
{
OutputStream stream = openFileOutputStream();
timeWriteStream("File", stream, todo, buffer);
stream.close();
}
catch (Exception e)
{
reportError(e, "timeWriteToFile(" + todo + ", " + buffer.length + ")");;
}
}

private static void
timeWriteToNetwork(int todo)
{
try
{
OutputStream stream = openNetworkOutputStream();
timeWriteStream("Network", stream, todo);
stream.close();
}
catch (Exception e)
{
reportError(e, "timeWriteToNetwork(" + todo + ")");;
}
}

private static void
timeWriteToNetwork(int todo, byte[] buffer)
{
try
{
OutputStream stream = openNetworkOutputStream();
timeWriteStream("Network", stream, todo, buffer);
stream.close();
}
catch (Exception e)
{
reportError(e, "timeWriteToNetwork(" + todo + ", " + buffer.length + ")");;
}
}

private static void
timeWriteStream(String name, OutputStream stream, int todo)
throws IOException
{
int done = 0;
long start = now();
while (done < todo)
{
stream.write((byte)(done-128));
done++;
}
stream.flush();
reportTime("write bytewise", done, name, now()-start);
}

private static void
timeWriteStream(String name, OutputStream stream, int todo, byte[] buffer)
throws IOException
{
int done = 0;
long start = now();
while (done < todo)
{
int write = Math.min(todo-done, buffer.length);
stream.write(buffer, 0, write);
done += write;
}
stream.flush();
reportTime("write[" + buffer.length + "]", done, name, now()-start);
}


private static void
timeReadsFromFile(int todo)
{
timeReadFromFile(todo);
timeReadFromFile(todo, buffer1);
timeReadFromFile(todo, buffer8);
timeReadFromFile(todo, buffer64);
}

private static void
timeReadsFromNetwork(int todo)
{
timeReadFromNetwork(todo);
timeReadFromNetwork(todo, buffer1);
timeReadFromNetwork(todo, buffer8);
timeReadFromNetwork(todo, buffer64);
}

private static void
timeReadFromFile(int todo)
{
try
{
InputStream stream = openFileInputStream();
timeReadStream("File", stream, todo);
stream.close();
}
catch (Exception e)
{
System.out.println("Did not test timeReadFromFile(" + todo + ")");;
}
}

private static void
timeReadFromFile(int todo, byte[] buffer)
{
try
{
InputStream stream = openFileInputStream();
timeReadStream("File", stream, todo, buffer);
stream.close();
}
catch (Exception e)
{
reportError(e, "timeReadFromFile(" + todo + ", " + buffer.length + ")");;
}
}

private static void
timeReadFromNetwork(int todo)
{
try
{
InputStream stream = openNetworkInputStream();
timeReadStream("Network", stream, todo);
stream.close();
}
catch (Exception e)
{
reportError(e, "timeReadFromNetwork(" + todo + ")");;
}
}

private static void
timeReadFromNetwork(int todo, byte[] buffer)
{
try
{
InputStream stream = openNetworkInputStream();
timeReadStream("Network", stream, todo, buffer);
stream.close();
}
catch (Exception e)
{
reportError(e, "timeReadFromNetwork(" + todo + ", " + buffer.length +
")");;
}
}

private static void
timeReadStream(String name, InputStream stream, int todo)
throws IOException
{
int done = 0;
long start = now();
while (done < todo)
{
// not actually interested in EOF or value read
stream.read();
done++;
}
reportTime("read bytewise", done, name, now()-start);
}

private static void
timeReadStream(String name, InputStream stream, int todo, byte[] buffer)
throws IOException
{
int done = 0;
long start = now();
while (done < todo)
{
// just overwrite buffer contents and ignore possible EOF
done += stream.read(buffer, 0, Math.min(todo-done, buffer.length));
}
reportTime("read[" + buffer.length + "]", done, name, now()-start);
}

private static OutputStream
openNetworkOutputStream()
throws IOException
{
return new BufferedOutputStream(
new Socket(SERVER, Server.WRITE_PORT)
.getOutputStream());
}

private static OutputStream
openFileOutputStream()
throws IOException
{
return new BufferedOutputStream(
new FileOutputStream(
FILENAME));
}

private static InputStream
openNetworkInputStream()
throws IOException
{
return new BufferedInputStream(
new Socket(SERVER, Server.READ_PORT)
.getInputStream());
}

private static InputStream
openFileInputStream()
throws IOException
{
return new BufferedInputStream(
new FileInputStream(
FILENAME));
}

private static long
now()
{
return System.currentTimeMillis();
}

private static void
reportTime(String test, int size, String name, long time)
{
System.out.print(name + " " + test + ":\t");
System.out.print(size + " bytes:\t");
System.out.println(time / 1000.0);
}

private static void
reportError(Exception e, String test)
{
System.err.print("Did not test ");
System.err.println(test);
e.printStackTrace();
}
}
========== end of Main.java ==========


============= Server.java ============
import java.io.*;
import java.net.Socket;

import java.net.*;
import java.io.*;

public abstract class Server
implements Runnable
{
public static final int READ_PORT = 3344; // port CLIENTS read from
public static final int WRITE_PORT = 4433; // port CLIENTS write to

protected final byte[] buffer = new byte[1024 * 256];

public static void
main(String[] args)
{
new Thread(new Reader()).start();
new Thread(new Writer()).start();
}

public void
run()
{
ServerSocket socket = null;
try
{
socket = new ServerSocket(serverPort());
}
catch (IOException e)
{
System.err.println(e);
return;
}

for (;;)
{
try
{
System.err.println("waiting on " + socket);
Socket client = socket.accept();
System.err.println("got " + client);
handle(client);
client.close();
System.err.println("finished with " + client);
}
catch (IOException e)
{
System.err.println(e);
}
}
}

protected abstract int serverPort();
protected abstract void handle(Socket client) throws IOException;
}

class Reader
extends Server
{
protected int serverPort()
{
return WRITE_PORT;
}

protected void
handle(Socket client)
throws IOException
{
InputStream in = client.getInputStream();

while (in.read(buffer) != -1)
;

in.close();
}
}

class Writer
extends Server
{
protected int serverPort()
{
return READ_PORT;
}

protected void
handle(Socket client)
throws IOException
{
OutputStream out = client.getOutputStream();

try
{
for (;;)
out.write(buffer);
}
catch (IOException e)
{
}

out.close();
}
}
========== end of Server.java ==========



was the server let & the client , both running on the same machine?

If so it's not really a real world test, as the OS will loop the data back
internally.

You would get a better idea , if the code was setup on 2 machines.
Otherwise you are not going to get a true idea of all the overheads, after
all that is what we are looking at.

steve
 
C

Chris Uppal

steve said:
sorry Mr policeman. is there something you want to say.
Perhaps you can go play in another news group.

I there is no doubt /whatsoever/ that Carl was correct. For you to quote all
of my (admittedly overlong) post to add one line of commentary was discourteous
at best.
may i recommend alt.wankers.

Indeed.

Anyone can make a mistake, but your infantile response passes the bounds of my
tolerance.

Bye.

-- chris
 
A

Andrew Thompson

You would get a better idea ,

You would get (offered) better ideas, steve,
if you did not set out to inconvenience every
member of the group with your execcssive posts.

I will add my objections to those of both Carl and
Chris. Please delete unnecessary material from your
posts.

For further information, this matter is discussed in
a page I wrote to answer common questions.
<http://www.physci.org/codes/javafaq.jsp#netiquette>

The first paragraphs of that entry deal with top-posting,
but the latter ones discuss the inconvenience caused by
excessive bottom quoting.

Now, since this post was unwisely cross-posted to
both c.l.j.programmer and c.l.j.help, I will assume
you are reading it on c.l.j.help and be done with it.

OTOH, if you set out to piss-off the people on these
groups, you will quickly find that they become less
than useful for you, when everybody begins to ignore you.
You end up having conversations with yourself.

Think about it.

I am setting the Follow-Ups for this part of the
thread to c.l.j.help, as most c.l.j.programmers
already understand the things you seem to be
objecting to.
 
S

Steve Cassidy

The write(), now, /is/ "INCREDIBLY wasteful", since there doesn't seem to
be a
buffered writer in use, but I assume that's just an oversight.

Streaming out raw binary data with a Writer is fundamentally misguided.
Writers are for writing character streams. If you want raw bytes, you need
to use an OutputStream class.

From the Writer JavaDoc:
"public void write(int c) throws IOException
Write a single character. The character to be written is contained in the 16
low-order bits
of the given integer value; the 16 high-order bits are ignored."

In other words, any int that happens to have any of the high order bits set
will get munged.

Regards,
Steven
 
A

Alex Hunsley

steve said:
sorry Mr policeman. is there something you want to say.
Perhaps you can go play in another news group.

may i recommend alt.wankers.

Way to go, Steve.
You break common usenet etiquette and then when somebody, quite rightly, points
it out to you and tells you how to fix it, you throw the toys out of the pram.

Don't expect to get as much help as you otherwise could out of this group (or
usenet in general) if you are going to behave like a child. Do expect to end up
in many killfiles.

alex
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top