Enhancement request

M

Martin Gregorie

I guess you write only GUIs, not utilities. I use them all the time.

I use main() on GUI applications, usually so I can launch then from the
command line, but also so that "java MyGUIApp -?" will return something
meaningful. Are you (Tegiri) really saying you've never started a GUI
application from a command line or a script?
 
A

Arne Vajhøj

Tom said:
Lew said:
Tegiri Nenashi wrote:
static void main() {
}

Mark Space wrote:
Forgot the "public."

Unless you call it from another Java class in a different package,
'main()' doesn't need to be public.

It's not callable from the command line unless it's public.

class Hello
{
static void main(String[] args)
{
System.out.println("Hello.world.");
}
}


% java -cp . Hello
Main method not public.

I could have sworn that private main methods worked. Was that changed at
some point, or was i wrong all along?

http://java.sun.com/docs/books/jls/third_edition/html/execution.html#12.1.4

says:

"The method main must be declared public, static, and void. It must
accept a single argument that is an array of strings."

so it is rather specific.

Arne
 
M

Mark Space

Martin said:
File inf = new File ("myinputfile.txt");
InputStream is = new FileInputStream(inf);
Reader isr = new InputStreamReader(is);
BufferedReader inb = new BufferedReader(isr);

is just plain perverse. When I can release all the resources with

It isn't too hard, although I agree it takes getting use to. It always
follows the pattern:

Reader( StreamReader( Stream ) )

And same with Writers/StreamWriter.

The reason is Streams are older, and didn't quite work out. So Sun
needed to add Readers and Writers to fix the problem. But to get
backwards compatibility, they didn't touch the old Streams. The added
"bridge" classes instead: StreamReader and StreamWriter.

So those classes always go in between the Reader/Writer and the Stream,
and the Stream is always the deepest nested.

inb.close()

why can't I acquire them with
BufferedReader inb = new BufferedReader(inf);

or
BufferedReader("myinputfile.txt");

Maybe there's a good reason for this, but I'm damned if I can see it.

This might be a good job for a utility class with some static methods:

public class IOUtil {
private IOUtil() {} // only static methods, can't instantiate

public static BufferedReader makeReader( String s ) {
return new BufferedReader( new InputStreamReader( new

FileInputStream( s ) ) );
}

public static BufferedReader makeReader( File f ) {
return new BufferedReader( new InputStreamReader(
new FileInputStream( f ) ) );
}
}

etc. Tedious but do-able, and you only have to do it once. I'm not
sure if this could be improved with generic methods or covariant return
types.
 
M

Mike Schilling

Mark said:
The reason is Streams are older, and didn't quite work out. So Sun
needed to add Readers and Writers to fix the problem. But to get
backwards compatibility, they didn't touch the old Streams. The
added
"bridge" classes instead: StreamReader and StreamWriter.

Well, no.

Streams are used to read and write bytes. Reader and Writers are used
to read and write characters. Sometimes you want one, sometimes the
other.

PrintStreams are kind of idiotic, because as soon as you're printing
things, you're in the realm of characters. System.out and System.err
should be PrintReaders. You're quite right there that backwards
compatibility results in silliness.
 
A

Arne Vajhøj

Jason said:
Tom said:
Tegiri Nenashi wrote:
static void main() {
}

Mark Space wrote:
Forgot the "public."

Unless you call it from another Java class in a different package,
'main()' doesn't need to be public.

It's not callable from the command line unless it's public.

class Hello
{
static void main(String[] args)
{
System.out.println("Hello.world.");
}
}

% java -cp . Hello
Main method not public.

I could have sworn that private main methods worked. Was that changed
at some point, or was i wrong all along?

http://java.sun.com/docs/books/jls/third_edition/html/execution.html#12.1.4

says:

"The method main must be declared public, static, and void. It must
accept a single argument that is an array of strings."

so it is rather specific.

Okay. I should probably take my brain in for a service, then.

The exam does not have to be public.

And in C# Main does not have to be public.

So it is more or First an oppressive hatred that reprehensible in Project need
to be public.

Lisette


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
"There are some who believe that the non-Jewish population,
even in a high percentage, within our borders will be more
effectively under our surveillance; and there are some who
believe the contrary, i.e., that it is easier to carry out
surveillance over the activities of a neighbor than over
those of a tenant.

tend to support the latter view and have an additional
argument: the need to sustain the character of the state
which will henceforth be Jewish with a non-Jewish minority
limited to 15 percent. I had already reached this fundamental
position as early as 1940 [and] it is entered in my diary."

--- Joseph Weitz, head of the Jewish Agency’s Colonization
Department. From Israel: an Apartheid State by Uri Davis, p.5.
 
A

Arne Vajhøj

Actually the invaluable futuristic giggler wrote ...

Norman



- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
The Times reported that over the last twenty years, the CIA owned
or subsidized more than fifty newspapers, news services, radio
stations, periodicals and other communications facilities, most
of them overseas. These were used for propaganda efforts, or even
as cover for operations.

Another dozen foreign news organizations were infiltrated by paid
CIA agents. At least 22 American news organizations had employed
American journalists who were also working for the CIA, and nearly
a dozen American publishing houses printed some of the more than
1,000 books that had been produced or subsidized by the CIA.

When asked in a 1976 interview whether the CIA had ever told its
media agents what to write, William Colby replied,
"Oh, sure, all the time."

--- Former CIA Director William Colby

[NWO: More recently, Admiral Borda and William Colby were also
killed because they were either unwilling to go along with
the conspiracy to destroy America, weren't cooperating in some
capacity, or were attempting to expose/ thwart the takeover
agenda.]
 
T

Tom Anderson

Agreed. Why not pick on something more substantial, such as the tangle of
Readers, InputStreams etc - beast me why I have to jump through nested
hoops just to open a BufferedReader when I have File that identified the
data source. The current way of doing it:

File inf = new File ("myinputfile.txt");
InputStream is = new FileInputStream(inf);
Reader isr = new InputStreamReader(is);
BufferedReader inb = new BufferedReader(isr);

is just plain perverse. When I can release all the resources with
inb.close()

why can't I acquire them with
BufferedReader inb = new BufferedReader(inf);

or
BufferedReader("myinputfile.txt");

Maybe there's a good reason for this, but I'm damned if I can see it.

Because BufferedReaders aren't file-specific. They could be wrapping a
StringReader, and InputStreamReader wrapping a socket InputStream, a
PipedReader, etc. Would you supply constructors for all those uses? Or
privilege files above other cases?

Personally, i don't have a problem with:

BufferedReader inb = new BufferedReader(new FileReader(inf)) ;

Although i do find it shocking that FileReader's constructor doesn't take
a character set.

tom
 
T

Tom Anderson

Tom said:
Lew wrote:
Tegiri Nenashi wrote:
static void main() {
}

Mark Space wrote:
Forgot the "public."

Unless you call it from another Java class in a different package,
'main()' doesn't need to be public.

It's not callable from the command line unless it's public.

class Hello
{
static void main(String[] args)
{
System.out.println("Hello.world.");
}
}


% java -cp . Hello
Main method not public.

I could have sworn that private main methods worked. Was that changed at
some point, or was i wrong all along?

http://java.sun.com/docs/books/jls/third_edition/html/execution.html#12.1.4

says:

"The method main must be declared public, static, and void. It must accept a
single argument that is an array of strings."

so it is rather specific.

Okay. I should probably take my brain in for a service, then.

tom
 
A

Arne Vajhøj

Tom said:
Tom said:
Tegiri Nenashi wrote:
static void main() {
}

Mark Space wrote:
Forgot the "public."

Unless you call it from another Java class in a different package,
'main()' doesn't need to be public.

It's not callable from the command line unless it's public.

class Hello
{
static void main(String[] args)
{
System.out.println("Hello.world.");
}
}

% java -cp . Hello
Main method not public.

I could have sworn that private main methods worked. Was that changed
at some point, or was i wrong all along?

http://java.sun.com/docs/books/jls/third_edition/html/execution.html#12.1.4

says:

"The method main must be declared public, static, and void. It must
accept a single argument that is an array of strings."

so it is rather specific.

Okay. I should probably take my brain in for a service, then.

The class does not have to be public.

And in C# Main does not have to be public.

So it is more or less a random decision that main in Java need
to be public.

Arne
 
M

Mike Schilling

Tom said:
Personally, i don't have a problem with:

BufferedReader inb = new BufferedReader(new FileReader(inf)) ;

Although i do find it shocking that FileReader's constructor doesn't
take a character set.

Me too. It makes FileReader useless to me; I always have to decorate
FileInputStream with InputStreamReader instead.
 
L

Lew

I did *not* write that.

--
Lew



- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[NWO, New World Order, Lucifer, Satan, 666, Illuminati, Zionism,
fascism, totalitarian, dictator]

In the 1844 political novel Coningsby by Benjamin Disraeli,
the British Prime Minister, a character known as Sidonia
(which was based on Lord Rothschild, whose family he had become
close friends with in the early 1840's) says:

"That mighty revolution which is at this moment preparing in Germany
and which will be in fact a greater and a second Reformation, and of
which so little is as yet known in England, is entirely developing
under the auspices of the Jews, who almost monopolize the professorial
chairs of Germany...the world is governed by very different personages
from what is imagined by those who are not behind the scenes."
 
M

Martin Gregorie

If that's too urban, it can be simplified to just:

return new BufferedReader( new FileReader( s ));

and

return new BufferedWriter( new FileWriter( s ));
I missed that - maybe my brain needs a spring clean since I didn't manage
to deduce that one from the Javadocs. The reasoning behind keeping
BufferedReader separate from FileReader is fine - until you want to read
lines! IMO there's a reasonable case to be made that readLine() should be
a FileReader method instead of something that can only be done through a
BufferedReader. To generalize the point, using the buffered wrapper
should purely add buffering without changing the set of data access
methods.


Thanks.
 
M

Martin Gregorie

I did *not* write that.

Apologies: I didn't read the header when I should have done.

However, my point about BufferedReader providing additional data access
methods in addition to pure buffering capability still stands.
 
T

Tom Anderson

I missed that - maybe my brain needs a spring clean since I didn't
manage to deduce that one from the Javadocs. The reasoning behind
keeping BufferedReader separate from FileReader is fine - until you want
to read lines! IMO there's a reasonable case to be made that readLine()
should be a FileReader method instead of something that can only be done
through a BufferedReader. To generalize the point, using the buffered
wrapper should purely add buffering without changing the set of data
access methods.

The problem is that it's traditionally considered impossible to implement
readLine without a buffer. At least, if you want to be able to handle
multiple forms of line ending - CR, LF and CRLF. Why? Well, what do you do
when you hit a CR? Declare the line finished, and return it? What if the
next character's a LF? Then the line terminator is actually CRLF, and your
next read will give you a spurious empty line when it hits the LF. What
you have to do is read the CR, then read the next character, and if it's
an LF, carry on, but if it's not, unread it - put it back into the input.
You can't do that without a buffer, although it does only need to be one
character big. That's part of the reason why PushbackInputStream exists -
DataInputStream uses it internally to implemented ReadLine. Aah, JDK 1.0.

Now, i'm not actually sure that the above argument is true. I've never
stopped to question it before, but couldn't you just have a flag in the
reader, a boolean lastLineReadEndedWithCR, and the next time you read a
character, if it's set, you check to see if the character is an LF, and if
it is, throw it away. Would that work? It would involve doing a test every
single time you read a character, though, which could be inefficient, and
it's not immediately obvious how it would work with read(char[]), although
my gut feeling is that wouldn't be complicated. I think you might also
have trouble with available() and semantics with regard to the position in
the file.

Since buffering is almost always a good idea, though, shouldn't you almost
always be using a buffer? And if so, does it matter that FileReader
doesn't have readLine?

tom
 
M

Martin Gregorie

The problem is that it's traditionally considered impossible to
implement readLine without a buffer.
Its fairly commonly done in C using both buffered and unbuffered i/o, so
I don't see why it should be considered impossible in Java, unless that's
something to do with the implementation-dependent handling of '\n' that C
uses.
At least, if you want to be able to handle multiple forms of line
ending - CR, LF and CRLF.
That is a nice-to-have, though not usually all that useful in practice.
Now, i'm not actually sure that the above argument is true.
Likewise. ungetc() is usually implemented on a FILE*, which is buffered,
but I know I've handled line reading quite successfully from unbuffered
input.
I've never stopped to question it before, but couldn't you just have
a flag in the
reader, a boolean lastLineReadEndedWithCR, and the next time you read a
character, if it's set, you check to see if the character is an LF, and
if it is, throw it away.
Yes, until you meet a system that uses CR as the line separator.

However, writing code to treat CR or LF as the line termination is
trivial. Its equally easy to save the last character read for comparison
purposes. Then you can discard LF if the last character was CR. This will
recognise CR, LF and CRLF as line separators.
Since buffering is almost always a good idea, though, shouldn't you
almost always be using a buffer? And if so, does it matter that
FileReader doesn't have readLine?
Yes, if you're dealing with a medium to large amount of data, but its a
pain in the jacksie when you're reading from an interactive console and/
or want to deal with individual keystrokes. Its also somewhat OTT if
you're reading a small parameter file.
 
A

Andreas Leitgeb

Martin Gregorie said:
However, writing code to treat CR or LF as the line termination is
trivial. Its equally easy to save the last character read for comparison
purposes. Then you can discard LF if the last character was CR. This will
recognise CR, LF and CRLF as line separators.

Doing it strictly unbuffered (thus no ungetc-functionality) implies
two disadvantages:
- you have to read each character separately from the system
- if you see a CR during a readLine() you have to return the
line immediately, and leave the possibly following \n
in the stream until next readWhatever(), since it could
just as well be the not a \n but the first char of the
next line.
Yes, if you're dealing with a medium to large amount of data, but its a
pain in the jacksie when you're reading from an interactive console and/
or want to deal with individual keystrokes.

When you read single keystrokes from console, you never need a readLine().
Since doing a plain readLine() (not an intelligent one like GNU-readline)
will prevent recognizing and dealing with control-characters or cursor-keys
until, well, until Return is pressed.
Its also somewhat OTT if
you're reading a small parameter file.
Sorry, what is "OTT" ? If it's a file, why not buffer it?
If it's not expected to be a large file, just read it in in one slurp.
 
M

Martin Gregorie

Sorry, what is "OTT" ?
Over The Top, i.e. excessive function for what you're doing.
If it's a file, why not buffer it? If it's not
expected to be a large file, just read it in in one slurp.
Fair comment - I suppose I'm showing mental conditioning from a lot of
time spent using small computers where RAM is a precious resource.
 
T

Tom Anderson

That is a nice-to-have, though not usually all that useful in practice.

Why not? It means that you can write a program which opens text files and
reads them without having to know which platform it's on. Which, since
java is supposed to be platform-neutral, is rather useful in practice.
Likewise. ungetc() is usually implemented on a FILE*, which is buffered,
but I know I've handled line reading quite successfully from unbuffered
input.

Did you deal with input containing any combination of CR, LF and CRLF as
line terminators?
Yes, until you meet a system that uses CR as the line separator.

No, it'd deal with that fine, that's the whole point. The logic is:

boolean lastLineReadEndedWithCR ;
static boolean isCrOrLf(char ch) {
return (ch == '\r') || (ch == '\n') ;
}
String readLine() {
StringBuffer sb = new StringBuffer() ;
char ch ;
while (!isCrOrLf(ch = read())) {
sb.append(ch) ;
}
if (ch == '\r') lastLineReadEndedWithCR = true ;
return sb.toString() ;
}
char read() {
char ch = in.read() ;
if (lastLineReadEndedWithCR) {
lastLineReadEndedWithCR = false ;
if (ch == '\n') ch = in.read() ;
}
return ch ;
}

I haven't tested that, but the idea is that you make a note if ending a
line on a CR, and then you throw away the next character read if and only
if it's an LF, on the grounds that it was part of the line terminator.
Single CRs or LFs don't result in anything being thrown away.
However, writing code to treat CR or LF as the line termination is
trivial. Its equally easy to save the last character read for comparison
purposes. Then you can discard LF if the last character was CR. This
will recognise CR, LF and CRLF as line separators.

Which is exactly what i said.
Yes, if you're dealing with a medium to large amount of data, but its a
pain in the jacksie when you're reading from an interactive console and/
or want to deal with individual keystrokes.

In which case you won't be using readLine anyway.
Its also somewhat OTT if you're reading a small parameter file.

In that case, it's also a small buffer. Doesn't seem like a huge deal.

I do agree that it would be nicer if readLine didn't require a buffered
stream, and that it doesn't require that in principle. But i'm not all
that bothered that things are the way they are.

The fact that it's only BufferedWriter that has a newLine method, on the
other hand, makes me utterly furious!

tom
 
T

Tom Anderson

Doesn't the java.io API already give us that capability in a
platform-neutral way? I know that BufferedReader#readLine(), for
example, handles all three forms of line-end sequences.

That was my point! Java provides this. I read Martin's post as saying he
thought that feature was "not usually all that useful in practice", and i
disagree.

tom
 

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

Forum statistics

Threads
473,731
Messages
2,569,432
Members
44,832
Latest member
GlennSmall

Latest Threads

Top