[m-rev.] For review: Java implementation of IO library

Fergus Henderson fjh at cs.mu.OZ.AU
Thu Jan 15 16:15:16 AEDT 2004


On 15-Jan-2004, James Goddard <goddardjames at yahoo.com> wrote:
> Is this what you had in mind re binary stdin/stdout?  They now read/write data
> using the same method as randomaccess, so in that respect they're
> treated the same as binary files.  The only way to allow proper seeking on
> stdin and stdout would be to buffer them entirely in memory.
> Would that be preferable?

No, buffering them in memory would cause as many problems as it would solve;
in particular it would increase space usage for some programs from constant
to linear in the size of the input.

Does Java really provide no other way?  Hmm, I had a long look, and it
does appear that Java < 1.4 does not provide any other way.

I think it would be possible to use reflection to do it correctly for
Java 1.4, by extracting the FileChannel for System.out and System.in,
and invoking seek on that.  If you use Reflection for everything, the
code for it should compile fine in Java < 1.4.  This code is a bit
implementation-dependent, but if it doesn't work it will just throw
an exception.

Here's code for getting the FileChannel for System.out:

	static Object/*FileChannel*/ get_out_channel() {
		try {
			Object/*PrintStream*/ ps = System.out;

			// Simulate
			//	BufferedOutputStream bos =
			//		(BufferedOutputStream) ps.out;
			// using reflection.
			Field out_fld = ps.getClass().getSuperclass().
				getDeclaredField("out");
			out_fld.setAccessible(true);
			Object/*BufferedOutputStream*/ bos = out_fld.get(ps);

			// Simulate
			//	FileOutputStream fs =
			//		(FileOutputStream) bos.out;
			// using reflection.
			Field out_fld2 = bos.getClass().getSuperclass().
				getDeclaredField("out");
			out_fld2.setAccessible(true);
			Object/*FileStream*/ fs = out_fld2.get(bos);

			// Simulate
			//	FileChannel channel = fs.getChannel();
			// using reflection.
			Method getChannel_mth =
				fs.getClass().getMethod("getChannel", null);
			Object/*FileChannel*/ channel =
				getChannel_mth.invoke(fs, null);

			return channel;
		} catch (Exception e) {
			return null;
		}
	}

> @@ -4897,20 +4900,101 @@
>  			}
>  		}
>  
> +		/*
> +		** This constructor is only used for mercury_stdin_binary. It
> +		** opens stdin as an approximation of a binary file and allows
> +		** a limited amount of seeking.
> +		*/
> +		public MR_MercuryFileStruct(java.io.InputStream stream,
> +				boolean openAsBinary)
> +		{
> +			if (!openAsBinary) {
> +				id		= ML_next_stream_id++;
> +				mode		= INPUT;
> +				pushback	= new java.util.Stack();
> +				input		= new java.io.
> +						InputStreamReader(stream);
> +			} else {
> +				id		= ML_next_stream_id++;
> +				mode		= INPUT;
> +				pushback	= new java.util.Stack();
> +				
> +				binary_input = new java.io.BufferedInputStream(
> +						stream);
> +			}
> +		}

The comment here is not correct.

The first three lines of code are duplicated in both branches of
the if-then-else; to avoid unnecessary code duplication,
they should be moved to before the if-then-else.

> +		/*
> +		** This constructor is only used for mercury_stdout_binary. It
> +		** opens stdout as an approximation of a binary file and allows
> +		** a limited amount of seeking.
> +		*/
> +		public MR_MercuryFileStruct(java.io.OutputStream stream,
> +				boolean openAsBinary)
> +		{
> +			if (!openAsBinary) {
> +				id		= ML_next_stream_id++;
> +				mode		= OUTPUT;
> +				output		= new java.io.
> +						OutputStreamWriter(stream);
> +			} else {
> +				id		= ML_next_stream_id++;
> +				mode		= OUTPUT;
> +				
> +				binary_output = new java.io.
> +						BufferedOutputStream(stream);
> +			}
> +		}

Likewise.

[to be continued.]

-- 
Fergus Henderson <fjh at cs.mu.oz.au>  |  "I have always known that the pursuit
The University of Melbourne         |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  |     -- the last words of T. S. Garp.
--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list