Parsing text file using StreamTokenizer
BufferedReader br = new BufferedReader(new FileReader("file"));
StreamTokenizer st = new StreamTokenizer(br);
st.resetSyntax();
// set the syntax to read -9.0123E+5 as a single token
st.whitespaceChars((int)'\u0000',(int)'\u0020');
st.wordChars((int)'.',(int)'.');
st.wordChars((int)'-',(int)'-');
st.wordChars((int)'+',(int)'+');
st.wordChars((int)'0',(int)'9');
st.wordChars((int)'E',(int)'E');
int stn = st.nextToken(); zliberror.assert(stn == StreamTokenizer.TT_WORD);
stn = st.nextToken();
while(stn != StreamTokenizer.TT_EOF)
{
String tag = st.sval;
stn = st.nextToken();
float val = (float)Double.parseDouble(st.sval);
stn = st.nextToken();
...
}
br.close();
Write text file
// filewriter is the basic text output class
// passing through a bufferedwriter buffers requests, faster
// printwriter adds ability to print by lines
PrintWriter fout =
new PrintWriter(new BufferedWriter(new FileWriter("filename")));
fout.print("abc");
fout.println("...");
fout.close();
Write binary data using ObjectStream
ObjectStream reads/writes binary data in the java-standard order,
so you can write a binary file on e.g. Sun or Mac and read on Intel
without byteswapping in your program.
Example adapted from
http://java.sun.com/j2se/1.4/docs/api/java/io/ObjectInputStream.html
FileOutputStream ostream = new FileOutputStream("t.tmp");
// faster:
// BufferedOutputStream ostream
// = new BufferedOutputStream(new FileOutputStream("t.tmp"));
ObjectOutputStream p = new ObjectOutputStream(ostream);
p.writeInt(12345);
p.writeDouble(3.33);
p.writeObject("Today");
p.writeObject(new Date());
p.flush();
ostream.close();
----------------
FileInputStream istream = new FileInputStream("t.tmp");
ObjectInputStream p = new ObjectInputStream(istream);
int i = p.readInt();
double d = p.readDouble();
String today = (String)p.readObject();
Date date = (Date)p.readObject();
istream.close();
Read/Write raw binary data using DataInputStream.
This should not be needed except for special purposes,
ObjectInput/OutputStream is easier.
DataInputStream di =
new DataInputStream(new BufferedInputStream(new FileInputStream("in.dat")));
DataOutputStream do =
new DataOutputStream(new BufferedOutputStream(new FileOutputStream("out.dat")));
public static int readIntIntel(DataInputStream di)
throws IOException
{
byte a = di.readByte();
byte b = di.readByte();
byte c = di.readByte();
byte d = di.readByte();
return ( ((d&0xff) << 24) | ((c&0xff) << 16) |
((b&0xff) << 8 ) | (a&0xff) );
}
public static void writeIntIntel(DataOutputStream dos, int i)
throws IOException
{
byte a = (byte)(i & 0xff);
byte b = (byte)((i >>> 8) & 0xff);
byte c = (byte)((i >>> 16) & 0xff);
byte d = (byte)((i >>> 24) & 0xff);
dos.write(a);
dos.write(b);
dos.write(c);
dos.write(d);
}
Use buffered I/O for speed in writing large files
(this is like the difference between read, fread in C):
InputStream f = new BufferedInputStream(new FileInputStream("c:xx.pic"));
ObjectInputStream f
= new ObjectInputStream(new BufferedInputStream(new FileInputStream(...)));
Reader f = new BufferedInputReader(new FileReader("..."));
same for fileoutput:
OutputStream f = new BufferedOutputStream(new FileOutputStream(...
Serialization
There is a commandline program 'serialver' that is part of the jdk,
run this on a serialized class and it prints out a magic number.
Example, Nurb.class is serializable,
serialver Nurb
prints
Nurb: static final long serialVersionUID = -5821547843414617226L;
then add this variable to the java file and the serial version
will remain the same. I expect that you can pick any number
rather than running the serialver program. And of course
you should change the serialver if class members are added or
changed.
Reflection
Print the type of an object:
Class c = x.getClass();
String n = c.getName();
Matrix
Two free matrix libraries (that include e.g. svd) are Jama and JNL.
Jama provides source, but I found it to be slower than JNL,
because it uses an abstraction rather than java arrays for the matrix
accessing.
JNL routines are in the package VisualNumerics.math.*.
JNL has been superceeded by a commercial product,
but the original version is available for download at
http://www.vni.com/products/imsl/jnl/download/
The JNL docs are on the web in various places e.g.,
http://www.physics.orst.edu/~rubin/COURSES/Handouts/JNL/api/Package-VisualNumerics.math.html
idioms
public double[] getPivot() { return new double[]{_pivotX,_pivotY} };
import java.text.NumberFormat;
static NumberFormat _nf;
static {
_nf = NumberFormat.getInstance();
_nf.setMinimumFractionDigits(3);
_nf.setMaximumFractionDigits(3);
_nf.setMinimumIntegerDigits(3);
_nf.setMaximumIntegerDigits(3);
}
System.out.println(_nf.format(d) + " "); ...
bufferedimage
BufferedImage image = ImageIO.read(new File(cmdline[0]));
int xres = image.getWidth();
int yres = image.getHeight();
printInfo(image);
// or create a new image from scratch:
//BufferedImage image
// = new BufferedImage(xres, yres, BufferedImage.TYPE_INT_ARGB);
// per-pixel access (slowest)
int xloc = xres/2;
int yloc = yres/2;
{
int pv = image.getRGB(xloc, yloc);
int r = (pv >> 16) & 0xff;
int g = (pv >> 8) & 0xff;
int b = pv & 0xff;
r = 0; // zero the r
pv = (255<<24)|(r<<16)|(g<<8)|b; // ARGB is default
image.setRGB(xloc, yloc, pv);
}
// medium speed: go through the WritableRaster api
WritableRaster wr = image.getRaster();
// make a red line going right from the center
for( int i = 1; i < 5; i++ )
wr.setSample(xloc+i, yloc, 0, 255);
// fastest: access the pixels directly
DataBuffer db = (DataBuffer)wr.getDataBuffer();
if (db.getDataType() == DataBuffer.TYPE_INT) {
DataBufferInt dbi = (DataBufferInt)db;
int[] pixels = dbi.getData();
if (pixels.length != (xres*yres*3)) error("data is not rgb");
for( int iy = 0; iy < yres; iy++ ) {
for( int ix = 0; ix < xres; ix++ ) {
int off = iy*xres + ix;
int pixel = pixels[off];
int r = (pixel>>16) & 0xff;
int g = (pixel>>8) & 0xff;
int b = pixel & 0xff;
int avg = (r+g+b)/3;
pixel = (0xff<<24)|(r<<16)|(g<<8)|b;
pixels[off] = (byte)pixel;
}
}
}
// data accessed as array of unsigned bytes,
// but java byte type is always signed, so some fussy conversion here
else if (db.getDataType() == DataBuffer.TYPE_BYTE) {
DataBufferByte dbi = (DataBufferByte)db;
byte[] pixels = dbi.getData();
if (pixels.length != (xres*yres*3)) error("data is not rgb");
if (image.getType() == TYPE_3BYTE_BGR) {
for( int iy = 0; iy < yres; iy++ ) {
for( int ix = 0; ix < xres; ix++ ) {
int off = 3*(iy*xres + ix);
int b = pixels[off+0]; if (b < 0) b += 255;
int g = pixels[off+1]; if (g < 0) g += 255;
int r = pixels[off+1]; if (r < 0) r += 255; // fix signed issue
r = (r+g+b)/3; // r,g to luminance, zero blue
g = r;
b = 0;
//r = 0;
pixels[off+0] = (byte)((b > 127) ? (b - 256) : b);
pixels[off+1] = (byte)((g > 127) ? (g - 256) : g);
pixels[off+2] = (byte)((r > 127) ? (r - 256) : r);
}
}
}
else {
error("cannot handle this image type");
}
}
Graphics2D g = (Graphics2D)image.getGraphics();
ImageIO.write( image, "jpg", new File( "output.jpg" ) );
System.exit(0);
Package java program into a single file:
jar cvf demo.jar *.class
to put all the class files into a single .jar. Then can run
java -jar demo.jar MyProgram ...
Also you can make the program run by double-clicking with the mouse
like a regular mac/windows program if it has no necessary
commandline arguments.
To do this, make a file 'manif' that has these two lines:
Manifest-Version: 1.0
Main-Class: MyProgram
(replace 'MyProgram' with the name of the main class).
Then do
jar cmvf manif demo.jar *.class
and the .jar can be double-clicked.
IBM JDK Download:
1.3.0 for windows
http://www7b.boulder.ibm.com/wsdd/wspvtdevkit-info.html
1.3.1 for linux
https://www6.software.ibm.com/dl/lxdk/lxdk-p