iterator() {
+ return files.iterator();
+ }
+
+ public void addAll(TreeInfo other) {
+ files.addAll(other.files);
+ dirs.addAll(other.dirs);
+ }
+
+ @Override
+ public String toString() {
+ return "dirs: " + dirs +
+ "\n\nfiles: " + files;
+ }
+ }
+
+ public static TreeInfo walk(String start,String regex) {
+ return recuresDirs(new File(start),regex);
+ }
+
+ public static TreeInfo walk(File start,String regex) {
+ return recuresDirs(start, regex);
+ }
+
+ public static TreeInfo walk(File start) {
+ return recuresDirs(start, ".*");// 全部
+ }
+
+ public static TreeInfo walk(String start) {
+ return recuresDirs(new File(start), ".*");// 全部
+ }
+
+ public static TreeInfo recuresDirs(File startDir,String regex) {
+ TreeInfo result = new TreeInfo();
+ for(File item : startDir.listFiles()) {
+ if (item.isDirectory()) {
+ result.dirs.add(item);
+ result.addAll(recuresDirs(item, regex));
+ } else
+ if (item.getName().matches(regex))
+ result.files.add(item);
+ }
+ return result;
+ }
+
+}
diff --git a/src/main/java/org/javacore/io/FileIOStreamT.java b/src/main/java/org/javacore/io/FileIOStreamT.java
new file mode 100644
index 0000000..4f67287
--- /dev/null
+++ b/src/main/java/org/javacore/io/FileIOStreamT.java
@@ -0,0 +1,52 @@
+package org.javacore.io;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年10月8日 20:06:03
+ * FileInputStream&FileOutputStream使用案例
+ */
+public class FileIOStreamT {
+ private static final String thisFilePath =
+ "src" + File.separator +
+ "org" + File.separator +
+ "javacore" + File.separator +
+ "io" + File.separator +
+ "FileIOStreamT.java";
+ public static void main(String[] args) throws IOException {
+ // 创建文件输入流
+ FileInputStream fileInputStream = new FileInputStream(thisFilePath);
+ // 创建文件输出流
+ FileOutputStream fileOutputStream = new FileOutputStream("data.txt");
+
+ // 创建流的最大字节数组
+ byte[] inOutBytes = new byte[fileInputStream.available()];
+ // 将文件输入流读取,保存至inOutBytes数组
+ fileInputStream.read(inOutBytes);
+ // 将inOutBytes数组,写出到data.txt文件中
+ fileOutputStream.write(inOutBytes);
+
+ fileOutputStream.close();
+ fileInputStream.close();
+ }
+}
diff --git a/src/main/java/org/javacore/io/FileMethodsT.java b/src/main/java/org/javacore/io/FileMethodsT.java
new file mode 100644
index 0000000..38852ac
--- /dev/null
+++ b/src/main/java/org/javacore/io/FileMethodsT.java
@@ -0,0 +1,50 @@
+package org.javacore.io;
+
+import java.io.File;
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年7月13日 10:06:28
+ * File方法详细使用
+ */
+public class FileMethodsT {
+
+ private static void fileData(File f) {
+ System.out.println(
+ " 绝对路径:" + f.getAbsolutePath() +
+ "\n 可读:" + f.canRead() +
+ "\n 可写:" + f.canWrite() +
+ "\n 文件名:" + f.getName() +
+ "\n 上级目录:" + f.getParent() +
+ "\n 相对地址:" + f.getPath() +
+ "\n 长度:" + f.length() +
+ "\n 最近修改时间:" + f.lastModified()
+ );
+ if(f.isFile())
+ System.out.println(" 是一个文件");
+ else if(f.isDirectory())
+ System.out.println(" 是一个目录");
+ }
+
+ public static void main(String[] args) {
+ // 获取src目录
+ File file = new File("src");
+ // file详细操作
+ fileData(file);
+ }
+}
diff --git a/src/main/java/org/javacore/io/FileT.java b/src/main/java/org/javacore/io/FileT.java
new file mode 100644
index 0000000..6b8d677
--- /dev/null
+++ b/src/main/java/org/javacore/io/FileT.java
@@ -0,0 +1,66 @@
+package org.javacore.io;
+
+import java.io.File;
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import java.io.IOException;
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年6月30日 14:21:47
+ * File类的使用
+ */
+public class FileT {
+
+ public static void main(String[] args) {
+ try {
+ // 创建一个目录
+ File dir = new File("E:" + File.separator + "dir");
+ dir.mkdir();
+ // 创建一个文件
+ File file = new File(dir,"file.txt");
+ file.createNewFile();
+
+ // 是否是一个目录
+ System.out.println(dir.isDirectory());
+ // 是否是一个文件
+ System.out.println(file.isFile());
+
+ // 删除文件
+ if (file.delete()) {
+ System.out.println(file.getName() + "被删除了!");
+ } else {
+ System.out.println("文件删除失败!");
+ }
+ } catch (IOException e) { e.printStackTrace(); }
+ }
+
+}
diff --git a/src/main/java/org/javacore/io/FilenameFilterT.java b/src/main/java/org/javacore/io/FilenameFilterT.java
new file mode 100644
index 0000000..67bb7c3
--- /dev/null
+++ b/src/main/java/org/javacore/io/FilenameFilterT.java
@@ -0,0 +1,63 @@
+package org.javacore.io;
+
+import java.io.File;
+import java.io.FilenameFilter;
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年7月20日 13:31:41
+ * 类名过滤器的使用
+ */
+public class FilenameFilterT {
+
+ public static void main(String[] args) {
+ // IO包路径
+ String dir = "src" + File.separator +
+ "org" + File.separator +
+ "javacore" + File.separator +
+ "io";
+ File file = new File(dir);
+ // 创建过滤器文件
+ MyFilter filter = new MyFilter("y.java");
+ // 过滤
+ String files[] = file.list(filter);
+
+ // 打印
+ for (String name : files) {
+ System.err.println(name);
+ }
+ }
+
+ /**
+ * 内部类实现过滤器文件接口
+ */
+ static class MyFilter implements FilenameFilter {
+
+ private String type;
+
+ public MyFilter (String type) {
+ this.type = type;
+ }
+
+ @Override
+ public boolean accept(File dir, String name) {
+ return name.endsWith(type);// 以Type结尾
+ }
+
+ }
+}
diff --git a/src/main/java/org/javacore/io/FormatteMemoryInput.java b/src/main/java/org/javacore/io/FormatteMemoryInput.java
new file mode 100644
index 0000000..1a92545
--- /dev/null
+++ b/src/main/java/org/javacore/io/FormatteMemoryInput.java
@@ -0,0 +1,31 @@
+package org.javacore.io;
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.EOFException;
+import java.io.File;
+import java.io.IOException;
+/**
+ * @author Jeff Lee
+ * @since 2015年7月15日 20:42:47
+ * 格式化内存输入
+ */
+public class FormatteMemoryInput {
+ public static void main(String[] args) throws IOException {
+ String filePath = "src" + File.separator +
+ "org" + File.separator +
+ "javacore" + File.separator +
+ "io" + File.separator +
+ "FormatteMemoryInput.java";
+ try {
+ DataInputStream in = new DataInputStream(
+ // 缓冲区字节输入
+ new ByteArrayInputStream(
+ BufferedInputFileT.read(filePath).getBytes()));
+ while(true)
+ System.out.println((char)in.readByte());
+ } catch (EOFException e) {
+ System.out.println("End of Stream");
+ }
+ }
+}
diff --git a/src/main/java/org/javacore/io/JavaFileListT.java b/src/main/java/org/javacore/io/JavaFileListT.java
new file mode 100644
index 0000000..4a137dc
--- /dev/null
+++ b/src/main/java/org/javacore/io/JavaFileListT.java
@@ -0,0 +1,50 @@
+package org.javacore.io;
+
+import java.io.File;
+import java.io.FilenameFilter;
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年7月13日 21:13:58
+ * FilenameFilter文件过滤器的使用
+ */
+public class JavaFileListT {
+
+ // 文件过滤接口
+ // 作为匿名内部类,变量type必须声明为final类型
+ public static FilenameFilter javaFileFilter(final String type) {
+ // 过滤接口-匿名内部类
+ return new FilenameFilter() {
+ @Override
+ public boolean accept(File dir, String name) {
+ return new File(name).getName().indexOf(type) != -1;
+ }
+ };
+ }
+
+ public static void main(String[] args) {
+ // 创建一个目录
+ File file = new File("src\\org\\javacore\\io");// 当前目录
+ // 获取文件名数组
+ String fileNames[] = file.list(javaFileFilter(".java"));
+ // 打印
+ for (String item : fileNames) {
+ System.out.println(item);
+ }
+ }
+}
diff --git a/src/main/java/org/javacore/io/MemoryInputT.java b/src/main/java/org/javacore/io/MemoryInputT.java
new file mode 100644
index 0000000..0e4a666
--- /dev/null
+++ b/src/main/java/org/javacore/io/MemoryInputT.java
@@ -0,0 +1,39 @@
+package org.javacore.io;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.StringReader;
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年7月14日 08:54:24
+ * 内存中输入
+ */
+public class MemoryInputT {
+ public static void main(String[] args) throws IOException {
+ StringReader in = new StringReader(BufferedInputFileT.read(
+ "src" + File.separator +
+ "org" + File.separator +
+ "javacore" + File.separator +
+ "io" + File.separator +
+ "BufferedInputFileT.java"));
+ int c;
+ while((c = in.read()) != -1)// int形式
+ System.out.println((char)c);// int字节,转char显示
+ }
+}
diff --git a/src/main/java/org/javacore/io/OSExecuteT.java b/src/main/java/org/javacore/io/OSExecuteT.java
new file mode 100644
index 0000000..ecda29d
--- /dev/null
+++ b/src/main/java/org/javacore/io/OSExecuteT.java
@@ -0,0 +1,72 @@
+package org.javacore.io;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年10月6日 18:40:24
+ * 操作系统进程流的案例
+ */
+public class OSExecuteT {
+ public static void commond(String command) {
+ boolean err = false;
+
+ try {
+ // 创建操作系统进程
+ Process process =
+ new ProcessBuilder(command.split(" ")).start();
+
+ // 读取进程的输入流
+ BufferedReader results = new BufferedReader(
+ new InputStreamReader(process.getInputStream()));
+ String s;
+ while ((s = results.readLine()) != null)
+ System.out.println(s);
+
+ // 读取进程的错误流
+ BufferedReader errors = new BufferedReader(
+ new InputStreamReader(process.getErrorStream()));
+ while ((s = errors.readLine()) != null) {
+ System.err.println(s);
+ if (!err)
+ err = true;
+ }
+
+ } catch (Exception e) {
+ if (!command.startsWith("CMD /C"))
+ commond("CMD /C " + command);
+ else
+ throw new RuntimeException(e);
+ }
+
+ if (err)
+ throw new OSExecuteException("Errors Executing " + command);
+ }
+
+ public static void main(String[] args) {
+ commond("java -version");
+ }
+}
+class OSExecuteException extends RuntimeException {
+ private static final long serialVersionUID = -3254218368058055219L;
+
+ public OSExecuteException(String msg) {
+ super(msg);
+ }
+}
diff --git a/src/main/java/org/javacore/io/PipeStreamT.java b/src/main/java/org/javacore/io/PipeStreamT.java
new file mode 100644
index 0000000..018abe0
--- /dev/null
+++ b/src/main/java/org/javacore/io/PipeStreamT.java
@@ -0,0 +1,66 @@
+package org.javacore.io;
+
+import java.io.IOException;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年7月30日 21:58:18
+ * 管道输入输出流的使用
+ * 同一个JVM中,两个线程直接的字节流通信
+ */
+public class PipeStreamT {
+ public static void main(String[] args) throws IOException {
+ // 创建管道输出流
+ final PipedOutputStream output = new PipedOutputStream();
+ // 创建管道输入流,并连接到管道输出流
+ @SuppressWarnings("resource")
+ final PipedInputStream input = new PipedInputStream(output);
+ //final PipedInputStream input = new PipedInputStream();
+ //input.connect(output); // 等价于
+
+ Thread outputThread = new Thread(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ // 将指定的字节数组写入管道输出流
+ output.write("Hello,PipedStream!".getBytes());
+ } catch (IOException e) {}
+ }
+ });
+
+ Thread inputThread = new Thread(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ // 读取管道输入流中的下一个数据字节
+ int data = input.read();
+ while( data != -1) {
+ System.out.print((char) data);
+ // 再次读取下一个字节
+ data = input.read();
+ }
+ } catch (IOException e){}
+ }
+ });
+
+ outputThread.start();
+ inputThread.start();
+ }
+}
diff --git a/src/main/java/org/javacore/io/RandomAccessFileT.java b/src/main/java/org/javacore/io/RandomAccessFileT.java
new file mode 100644
index 0000000..875969a
--- /dev/null
+++ b/src/main/java/org/javacore/io/RandomAccessFileT.java
@@ -0,0 +1,48 @@
+package org.javacore.io;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年7月14日 08:54:24
+ * RandomAccessFile的使用
+ */
+public class RandomAccessFileT {
+ public static void main(String[] args) throws IOException {
+ // 获取文件,读写方式
+ RandomAccessFile file = new RandomAccessFile("D:\\data\\file.txt","rw");
+
+ // 设置文件指针位置
+ file.seek(6);
+ // 文件中的当前偏移量
+ System.out.println(file.getFilePointer());
+
+ // 读取文本的一行
+ System.out.println((char)file.read());// int字节,转char显示
+
+ // 写入字节数组
+ file.write("Hello World".getBytes());
+
+ // 初始化文件指针位置
+ file.seek(0);
+ // 读取文本的一行
+ System.out.println(file.readLine());
+
+ file.close();
+ }
+}
diff --git a/src/main/java/org/javacore/io/SByteArrayInputStream.java b/src/main/java/org/javacore/io/SByteArrayInputStream.java
new file mode 100644
index 0000000..f0bd662
--- /dev/null
+++ b/src/main/java/org/javacore/io/SByteArrayInputStream.java
@@ -0,0 +1,258 @@
+//package org.javacore.io;
+//
+//import java.io.IOException;
+//import java.io.InputStream;
+//
+///**
+// * A ByteArrayInputStream contains
+// * an internal buffer that contains bytes that
+// * may be read from the stream. An internal
+// * counter keeps track of the next byte to
+// * be supplied by the read method.
+// *
+// * Closing a ByteArrayInputStream has no effect. The methods in
+// * this class can be called after the stream has been closed without
+// * generating an IOException.
+// */
+//public
+//class SByteArrayInputStream extends InputStream {
+//
+// /**
+// * An array of bytes that was provided
+// * by the creator of the stream. Elements buf[0]
+// * through buf[count-1] are the
+// * only bytes that can ever be read from the
+// * stream; element buf[pos] is
+// * the next byte to be read.
+// */
+// protected byte buf[];
+//
+// /**
+// * The index of the next character to read from the input stream buffer.
+// * This value should always be nonnegative
+// * and not larger than the value of count.
+// * The next byte to be read from the input stream buffer
+// * will be buf[pos].
+// */
+// protected int pos;
+//
+// /**
+// * The currently marked position in the stream.
+// * ByteArrayInputStream objects are marked at position zero by
+// * default when constructed. They may be marked at another
+// * position within the buffer by the mark() method.
+// * The current buffer position is set to this point by the
+// * reset() method.
+// *
+// * If no mark has been set, then the value of mark is the offset
+// * passed to the constructor (or 0 if the offset was not supplied).
+// *
+// * @since JDK1.1
+// */
+// protected int mark = 0;
+//
+// /**
+// * The index one greater than the last valid character in the input
+// * stream buffer.
+// * This value should always be nonnegative
+// * and not larger than the length of buf.
+// * It is one greater than the position of
+// * the last byte within buf that
+// * can ever be read from the input stream buffer.
+// */
+// protected int count;
+//
+// /**
+// * Creates a ByteArrayInputStream
+// * so that it uses buf as its
+// * buffer array.
+// * The buffer array is not copied.
+// * The initial value of pos
+// * is 0 and the initial value
+// * of count is the length of
+// * buf.
+// *
+// * @param buf the input buffer.
+// */
+// public ByteArrayInputStream(byte buf[]) {
+// this.buf = buf;
+// this.pos = 0;
+// this.count = buf.length;
+// }
+//
+// /**
+// * Creates ByteArrayInputStream
+// * that uses buf as its
+// * buffer array. The initial value of pos
+// * is offset and the initial value
+// * of count is the minimum of offset+length
+// * and buf.length.
+// * The buffer array is not copied. The buffer's mark is
+// * set to the specified offset.
+// *
+// * @param buf the input buffer.
+// * @param offset the offset in the buffer of the first byte to read.
+// * @param length the maximum number of bytes to read from the buffer.
+// */
+// public ByteArrayInputStream(byte buf[], int offset, int length) {
+// this.buf = buf;
+// this.pos = offset;
+// this.count = Math.min(offset + length, buf.length);
+// this.mark = offset;
+// }
+//
+// /**
+// * Reads the next byte of data from this input stream. The value
+// * byte is returned as an int in the range
+// * 0 to 255. If no byte is available
+// * because the end of the stream has been reached, the value
+// * -1 is returned.
+// *
+// * This read method
+// * cannot block.
+// *
+// * @return the next byte of data, or -1 if the end of the
+// * stream has been reached.
+// */
+// public synchronized int read() {
+// return (pos < count) ? (buf[pos++] & 0xff) : -1; +// } +// +// /** +// * Reads up to len bytes of data into an array of bytes
+// * from this input stream.
+// * If pos equals count,
+// * then -1 is returned to indicate
+// * end of file. Otherwise, the number k
+// * of bytes read is equal to the smaller of
+// * len and count-pos.
+// * If k is positive, then bytes
+// * buf[pos] through buf[pos+k-1]
+// * are copied into b[off] through
+// * b[off+k-1] in the manner performed
+// * by System.arraycopy. The
+// * value k is added into pos
+// * and k is returned.
+// *
+// * This read method cannot block.
+// *
+// * @param b the buffer into which the data is read.
+// * @param off the start offset in the destination array b
+// * @param len the maximum number of bytes read.
+// * @return the total number of bytes read into the buffer, or
+// * -1 if there is no more data because the end of
+// * the stream has been reached.
+// * @exception NullPointerException If b is null.
+// * @exception IndexOutOfBoundsException If off is negative,
+// * len is negative, or len is greater than
+// * b.length - off
+// */
+// public synchronized int read(byte b[], int off, int len) {
+// if (b == null) {
+// throw new NullPointerException();
+// } else if (off < 0 || len < 0 || len> b.length - off) {
+// throw new IndexOutOfBoundsException();
+// }
+//
+// if (pos>= count) {
+// return -1;
+// }
+//
+// int avail = count - pos;
+// if (len> avail) {
+// len = avail;
+// }
+// if (len <= 0) { +// return 0; +// } +// System.arraycopy(buf, pos, b, off, len); +// pos += len; +// return len; +// } +// +// /** +// * Skips n bytes of input from this input stream. Fewer
+// * bytes might be skipped if the end of the input stream is reached.
+// * The actual number k
+// * of bytes to be skipped is equal to the smaller
+// * of n and count-pos.
+// * The value k is added into pos
+// * and k is returned.
+// *
+// * @param n the number of bytes to be skipped.
+// * @return the actual number of bytes skipped.
+// */
+// public synchronized long skip(long n) {
+// long k = count - pos;
+// if (n < k) { +// k = n < 0 ? 0 : n; +// } +// +// pos += k; +// return k; +// } +// +// /** +// * Returns the number of remaining bytes that can be read (or skipped over) +// * from this input stream. +// *
+// * The value returned is count - pos,
+// * which is the number of bytes remaining to be read from the input buffer.
+// *
+// * @return the number of remaining bytes that can be read (or skipped
+// * over) from this input stream without blocking.
+// */
+// public synchronized int available() {
+// return count - pos;
+// }
+//
+// /**
+// * Tests if this InputStream supports mark/reset. The
+// * markSupported method of ByteArrayInputStream
+// * always returns true.
+// *
+// * @since JDK1.1
+// */
+// public boolean markSupported() {
+// return true;
+// }
+//
+// /**
+// * Set the current marked position in the stream.
+// * ByteArrayInputStream objects are marked at position zero by
+// * default when constructed. They may be marked at another
+// * position within the buffer by this method.
+// *
+// * If no mark has been set, then the value of the mark is the
+// * offset passed to the constructor (or 0 if the offset was not
+// * supplied).
+// *
+// *
Note: The readAheadLimit for this class
+// * has no meaning.
+// *
+// * @since JDK1.1
+// */
+// public void mark(int readAheadLimit) {
+// mark = pos;
+// }
+//
+// /**
+// * Resets the buffer to the marked position. The marked position
+// * is 0 unless another position was marked or an offset was specified
+// * in the constructor.
+// */
+// public synchronized void reset() {
+// pos = mark;
+// }
+//
+// /**
+// * Closing a ByteArrayInputStream has no effect. The methods in
+// * this class can be called after the stream has been closed without
+// * generating an IOException.
+// *
+// */
+// public void close() throws IOException {
+// }
+//
+//}
+//
diff --git a/src/main/java/org/javacore/io/SFileInputStream.java b/src/main/java/org/javacore/io/SFileInputStream.java
new file mode 100644
index 0000000..2a898e8
--- /dev/null
+++ b/src/main/java/org/javacore/io/SFileInputStream.java
@@ -0,0 +1,184 @@
+//package org.javacore.io;
+//
+//import java.io.File;
+//import java.io.FileDescriptor;
+//import java.io.FileNotFoundException;
+//import java.io.IOException;
+//import java.io.InputStream;
+//import java.nio.channels.FileChannel;
+//
+//import sun.misc.IoTrace;
+//import sun.nio.ch.FileChannelImpl;
+//
+///**
+// * FileInputStream 从文件系统的文件中获取输入字节流。文件取决于主机系统。
+// * 比如读取图片等的原始字节流。如果读取字符流,考虑使用 FiLeReader。
+// */
+//public class SFileInputStream extends InputStream
+//{
+// /* 文件描述符类---此处用于打开文件的句柄 */
+// private final FileDescriptor fd;
+//
+// /* 引用文件的路径 */
+// private final String path;
+//
+// /* 文件通道,NIO部分 */
+// private FileChannel channel = null;
+//
+// private final Object closeLock = new Object();
+// private volatile boolean closed = false;
+//
+// private static final ThreadLocal runningFinalize =
+// new ThreadLocal();
+//
+// private static boolean isRunningFinalize() {
+// Boolean val;
+// if ((val = runningFinalize.get()) != null)
+// return val.booleanValue();
+// return false;
+// }
+//
+// /* 通过文件路径名来创建FileInputStream */
+// public FileInputStream(String name) throws FileNotFoundException {
+// this(name != null ? new File(name) : null);
+// }
+//
+// /* 通过文件来创建FileInputStream */
+// public FileInputStream(File file) throws FileNotFoundException {
+// String name = (file != null ? file.getPath() : null);
+// SecurityManager security = System.getSecurityManager();
+// if (security != null) {
+// security.checkRead(name);
+// }
+// if (name == null) {
+// throw new NullPointerException();
+// }
+// if (file.isInvalid()) {
+// throw new FileNotFoundException("Invalid file path");
+// }
+// fd = new FileDescriptor();
+// fd.incrementAndGetUseCount();
+// this.path = name;
+// open(name);
+// }
+//
+// /* 通过文件描述符类来创建FileInputStream */
+// public FileInputStream(FileDescriptor fdObj) {
+// SecurityManager security = System.getSecurityManager();
+// if (fdObj == null) {
+// throw new NullPointerException();
+// }
+// if (security != null) {
+// security.checkRead(fdObj);
+// }
+// fd = fdObj;
+// path = null;
+// fd.incrementAndGetUseCount();
+// }
+//
+// /* 打开文件,为了下一步读取文件内容。native方法 */
+// private native void open(String name) throws FileNotFoundException;
+//
+// /* 从此输入流中读取一个数据字节 */
+// public int read() throws IOException {
+// Object traceContext = IoTrace.fileReadBegin(path);
+// int b = 0;
+// try {
+// b = read0();
+// } finally {
+// IoTrace.fileReadEnd(traceContext, b == -1 ? 0 : 1);
+// }
+// return b;
+// }
+//
+// /* 从此输入流中读取一个数据字节。native方法 */
+// private native int read0() throws IOException;
+//
+// /* 从此输入流中读取多个字节到byte数组中。native方法 */
+// private native int readBytes(byte b[], int off, int len) throws IOException;
+//
+// /* 从此输入流中读取多个字节到byte数组中。 */
+// public int read(byte b[]) throws IOException {
+// Object traceContext = IoTrace.fileReadBegin(path);
+// int bytesRead = 0;
+// try {
+// bytesRead = readBytes(b, 0, b.length);
+// } finally {
+// IoTrace.fileReadEnd(traceContext, bytesRead == -1 ? 0 : bytesRead);
+// }
+// return bytesRead;
+// }
+//
+// /* 从此输入流中读取最多len个字节到byte数组中。 */
+// public int read(byte b[], int off, int len) throws IOException {
+// Object traceContext = IoTrace.fileReadBegin(path);
+// int bytesRead = 0;
+// try {
+// bytesRead = readBytes(b, off, len);
+// } finally {
+// IoTrace.fileReadEnd(traceContext, bytesRead == -1 ? 0 : bytesRead);
+// }
+// return bytesRead;
+// }
+//
+//
+// public native long skip(long n) throws IOException;
+//
+// /* 返回下一次对此输入流调用的方法可以不受阻塞地从此输入流读取(或跳过)的估计剩余字节数。 */
+// public native int available() throws IOException;
+//
+// /* 关闭此文件输入流并释放与此流有关的所有系统资源。 */
+// public void close() throws IOException {
+// synchronized (closeLock) {
+// if (closed) {
+// return;
+// }
+// closed = true;
+// }
+// if (channel != null) {
+// fd.decrementAndGetUseCount();
+// channel.close();
+// }
+//
+// int useCount = fd.decrementAndGetUseCount();
+//
+// if ((useCount <= 0) || !isRunningFinalize()) { +// close0(); +// } +// } +// +// public final FileDescriptor getFD() throws IOException { +// if (fd != null) return fd; +// throw new IOException(); +// } +// +// /* 获取此文件输入流的唯一FileChannel对象 */ +// public FileChannel getChannel() { +// synchronized (this) { +// if (channel == null) { +// channel = FileChannelImpl.open(fd, path, true, false, this); +// fd.incrementAndGetUseCount(); +// } +// return channel; +// } +// } +// +// private static native void initIDs(); +// +// private native void close0() throws IOException; +// +// static { +// initIDs(); +// } +// +// protected void finalize() throws IOException { +// if ((fd != null) && (fd != FileDescriptor.in)) { +// runningFinalize.set(Boolean.TRUE); +// try { +// close(); +// } finally { +// runningFinalize.set(Boolean.FALSE); +// } +// } +// } +//} \ No newline at end of file diff --git a/src/main/java/org/javacore/io/SFileOutputStream.java b/src/main/java/org/javacore/io/SFileOutputStream.java new file mode 100644 index 0000000..b88aa99 --- /dev/null +++ b/src/main/java/org/javacore/io/SFileOutputStream.java @@ -0,0 +1,206 @@ +//package org.javacore.io; +// +//import java.io.File; +//import java.io.FileDescriptor; +//import java.io.FileNotFoundException; +//import java.io.IOException; +//import java.io.OutputStream; +//import java.nio.channels.FileChannel; +// +//import sun.misc.IoTrace; +//import sun.nio.ch.FileChannelImpl; +// +///** +// * 文件输入流是用于将数据写入文件或者文件描述符类 +// * 比如写入图片等的原始字节流。如果写入字符流,考虑使用 FiLeWriter。 +// */ +//public class SFileOutputStream extends OutputStream +//{ +// /* 文件描述符类---此处用于打开文件的句柄 */ +// private final FileDescriptor fd; +// +// /* 引用文件的路径 */ +// private final String path; +// +// /* 如果为 true,则将字节写入文件末尾处,而不是写入文件开始处 */ +// private final boolean append; +// +// /* 关联的FileChannel类,懒加载 */ +// private FileChannel channel; +// +// private final Object closeLock = new Object(); +// private volatile boolean closed = false; +// private static final ThreadLocal runningFinalize =
+// new ThreadLocal();
+//
+// private static boolean isRunningFinalize() {
+// Boolean val;
+// if ((val = runningFinalize.get()) != null)
+// return val.booleanValue();
+// return false;
+// }
+//
+// /* 通过文件名创建文件输入流 */
+// public FileOutputStream(String name) throws FileNotFoundException {
+// this(name != null ? new File(name) : null, false);
+// }
+//
+// /* 通过文件名创建文件输入流,并确定文件写入起始处模式 */
+// public FileOutputStream(String name, boolean append)
+// throws FileNotFoundException
+// {
+// this(name != null ? new File(name) : null, append);
+// }
+//
+// /* 通过文件创建文件输入流,默认写入文件的开始处 */
+// public FileOutputStream(File file) throws FileNotFoundException {
+// this(file, false);
+// }
+//
+// /* 通过文件创建文件输入流,并确定文件写入起始处 */
+// public FileOutputStream(File file, boolean append)
+// throws FileNotFoundException
+// {
+// String name = (file != null ? file.getPath() : null);
+// SecurityManager security = System.getSecurityManager();
+// if (security != null) {
+// security.checkWrite(name);
+// }
+// if (name == null) {
+// throw new NullPointerException();
+// }
+// if (file.isInvalid()) {
+// throw new FileNotFoundException("Invalid file path");
+// }
+// this.fd = new FileDescriptor();
+// this.append = append;
+// this.path = name;
+// fd.incrementAndGetUseCount();
+// open(name, append);
+// }
+//
+// /* 通过文件描述符类创建文件输入流 */
+// public FileOutputStream(FileDescriptor fdObj) {
+// SecurityManager security = System.getSecurityManager();
+// if (fdObj == null) {
+// throw new NullPointerException();
+// }
+// if (security != null) {
+// security.checkWrite(fdObj);
+// }
+// this.fd = fdObj;
+// this.path = null;
+// this.append = false;
+//
+// fd.incrementAndGetUseCount();
+// }
+//
+// /* 打开文件,并确定文件写入起始处模式 */
+// private native void open(String name, boolean append)
+// throws FileNotFoundException;
+//
+// /* 将指定的字节b写入到该文件输入流,并指定文件写入起始处模式 */
+// private native void write(int b, boolean append) throws IOException;
+//
+// /* 将指定的字节b写入到该文件输入流 */
+// public void write(int b) throws IOException {
+// Object traceContext = IoTrace.fileWriteBegin(path);
+// int bytesWritten = 0;
+// try {
+// write(b, append);
+// bytesWritten = 1;
+// } finally {
+// IoTrace.fileWriteEnd(traceContext, bytesWritten);
+// }
+// }
+//
+// /* 将指定的字节数组写入该文件输入流,并指定文件写入起始处模式 */
+// private native void writeBytes(byte b[], int off, int len, boolean append)
+// throws IOException;
+//
+// /* 将指定的字节数组b写入该文件输入流 */
+// public void write(byte b[]) throws IOException {
+// Object traceContext = IoTrace.fileWriteBegin(path);
+// int bytesWritten = 0;
+// try {
+// writeBytes(b, 0, b.length, append);
+// bytesWritten = b.length;
+// } finally {
+// IoTrace.fileWriteEnd(traceContext, bytesWritten);
+// }
+// }
+//
+// /* 将指定len长度的字节数组b写入该文件输入流 */
+// public void write(byte b[], int off, int len) throws IOException {
+// Object traceContext = IoTrace.fileWriteBegin(path);
+// int bytesWritten = 0;
+// try {
+// writeBytes(b, off, len, append);
+// bytesWritten = len;
+// } finally {
+// IoTrace.fileWriteEnd(traceContext, bytesWritten);
+// }
+// }
+//
+// /* 关闭此文件输出流并释放与此流有关的所有系统资源 */
+// public void close() throws IOException {
+// synchronized (closeLock) {
+// if (closed) {
+// return;
+// }
+// closed = true;
+// }
+//
+// if (channel != null) {
+// fd.decrementAndGetUseCount();
+// channel.close();
+// }
+//
+// int useCount = fd.decrementAndGetUseCount();
+//
+// if ((useCount <= 0) || !isRunningFinalize()) { +// close0(); +// } +// } +// +// public final FileDescriptor getFD() throws IOException { +// if (fd != null) return fd; +// throw new IOException(); +// } +// +// public FileChannel getChannel() { +// synchronized (this) { +// if (channel == null) { +// channel = FileChannelImpl.open(fd, path, false, true, append, this); +// +// fd.incrementAndGetUseCount(); +// } +// return channel; +// } +// } +// +// protected void finalize() throws IOException { +// if (fd != null) { +// if (fd == FileDescriptor.out || fd == FileDescriptor.err) { +// flush(); +// } else { +// +// runningFinalize.set(Boolean.TRUE); +// try { +// close(); +// } finally { +// runningFinalize.set(Boolean.FALSE); +// } +// } +// } +// } +// +// private native void close0() throws IOException; +// +// private static native void initIDs(); +// +// static { +// initIDs(); +// } +// +//} \ No newline at end of file diff --git a/src/main/java/org/javacore/io/SInputStream.java b/src/main/java/org/javacore/io/SInputStream.java new file mode 100644 index 0000000..361b6f6 --- /dev/null +++ b/src/main/java/org/javacore/io/SInputStream.java @@ -0,0 +1,95 @@ +package org.javacore.io; + +import java.io.IOException; + +/** + * 所有字节输入流实现类的基类 + */ +public abstract class SInputStream { + + // 缓存区字节数组最大值 + private static final int MAX_SKIP_BUFFER_SIZE = 2048; + + // 从输入流中读取数据的下一个字节,以int返回 + public abstract int read() throws IOException; + + // 从输入流中读取数据的一定数量字节,并存储在缓存数组b + public int read(byte b[]) throws IOException { + return read(b, 0, b.length); + } + + // 从输入流中读取数据最多len个字节,并存储在缓存数组b + public int read(byte b[], int off, int len) throws IOException { + if (b == null) { + throw new NullPointerException(); + } else if (off < 0 || len < 0 || len> b.length - off) {
+ throw new IndexOutOfBoundsException();
+ } else if (len == 0) {
+ return 0;
+ }
+
+ int c = read();
+ if (c == -1) {
+ return -1;
+ }
+ b[off] = (byte)c;
+
+ int i = 1;
+ try {
+ for (; i < len ; i++) { + c = read(); + if (c == -1) { + break; + } + b[off + i] = (byte)c; + } + } catch (IOException ee) { + } + return i; + } + + // 跳过输入流中数据的n个字节 + public long skip(long n) throws IOException { + + long remaining = n; + int nr; + + if (n <= 0) { + return 0; + } + + int size = (int)Math.min(MAX_SKIP_BUFFER_SIZE, remaining); + byte[] skipBuffer = new byte[size]; + while (remaining> 0) {
+ nr = read(skipBuffer, 0, (int)Math.min(size, remaining));
+ if (nr < 0) { + break; + } + remaining -= nr; + } + + return n - remaining; + } + + // 返回下一个方法调用能不受阻塞地从此读取(或者跳过)的估计字节数 + public int available() throws IOException { + return 0; + } + + // 关闭此输入流,并释放与其关联的所有资源 + public void close() throws IOException {} + + // 在此输出流中标记当前位置 + public synchronized void mark(int readlimit) {} + + // 将此流重新定位到最后一次对此输入流调用 mark 方法时的位置。 + public synchronized void reset() throws IOException { + throw new IOException("mark/reset not supported"); + } + + // 测试此输入流是否支持 mark 和 reset 方法 + public boolean markSupported() { + return false; + } + +} diff --git a/src/main/java/org/javacore/io/SOutputStream.java b/src/main/java/org/javacore/io/SOutputStream.java new file mode 100644 index 0000000..c254818 --- /dev/null +++ b/src/main/java/org/javacore/io/SOutputStream.java @@ -0,0 +1,43 @@ +package org.javacore.io; + +import java.io.Closeable; +import java.io.Flushable; +import java.io.IOException; + +/** + * 所有字节输出流实现类的基类 + */ +public abstract class SOutputStream implements Closeable, Flushable { + + // 将指定的字节写入输出流 + public abstract void write(int b) throws IOException; + + // 将指定的byte数组的字节全部写入输出流 + public void write(byte b[]) throws IOException { + write(b, 0, b.length); + } + + // 将指定的byte数组中从偏移量off开始的len个字节写入输出流 + public void write(byte b[], int off, int len) throws IOException { + if (b == null) { + throw new NullPointerException(); + } else if ((off < 0) || (off> b.length) || (len < 0) || + ((off + len)> b.length) || ((off + len) < 0)) { + throw new IndexOutOfBoundsException(); + } else if (len == 0) { + return; + } + for (int i = 0 ; i < len ; i++) { + write(b[off + i]); + } + } + + // 刷新输出流,并强制写出所有缓冲的输出字节 + public void flush() throws IOException { + } + + // 关闭输出流,并释放与该流有关的所有资源 + public void close() throws IOException { + } + +} \ No newline at end of file diff --git a/src/main/java/org/javacore/io/StoringAndRecoveringData.java b/src/main/java/org/javacore/io/StoringAndRecoveringData.java new file mode 100644 index 0000000..9773592 --- /dev/null +++ b/src/main/java/org/javacore/io/StoringAndRecoveringData.java @@ -0,0 +1,51 @@ +package org.javacore.io; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; + +/* + * Copyright [2015] [Jeff Lee] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author Jeff Lee + * @since 2015-9-28 17:30:21 + * DataOutputStream和DataInputStream的使用案例 + */ +public class StoringAndRecoveringData { + + @SuppressWarnings("resource") + public static void main(String[] args) throws IOException { + // 写入数据 + DataOutputStream outputStream = new DataOutputStream( + new BufferedOutputStream(new FileOutputStream("data.txt"))); + outputStream.writeDouble(3.1415926); + outputStream.writeUTF("你好"); + outputStream.writeInt(1); + outputStream.close(); + + // 写出数据 + DataInputStream inputStream = new DataInputStream( + new BufferedInputStream(new FileInputStream("data.txt"))); + System.out.println(inputStream.readDouble()); + System.out.println(inputStream.readUTF()); + System.out.println(inputStream.readInt()); + } +} diff --git a/src/main/java/org/javacore/io/SystemStreamT.java b/src/main/java/org/javacore/io/SystemStreamT.java new file mode 100644 index 0000000..b1a2675 --- /dev/null +++ b/src/main/java/org/javacore/io/SystemStreamT.java @@ -0,0 +1,47 @@ +package org.javacore.io; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintStream; +/* + * Copyright [2015] [Jeff Lee] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author Jeff Lee + * @since 2015-7-31 11:04:26 + * System.out, System.err中IO的使用 + * 替换系统流,输出至文本 + */ +public class SystemStreamT { + public static void main(String[] args) throws IOException { + // 创建文件输出流 + OutputStream out = new FileOutputStream("D:\\data\\console.txt"); + // 创建新的文件输出打印流 + PrintStream print = new PrintStream(out); + // 设置标准输出流 + System.setOut(print); + // 设置标准错误输出流 + System.setErr(print); + + System.out.println("Hello,System.out"); + System.err.println("Hello,System.err"); + + // 关闭流 + print.close(); + out.close(); + } +} diff --git a/src/main/java/org/javacore/io/TextFile.java b/src/main/java/org/javacore/io/TextFile.java new file mode 100644 index 0000000..bffa307 --- /dev/null +++ b/src/main/java/org/javacore/io/TextFile.java @@ -0,0 +1,120 @@ +package org.javacore.io; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.TreeSet; + +/* + * Copyright [2015] [Jeff Lee] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author Jeff Lee + * @since 2015-9-30 16:10:18 + * 文本文件的操作案例 + */ +public class TextFile extends ArrayList {
+
+ private static final long serialVersionUID = -6710557138987846943L;
+
+ // 读取文件内容,返回内容字符串
+ public static String read(String fileName) {
+ StringBuilder sb = new StringBuilder();
+ try {
+ // 创建缓存字符输入流
+ BufferedReader in = new BufferedReader(new FileReader(// 创建读取字符文件类
+ new File(fileName).getAbsolutePath()));// 文件绝对路径地址
+ try {
+ String s;
+ // 读取一个文本行
+ while ((s = in.readLine()) != null) {
+ sb.append(s);
+ sb.append("\n");
+ }
+ } finally {
+ in.close();
+ }
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ return sb.toString();
+ }
+
+ // 将字符串写入一个文本文件
+ public static void write(String fileName,String text) {
+ try {
+ // 创建打印输出流
+ PrintWriter out = new PrintWriter(
+ new File(fileName).getAbsolutePath());
+ try {
+ // 写入字符流
+ out.write(text);
+ } finally {
+ out.close();
+ }
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ // 通过正则匹配,读取文件
+ public TextFile(String fileName,String splitter) {
+ super(Arrays.asList(read(fileName).split(splitter)));
+ // 移除一个空格位置
+ if (get(0).equals("")) remove(0);
+ }
+
+ public TextFile(String fileName) {
+ this(fileName, "\n");
+ }
+
+ // 写入一个文本文件
+ public void write(String fileName) {
+ try {
+ // 创建打印输出流
+ PrintWriter out = new PrintWriter(
+ new File(fileName).getAbsolutePath());
+ try {
+ for (String item : this)
+ out.write(item);
+ } finally {
+ out.close();
+ }
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+
+ }
+
+ public static void main(String[] args) {
+ // 读取文件
+ String file = read("src/org/javacore/io/TextFile.java");
+ // 写入到test.txt
+ write("test.txt", file);
+
+ TextFile text = new TextFile("test.txt");
+ text.write("test2.txt");
+
+ TreeSet words = new TreeSet(
+ new TextFile("src/org/javacore/io/TextFile.java","\\W+"));
+ System.out.println(words.headSet("a"));
+
+ }
+}
diff --git a/src/main/java/org/javacore/io/UsingRandomAccessFile.java b/src/main/java/org/javacore/io/UsingRandomAccessFile.java
new file mode 100644
index 0000000..2f78e42
--- /dev/null
+++ b/src/main/java/org/javacore/io/UsingRandomAccessFile.java
@@ -0,0 +1,57 @@
+package org.javacore.io;
+
+import java.io.IOException;
+import java.io.RandomAccessFile;
+
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年9月28日 18:50:22
+ * RandomAccessFile的使用案例
+ */
+public class UsingRandomAccessFile {
+ // 文件名
+ static String file = "rtest.bat";
+
+ static void display() throws IOException {
+ // 创建随机访问类,只读模式
+ RandomAccessFile rf = new RandomAccessFile(file, "r");
+ for (int i = 0; i < 7; i++) + System.out.println("Value " + i + ": " + rf.readDouble());// 读取一个Double + System.out.println(rf.readUTF());// 读取一个字符串 + rf.close(); + } + + public static void main(String[] args) throws IOException { + // 创建随机访问类,读写模式 + RandomAccessFile rf = new RandomAccessFile(file, "rw"); + for (int i = 0; i < 7; i++) + rf.writeDouble( i * 1.123);// 写入一个Double + rf.writeUTF("文件结束");// 写入一个字符串 + rf.close(); + + display(); + + rf = new RandomAccessFile(file, "rw"); + rf.seek(5 * 8);// 设置文件指针偏移量,设置到第5个双精度字节 + rf.writeDouble(47.003); + rf.close(); + + display(); + } +} diff --git a/src/main/java/org/javacore/io/byteoper/IntegerConvertT.java b/src/main/java/org/javacore/io/byteoper/IntegerConvertT.java new file mode 100644 index 0000000..2a754a3 --- /dev/null +++ b/src/main/java/org/javacore/io/byteoper/IntegerConvertT.java @@ -0,0 +1,57 @@ +package org.javacore.io.byteoper; + +/* + * Copyright [2015] [Jeff Lee] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author Jeff Lee + * @since 2015-6-19 21:26:09 + * Integer与byte数组转换 + */ +public class IntegerConvertT { + + public static void main(String[] args){ + // 将我的学号转换成字节码 + byte[] bytes = IntegerConvertT.int2Bytes(1206010035); + System.out.println(bytes[0] + " " + bytes[1] + " " + bytes[2] + " " + bytes[3]); + // 字节码就可以转换回学号 + System.out.println(IntegerConvertT.bytes2Int(bytes)); + } + + /** + * Int转字节数组 + */ + public static byte[] int2Bytes(int inta){ + // 32位Int可存于长度为4的字节数组 + byte[] bytes = new byte[4]; + for (int i = 0; i < bytes.length; i++) + bytes[i] = (byte)(int)((inta>> i * 8) & 0xff);// 移位和清零
+
+ return bytes;
+ }
+
+ /**
+ * 字节数组转Int
+ */
+ public static int bytes2Int(byte[] bytes){
+ int inta = 0;
+ for (int i = 0; i < bytes.length; i++) + inta += (int)((bytes[i] & 0xff) << i * 8);// 移位和清零 + + return inta; + } + +} diff --git a/src/main/java/org/javacore/io/byteoper/IntegerOperT.java b/src/main/java/org/javacore/io/byteoper/IntegerOperT.java new file mode 100644 index 0000000..422e829 --- /dev/null +++ b/src/main/java/org/javacore/io/byteoper/IntegerOperT.java @@ -0,0 +1,35 @@ +package org.javacore.io.byteoper; +/* + * Copyright [2015] [Jeff Lee] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author Jeff Lee + * @since 2015-6-19 21:25:57 + * Integer类的进制转换 + */ +public class IntegerOperT { + + public static void main(String[] args) { + System.out.println("17的十六进制: " + Integer.toHexString(17)); + System.out.println("17的八进制: " + Integer.toOctalString(17)); + System.out.println("17的二进制: " + Integer.toBinaryString(17)); + + System.out.println(Integer.valueOf("11", 16)); + System.out.println(Integer.valueOf("21", 8)); + System.out.println(Integer.valueOf("00010001", 2)); + } + +} diff --git a/src/main/java/org/javacore/io/byteoper/LongConvertT.java b/src/main/java/org/javacore/io/byteoper/LongConvertT.java new file mode 100644 index 0000000..4796f11 --- /dev/null +++ b/src/main/java/org/javacore/io/byteoper/LongConvertT.java @@ -0,0 +1,46 @@ +package org.javacore.io.byteoper; +/* + * Copyright [2015] [Jeff Lee] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author Jeff Lee + * @since 2015-6-19 21:26:04 + * Long与byte数组转换 + */ +public class LongConvertT { + + /** + * long 转 byte数组 + */ + public static byte[] long2Bytes(long longa){ + byte[] bytes = new byte[8]; + for (int i = 0; i < bytes.length; i++) + bytes[i] = (byte)(long)(((longa)>> i * 8) & 0xff); // 移位和清零
+
+ return bytes;
+ }
+
+ /**
+ * byte数组 转 long
+ */
+ public static long bytes2Long(byte[] bytes){
+ long longa = 0;
+ for (int i = 0; i < bytes.length; i++) + longa += (long)((bytes[i] & 0xff) << i * 8); // 移位和清零 + + return longa; + } +} diff --git a/src/main/java/org/javacore/io/byteoper/StringConvertT.java b/src/main/java/org/javacore/io/byteoper/StringConvertT.java new file mode 100644 index 0000000..a8189f8 --- /dev/null +++ b/src/main/java/org/javacore/io/byteoper/StringConvertT.java @@ -0,0 +1,33 @@ +package org.javacore.io.byteoper; +/* + * Copyright [2015] [Jeff Lee] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author Jeff Lee + * @since 2015-6-19 21:27:41 + * String转换成byte数组 + */ +public class StringConvertT { + + public static void main(String[] args){ + String str = "李强强"; + byte[] bytes = str.getBytes(); + // 打印字节数组 + System.out.println("UTF-8编码'李强强'的字节数组为:"); + for (int i = 0; i < bytes.length; i++) + System.out.print("\t" + bytes[i]); + } +} diff --git a/src/main/java/org/javacore/io/serializable/SerializableT.java b/src/main/java/org/javacore/io/serializable/SerializableT.java new file mode 100644 index 0000000..31b8be4 --- /dev/null +++ b/src/main/java/org/javacore/io/serializable/SerializableT.java @@ -0,0 +1,60 @@ +package org.javacore.io.serializable; + + +import com.sun.xml.internal.messaging.saaj.util.ByteOutputStream; + +import java.io.*; + +/** + * 描述:Java序列化和反序列化的小例子 + * Created by 子木 on 2016/2/15. + */ +public class SerializableT { + public static void main(String[] args) throws IOException, ClassNotFoundException { + for (int i = 0;i < 10;i++) { + AObjcet aObjcet = new AObjcet(); + long beginTime = System.currentTimeMillis(); + + ByteOutputStream byteOutput = new ByteOutputStream(); + ObjectOutputStream objectOutput = new ObjectOutputStream(byteOutput); + objectOutput.writeObject(aObjcet); + objectOutput.close(); + byteOutput.close(); + byte[] bytes = byteOutput.toByteArray(); + System.out.println("Java序列化耗时:" + (System.currentTimeMillis() - beginTime) + "ms"); + System.out.println("Java序列化后的字节大小为:" + bytes.length); + + beginTime = System.currentTimeMillis(); + ByteArrayInputStream byteInput = new ByteArrayInputStream(bytes); + ObjectInputStream objectInput = new ObjectInputStream(byteInput); + objectInput.readObject(); + objectInput.close(); + byteInput.close(); + System.out.println("Java反序列化耗时:" + (System.currentTimeMillis() - beginTime) + "ms"); + + } + } +} +class AObjcet implements Serializable { + private String a = "bysocket"; + private String b = "likes"; + private String c = "java"; + private String d = "world"; + + private int i = 100; + private int j = 10; + private long m = 100L; + + private boolean isA = true; + private boolean isB = false; + private boolean isC = false; + + private BObject aObject = new BObject(); + private BObject bObject = new BObject(); + private BObject cObject = new BObject(); + private BObject dObject = new BObject(); + +} +class BObject implements Serializable { + +} diff --git a/src/main/java/org/javacore/io/zip/GZIPcompress.java b/src/main/java/org/javacore/io/zip/GZIPcompress.java new file mode 100644 index 0000000..b446c58 --- /dev/null +++ b/src/main/java/org/javacore/io/zip/GZIPcompress.java @@ -0,0 +1,60 @@ +package org.javacore.io.zip; + +import java.io.BufferedOutputStream; +import java.io.BufferedReader; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.zip.GZIPInputStream; +import java.util.zip.GZIPOutputStream; + +/* + * Copyright [2015] [Jeff Lee] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author Jeff Lee + * @since 2015-10-17 13:59:25 + * GZIP简单使用 + */ +public class GZIPcompress { + public static void main(String[] args) throws IOException { + // 用Reader读文件 + BufferedReader in = new BufferedReader(new InputStreamReader( + new FileInputStream("data.gz" ), "UTF-8" )); + // 使用缓冲输出流,输出压缩流文件 + BufferedOutputStream out = new BufferedOutputStream( + new GZIPOutputStream(new FileOutputStream("data.gz"))); + System.out.println("Writing File 压缩"); + int c; + while ((c = in.read())> 0)
+ out.write(String.valueOf((char)c).getBytes("UTF-8"));
+ in.close();
+ out.close();
+
+ System.out.println("Reading File 解压");
+ // 用输入解压流读取文件
+ BufferedReader in2 = new BufferedReader(
+ new InputStreamReader(
+ new GZIPInputStream(new FileInputStream("data.gz")),"UTF-8"));// encoding question
+ String s;
+ while ((s=in2.readLine()) != null)
+ System.out.println(s);
+ in2.close();
+ }
+}
diff --git a/src/main/java/org/javacore/io/zip/ZipCompress.java b/src/main/java/org/javacore/io/zip/ZipCompress.java
new file mode 100644
index 0000000..d0a6e61
--- /dev/null
+++ b/src/main/java/org/javacore/io/zip/ZipCompress.java
@@ -0,0 +1,120 @@
+package org.javacore.io.zip;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.zip.Adler32;
+import java.util.zip.CheckedInputStream;
+import java.util.zip.CheckedOutputStream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import java.util.zip.ZipInputStream;
+import java.util.zip.ZipOutputStream;
+
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年10月17日 14:58:59
+ * 利用Zip进行多文件保存
+ */
+public class ZipCompress {
+ private static String filePath = "src" + File.separator +
+ "org" + File.separator +
+ "javacore" + File.separator +
+ "io" + File.separator;
+
+ private static String[] fileNames= new String[] {
+ filePath + "BufferedInputFileT.java",
+ filePath + "ChangeSystemOut.java"
+ };
+
+ public static void main(String[] args) throws IOException {
+ zipFiles(fileNames);
+ }
+
+ private static void zipFiles(String[] fileNames)
+ throws IOException {
+ // 获取zip文件输出流
+ FileOutputStream f = new FileOutputStream("test.zip");
+ // 从文件输出流中获取数据校验和输出流,并设置Adler32
+ CheckedOutputStream csum = new CheckedOutputStream(f,new Adler32());
+ // 从数据校验和输出流中获取Zip输出流
+ ZipOutputStream zos = new ZipOutputStream(csum);
+ // 从Zip输出流中获取缓冲输出流
+ BufferedOutputStream out = new BufferedOutputStream(zos);
+ // 设置Zip文件注释
+ zos.setComment("测试 java zip stream");
+ for (String file : fileNames) {
+ System.out.println("写入文件: " + file);
+ // 获取文件输入字符流
+ BufferedReader in =
+ new BufferedReader(new FileReader(file));
+ // 想Zip处理写入新的文件条目,并流定位到数据开始处
+ zos.putNextEntry(new ZipEntry(file));
+ int c;
+ while ((c = in.read())> 0)
+ out.write(c);
+ in.close();
+ // 刷新Zip输出流,将缓冲的流写入该流
+ out.flush();
+ }
+ // 文件全部写入Zip输出流后,关闭
+ out.close();
+
+ // 输出数据校验和
+ System.out.println("数据校验和: " + csum.getChecksum().getValue());
+ System.out.println("读取zip文件");
+ // 读取test.zip文件输入流
+ FileInputStream fi = new FileInputStream("test.zip");
+ // 从文件输入流中获取数据校验和流
+ CheckedInputStream csumi = new CheckedInputStream(fi,new Adler32());
+ // 从数据校验和流中获取Zip解压流
+ ZipInputStream in2 = new ZipInputStream(csumi);
+ // 从Zip解压流中获取缓冲输入流
+ BufferedInputStream bis = new BufferedInputStream(in2);
+ // 创建文件条目
+ ZipEntry zipEntry;
+ while ((zipEntry = in2.getNextEntry()) != null) {
+ System.out.println("读取文件: " + zipEntry);
+ int x;
+ while ((x = bis.read())> 0)
+ System.out.write(x);
+ }
+ if (fileNames.length == 1)
+ System.out.println("数据校验和: " + csumi.getChecksum().getValue());
+ bis.close();
+
+ // 获取Zip文件
+ ZipFile zf = new ZipFile("test.zip");
+ // 获取文件条目枚举
+ Enumeration e = zf.entries();
+ while (e.hasMoreElements()) {
+ // 从Zip文件的枚举中获取文件条目
+ ZipEntry ze2 = (ZipEntry) e.nextElement();
+ System.out.println("文件: " + ze2);
+ }
+
+ }
+}
diff --git a/src/main/java/org/javacore/nio/AvailableCharSets.java b/src/main/java/org/javacore/nio/AvailableCharSets.java
new file mode 100644
index 0000000..9bdb9a3
--- /dev/null
+++ b/src/main/java/org/javacore/nio/AvailableCharSets.java
@@ -0,0 +1,51 @@
+package org.javacore.nio;
+
+import java.nio.charset.Charset;
+import java.util.Iterator;
+import java.util.SortedMap;
+
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年10月11日 19:51:10
+ * 可用的CharSet打印
+ */
+public class AvailableCharSets {
+ public static void main(String[] args) {
+ // charset对象的有序映射
+ SortedMap charSets =
+ Charset.availableCharsets();
+ // 获取key的迭代器
+ Iterator iterator = charSets.keySet().iterator();
+ while (iterator.hasNext()) {
+ String csName = iterator.next();
+ System.out.print(csName);
+ // 获取别名的Charset集合的迭代器
+ Iterator aliases =
+ charSets.get(csName).aliases().iterator();
+ if (aliases.hasNext())
+ System.out.print(": ");
+ while (aliases.hasNext()) {
+ System.out.print(aliases.next());
+ if (aliases.hasNext())
+ System.out.print(",");
+ }
+ System.out.println();
+ }
+ }
+}
diff --git a/src/main/java/org/javacore/nio/BufferToText.java b/src/main/java/org/javacore/nio/BufferToText.java
new file mode 100644
index 0000000..7e7554d
--- /dev/null
+++ b/src/main/java/org/javacore/nio/BufferToText.java
@@ -0,0 +1,101 @@
+package org.javacore.nio;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.charset.Charset;
+
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年10月10日 18:58:15
+ * ByteBuffer与char之间转换的案例
+ */
+public class BufferToText {
+ private static final int BSIZE = 1024; // 1K 字节
+ public static void main(String[] args) throws IOException {
+ // 从文件输出流获取FileChannel
+ FileChannel fc =
+ new FileOutputStream("data.txt").getChannel();
+ // 将带有字节的缓冲区写入该通道
+ fc.write(ByteBuffer.wrap("some data".getBytes()));
+ fc.close();
+
+ // 从文件输入流中获取FileChannel
+ fc = new FileInputStream("data.txt").getChannel();
+ // 分配ByteBuffer的大小 1K
+ ByteBuffer buffer = ByteBuffer.allocate(BSIZE);
+ // 将字节序列通过此通道写入到buffer
+ fc.read(buffer);
+ // 反转缓冲区,为写或者读取做准备
+ buffer.flip();
+ // 作为char缓冲区,并输出 乱码,因为Buffer编码是"UTF-16BE"
+ System.out.println(buffer.asCharBuffer());
+
+ // 重绕此缓冲区
+ buffer.rewind();
+ // 获取文件编码属性
+ String encoding = System.getProperty("file.encoding");
+ // 输出编码及内容
+ System.out.println("编码: " + encoding + " 内容为: "
+ + Charset.forName(encoding).decode(buffer));
+ fc.close();
+
+ // 从文件输出流获取FileChannel
+ fc = new FileOutputStream("data.txt").getChannel();
+ // 将带有字节的缓冲区写入该通道
+ fc.write(ByteBuffer.wrap("some data".getBytes("UTF-16BE")));
+ fc.close();
+
+ // 从文件输入流中获取FileChannel
+ fc = new FileInputStream("data.txt").getChannel();
+ // 清除其缓冲区
+ buffer.clear();
+ // 将字节序列通过该通道写入到buffer
+ fc.read(buffer);
+ // 反转缓冲区,为写或者读取做准备
+ buffer.flip();
+ // 作为char缓冲区,并输出
+ System.out.println(buffer.asCharBuffer());
+ fc.close();
+
+ // 从文件输出流获取FileChannel
+ fc = new FileOutputStream("data.txt").getChannel();
+ // 指定buffer大小为 24字节
+ buffer = ByteBuffer.allocate(24);
+ // 通过char缓冲区,在当前位置写入字符
+ buffer.asCharBuffer().put("some data");
+ // 将带有字节的缓冲区写入该通道
+ fc.write(buffer);
+ fc.close();
+
+ // 从文件输入流中获取FileChannel
+ fc = new FileInputStream("data.txt").getChannel();
+ // 清除缓冲区
+ buffer.clear();
+ // 将字节序列通过文件通道写入到buffer
+ fc.read(buffer);
+ // 反转缓冲区,为读或者写做准备
+ buffer.flip();
+ // 作为char缓冲区,并输出
+ System.out.println(buffer.asCharBuffer());
+ }
+}
diff --git a/src/main/java/org/javacore/nio/ChannelCopy.java b/src/main/java/org/javacore/nio/ChannelCopy.java
new file mode 100644
index 0000000..a6a1685
--- /dev/null
+++ b/src/main/java/org/javacore/nio/ChannelCopy.java
@@ -0,0 +1,63 @@
+package org.javacore.nio;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年10月9日 17:38:08
+ * FileChannel的文件复制案例
+ */
+public class ChannelCopy {
+ // 读取的文件
+ private static final String sourceFile =
+ "src" + File.separator +
+ "org" + File.separator +
+ "javacore" + File.separator +
+ "nio" + File.separator +
+ "ChannelCopy.java";
+ // 输出的文件
+ private static final String targetFile = "data.txt";
+
+ private static final int BSIZE = 1024; // 1K字节
+
+ @SuppressWarnings("resource")
+ public static void main(String[] args) throws IOException {
+ // 创建用于读写的Channel
+ FileChannel
+ in = new FileInputStream(sourceFile).getChannel(),
+ out = new FileOutputStream(targetFile).getChannel();
+
+ // 分配ByteBuffer的大小 1K
+ ByteBuffer buffer = ByteBuffer.allocate(BSIZE);
+ // 将字节序列从此通道读入给定的缓冲区,分块读,直至读到文件末端
+ while (in.read(buffer) != -1) {// -1,表示读到文件末端
+ // 反转缓冲区,为写入或读取做好准备
+ buffer.flip();
+ // 将含有字节序列的缓冲区写入文件通道
+ out.write(buffer);
+ // 清空缓冲区
+ buffer.clear();
+ }
+
+ }
+}
diff --git a/src/main/java/org/javacore/nio/Endians.java b/src/main/java/org/javacore/nio/Endians.java
new file mode 100644
index 0000000..712e77b
--- /dev/null
+++ b/src/main/java/org/javacore/nio/Endians.java
@@ -0,0 +1,50 @@
+package org.javacore.nio;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.Arrays;
+
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年10月13日 20:40:00
+ * ByteBuffer中字节存储次序
+ */
+public class Endians {
+ public static void main(String[] args) {
+ // 创建12个字节的字节缓冲区
+ ByteBuffer bb = ByteBuffer.wrap(new byte[12]);
+ // 存入字符串
+ bb.asCharBuffer().put("abdcef");
+ System.out.println(Arrays.toString(bb.array()));
+
+ // 反转缓冲区
+ bb.rewind();
+ // 设置字节存储次序
+ bb.order(ByteOrder.BIG_ENDIAN);
+ bb.asCharBuffer().put("abcdef");
+ System.out.println(Arrays.toString(bb.array()));
+
+ // 反转缓冲区
+ bb.rewind();
+ // 设置字节存储次序
+ bb.order(ByteOrder.LITTLE_ENDIAN);
+ bb.asCharBuffer().put("abcdef");
+ System.out.println(Arrays.toString(bb.array()));
+ }
+}
diff --git a/src/main/java/org/javacore/nio/FileChannelT.java b/src/main/java/org/javacore/nio/FileChannelT.java
new file mode 100644
index 0000000..325b2c4
--- /dev/null
+++ b/src/main/java/org/javacore/nio/FileChannelT.java
@@ -0,0 +1,75 @@
+package org.javacore.nio;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年7月23日 17:50:18
+ * FileChannel读写文件案例
+ */
+public class FileChannelT {
+
+ @SuppressWarnings("resource")
+ public static void main(String[] args) throws IOException {
+ // NIO包路径
+ String dir = "src" + File.separator +
+ "org" + File.separator +
+ "javacore" + File.separator +
+ "nio";
+ // 获取FileChannelT.java文件,读写方式
+ RandomAccessFile inFile = new RandomAccessFile(dir + File.separator +
+ "FileChannelT.java","rw");
+ // 创建输出文件流
+ FileOutputStream outFileStream = new FileOutputStream("D:\\FileChannelT2.java");
+ // 创建输入文件通道
+ FileChannel inChannel = inFile.getChannel();
+ // 创建输出文件通道
+ FileChannel outChannel = outFileStream.getChannel();
+ // 分配一个1024字节的字节缓存区
+ ByteBuffer byteBuffer = ByteBuffer.allocateDirect(1024); // 比allocate();效率高
+
+ // 测试时间
+ long startTime = System.currentTimeMillis();
+
+ // 读文件,存文件
+ while (true) {
+ // 将字节序列从此通道读入给定的缓冲区
+ int eof = inChannel.read(byteBuffer);
+ // 读到文件末尾退出
+ if (eof == -1)
+ break;
+ // 反转缓冲区
+ byteBuffer.flip();
+ // 将字节序列从给定的缓冲区写入此通道
+ outChannel.write(byteBuffer);
+ // 清空缓存区
+ byteBuffer.clear();
+ }
+ inChannel.close();
+ outChannel.close();
+
+ System.out.println("耗时:" + (System.currentTimeMillis() - startTime));
+ }
+
+}
diff --git a/src/main/java/org/javacore/nio/FileChannelTransferTo.java b/src/main/java/org/javacore/nio/FileChannelTransferTo.java
new file mode 100644
index 0000000..d480afc
--- /dev/null
+++ b/src/main/java/org/javacore/nio/FileChannelTransferTo.java
@@ -0,0 +1,53 @@
+package org.javacore.nio;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.channels.FileChannel;
+
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年10月9日 17:43:27
+ * FileChannel的transferTo/transferFrom案例
+ */
+public class FileChannelTransferTo {
+ // 读取的文件
+ private static final String sourceFile =
+ "src" + File.separator +
+ "org" + File.separator +
+ "javacore" + File.separator +
+ "nio" + File.separator +
+ "FileChannelTransferTo.java";
+ // 输出的文件
+ private static final String targetFile = "data.txt";
+
+ @SuppressWarnings("resource")
+ public static void main(String[] args) throws IOException {
+ // 创建用于读写的Channel
+ FileChannel
+ in = new FileInputStream(sourceFile).getChannel(),
+ out = new FileOutputStream(targetFile).getChannel();
+ // 将in通道的字节传输给out可写入字节通道
+ in.transferTo(0, in.size(),out);
+ // or
+ // 将字节从给定的可读取字节通道传输到此通道的文件中。
+ // out.transferFrom(in, 0, in.size());
+ }
+}
diff --git a/src/main/java/org/javacore/nio/FileLocking.java b/src/main/java/org/javacore/nio/FileLocking.java
new file mode 100644
index 0000000..3e86898
--- /dev/null
+++ b/src/main/java/org/javacore/nio/FileLocking.java
@@ -0,0 +1,44 @@
+package org.javacore.nio;
+
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.channels.FileLock;
+import java.util.concurrent.TimeUnit;
+
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年10月15日 19:31:34
+ * 文件加锁
+ */
+public class FileLocking {
+ public static void main(String[] args) throws IOException, InterruptedException {
+ // 获取输出流
+ FileOutputStream fos = new FileOutputStream("data.txt");
+ // 从输出流中获取文件加锁对象,并锁定File
+ FileLock fl = fos.getChannel().lock();
+ if (fl != null) {
+ System.out.println("Locked File");
+ TimeUnit.MICROSECONDS.sleep(100);
+ // 释放文件锁定
+ fl.release();
+ System.out.println("Release Lock");
+ }
+ }
+}
diff --git a/src/main/java/org/javacore/nio/GetChannel.java b/src/main/java/org/javacore/nio/GetChannel.java
new file mode 100644
index 0000000..61c2f65
--- /dev/null
+++ b/src/main/java/org/javacore/nio/GetChannel.java
@@ -0,0 +1,75 @@
+package org.javacore.nio;
+
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年10月8日 17:33:19
+ * 从流中获取FileChannel的案例
+ */
+public class GetChannel {
+ private static final int BSIZE = 1024; // 1K字节
+
+ @SuppressWarnings("resource")
+ public static void main(String[] args) throws IOException {
+ //////
+ // 写入文件
+ //////
+ // 从文件输出流获取FileChannel
+ FileChannel fc = new FileOutputStream("data.txt").getChannel();
+ // 将含有字节序列的缓冲区写入文件通道
+ fc.write(ByteBuffer.wrap("Some Text".getBytes()));// 将已存在的字节数组包装到ByteBuffer
+ // 关闭通道
+ fc.close();
+
+ //////
+ // 从文件尾部写入
+ //////
+ // 从RandomAccessFile获取FileChannel文件
+ fc = new RandomAccessFile("data.txt", "rw").getChannel();
+ // 文件指针指向文件尾部
+ fc.position(fc.size());
+ // 将含有字节序列的缓冲区写入文件通道
+ fc.write(ByteBuffer.wrap(" Some more".getBytes()));
+ // 关闭通道
+ fc.close();
+
+ //////
+ // 读取文件
+ //////
+ // 从文件输出流获取FileChannel文件
+ fc = new FileInputStream("data.txt").getChannel();
+ // 分配ByteBuffer的大小 1K
+ ByteBuffer buffer = ByteBuffer.allocate(BSIZE);
+ // 将字节序列从此通道读入给定的缓冲区。
+ fc.read(buffer);
+ // 反转缓冲区,为写入或读取做好准备
+ buffer.flip();
+ // 打印
+ while (buffer.hasRemaining()) {
+ System.out.print((char)buffer.get());
+ }
+ }
+
+}
diff --git a/src/main/java/org/javacore/nio/GetData.java b/src/main/java/org/javacore/nio/GetData.java
new file mode 100644
index 0000000..0a4766e
--- /dev/null
+++ b/src/main/java/org/javacore/nio/GetData.java
@@ -0,0 +1,60 @@
+package org.javacore.nio;
+
+import java.nio.ByteBuffer;
+
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年10月12日 18:53:10
+ * ByteBuffer操作类型数据的案例
+ */
+public class GetData {
+ private static final int BSIZE = 1024; // 1字节
+ public static void main(String[] args) {
+ // 创建字节缓冲区
+ ByteBuffer bb = ByteBuffer.allocate(BSIZE);
+ int i = 0;
+ while (i++ < bb.limit())// 缓冲区的限制 + if (bb.get() != 0)// 读取当前位置字节,如果字节不等于0 + System.out.println("该字节不为0"); + // 读取到最后一个跳出限制while,i为BSIZE大1。 + System.out.println("i = " + i); + + // 重绕此缓冲区 + bb.rewind(); + // 写入Hello + bb.asCharBuffer().put("Hello"); + // 从缓冲区读取char,并输出 + char c; + while ((c = bb.getChar()) != 0) + System.out.print(c + " "); + System.out.println(); + + // 写入Short类型数据 + bb.asShortBuffer().put((short) 47142); + System.out.println(bb.getShort()); + // 重绕此缓冲区 + bb.rewind(); + + // 写入Long类型数据 + bb.asLongBuffer().put((long)99471142); + System.out.println(bb.getLong()); + // 重绕此缓冲区 + bb.rewind(); + } +} diff --git a/src/main/java/org/javacore/nio/IntBufferDemo.java b/src/main/java/org/javacore/nio/IntBufferDemo.java new file mode 100644 index 0000000..2736e3d --- /dev/null +++ b/src/main/java/org/javacore/nio/IntBufferDemo.java @@ -0,0 +1,49 @@ +package org.javacore.nio; + +import java.nio.ByteBuffer; +import java.nio.IntBuffer; + +/* + * Copyright [2015] [Jeff Lee] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author Jeff Lee + * @since 2015-10-12 18:53:01 + * 通过IntBuffer操作ByteBuffer的int型数据 + */ +public class IntBufferDemo { + private static final int BSIZE = 1024;// 1字节 + public static void main(String[] args) { + // 创建1字节大小的字节缓冲区 + ByteBuffer bb = ByteBuffer.allocate(BSIZE); + // int视图缓冲区 + IntBuffer ib = bb.asIntBuffer(); + // 存储一个数组 + ib.put(new int[]{1, 2, 3, 4, 5, 6}); + // 通过访问ByteBuff字节缓冲区,获取某个位置的值 + System.out.println(ib.get(3)); + // 存储一个int数据 + ib.put(3, 44); + // 反转缓冲区 + ib.flip(); + // 如果当前位置还有元素 + while (ib.hasRemaining()) { + // 获取当前位置的元素 + int i = ib.get(); + System.out.println(i); + } + } +} diff --git a/src/main/java/org/javacore/nio/LargeMappedFiles.java b/src/main/java/org/javacore/nio/LargeMappedFiles.java new file mode 100644 index 0000000..72cd8fb --- /dev/null +++ b/src/main/java/org/javacore/nio/LargeMappedFiles.java @@ -0,0 +1,45 @@ +package org.javacore.nio; + +/* + * Copyright [2015] [Jeff Lee] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.MappedByteBuffer; +import java.nio.channels.FileChannel; + +/** + * @author Jeff Lee + * @since 2015-10-14 16:01:14 + * 内存映射文件的使用 + */ +public class LargeMappedFiles { + static int length = 0x8FFFFFF; // 128 MB + + public static void main(String[] args) throws IOException { + // 将此通道的文件区域直接映射到内存映射区域中。 + MappedByteBuffer out = new RandomAccessFile("data.txt","rw").getChannel() + .map(FileChannel.MapMode.READ_WRITE, 0, length); + // 写入128MB的字符串 + for (int i = 0;i < length; i++) + out.put((byte)'x'); + System.out.println("Finished writing"); + // 打印其中6个字符 + for (int i = length/2; i < length/2 + 6; i++) + System.out.print((char)out.get(i)); + } +} diff --git a/src/main/java/org/javacore/nio/LockingMappedFiles.java b/src/main/java/org/javacore/nio/LockingMappedFiles.java new file mode 100644 index 0000000..d0c7ace --- /dev/null +++ b/src/main/java/org/javacore/nio/LockingMappedFiles.java @@ -0,0 +1,75 @@ +package org.javacore.nio; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.ByteBuffer; +import java.nio.MappedByteBuffer; +import java.nio.channels.FileChannel; +import java.nio.channels.FileLock; + +/* + * Copyright [2015] [Jeff Lee] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author Jeff Lee + * @since 2015-10-17 15:17:04 + * 映射文件的使用 + */ +public class LockingMappedFiles { + static final int LENGTH = 0x8FFFFFF; // 128 MB + static FileChannel fc; + + public static void main(String[] args) throws IOException { + fc = new RandomAccessFile("data.txt" , "rw").getChannel(); + MappedByteBuffer out = fc.map(FileChannel.MapMode.READ_WRITE, + 0 , LENGTH); + for (int i = 0;i < LENGTH; i++) + out.put((byte)'x'); + new LockAndModify(out,0,0 + LENGTH/3); + new LockAndModify(out,LENGTH/2,LENGTH/2 + LENGTH/4); + } + + // 线程 + private static class LockAndModify extends Thread { + private ByteBuffer buffer; + private int start,end; + + LockAndModify(ByteBuffer mbb, int start, int end) { + this.start = start; + this.end = end; + mbb.limit(end); + mbb.position(start); + buffer = mbb.slice(); + start(); + } + + public void run() { + try { + // 从FileChannel获取文件加锁对象,并加锁 + FileLock fl = fc.lock(start,end,false); + System.out.println("Locked: " + start + " to " + end); + // 写入数据 + while (buffer.position() < buffer.limit() - 1) + buffer.put((byte)(buffer.get() + 1)); + fl.release(); + System.out.println("Released: " + start + " to " + end); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } +} diff --git a/src/main/java/org/javacore/nio/MappedIO.java b/src/main/java/org/javacore/nio/MappedIO.java new file mode 100644 index 0000000..83a58f1 --- /dev/null +++ b/src/main/java/org/javacore/nio/MappedIO.java @@ -0,0 +1,141 @@ +package org.javacore.nio; + +import org.javacore.io.RandomAccessFileT; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.IntBuffer; +import java.nio.channels.FileChannel; + +/* + * Copyright [2015] [Jeff Lee] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author Jeff Lee + * @since 2015-10-15 18:38:17 + * MappedByteBuffer与Old IO的性能比 + */ +public class MappedIO { + private static int numOfInts = 4000000; + private static int numOfUbuffInts = 200000; + + private abstract static class Tester { + private String name; + public Tester(String name){ + this.name = name; + } + + // 打印测试时间 + public void runTests(){ + System.out.print(name + ": "); + try { + long start = System.nanoTime(); + test(); + double duration = System.nanoTime() - start; + System.out.format("%.2f\n",duration/1.0e9); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public abstract void test() throws IOException; + } + + private static Tester[] tests = { + new Tester("Stream Write") { + @Override + public void test() throws IOException { + DataOutputStream dos = new DataOutputStream( + new BufferedOutputStream(new FileOutputStream(new File("data.txt")))); + for (int i = 0; i < numOfInts; i++) + dos.writeInt(i); + dos.close(); + } + }, + new Tester("Mapped Write") { + @Override + public void test() throws IOException { + FileChannel fc = + new RandomAccessFile("data.txt" , "rw").getChannel(); + IntBuffer ib = fc.map(FileChannel.MapMode.READ_WRITE, + 0,fc.size()).asIntBuffer(); + for (int i = 0; i < numOfInts; i++) + ib.put(i); + fc.close(); + } + }, + new Tester("Stream Read") { + @Override + public void test() throws IOException { + DataInputStream dis = new DataInputStream( + new BufferedInputStream(new FileInputStream(new File("data.txt")))); + for (int i = 0; i < numOfInts; i++) + dis.readInt(); + dis.close(); + } + }, + new Tester("Mapped Read") { + @Override + public void test() throws IOException { + FileChannel fc = + new FileInputStream(new File("data.txt")).getChannel(); + IntBuffer ib = fc.map(FileChannel.MapMode.READ_ONLY, + 0 , fc.size()).asIntBuffer(); + while (ib.hasRemaining()) + ib.get(); + fc.close(); + } + }, + new Tester("Stream Read/Write") { + @Override + public void test() throws IOException { + RandomAccessFile raf = new RandomAccessFile( + new File("data.txt"), "rw"); + raf.writeInt(1); + for (int i = 0; i < numOfUbuffInts; i++) { + raf.seek(raf.length() - 4); + raf.writeInt(raf.readInt()); + } + raf.close(); + } + }, + new Tester("Mapped Read/Write") { + @Override + public void test() throws IOException { + FileChannel fc = new RandomAccessFile( + new File("data.txt"),"rw").getChannel(); + IntBuffer ib = fc.map(FileChannel.MapMode.READ_WRITE, + 0,fc.size()).asIntBuffer(); + ib.put(0); + for (int i = 1; i < numOfUbuffInts; i++) + ib.put(ib.get(i-1)); + fc.close(); + } + } + }; + + public static void main(String[] args) { + for (Tester tester : tests) + tester.runTests(); + } +} diff --git a/src/main/java/org/javacore/nio/UsingBuffers.java b/src/main/java/org/javacore/nio/UsingBuffers.java new file mode 100644 index 0000000..bf49962 --- /dev/null +++ b/src/main/java/org/javacore/nio/UsingBuffers.java @@ -0,0 +1,55 @@ +package org.javacore.nio; + +import java.nio.ByteBuffer; +import java.nio.CharBuffer; + +/* + * Copyright [2015] [Jeff Lee] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author Jeff Lee + * @since 2015-10-14 15:48:12 + * 利用buffer实现交换相邻字符 + */ +public class UsingBuffers { + + private static void symmetricScaramble(CharBuffer buffer) { + while (buffer.hasRemaining()) { + // 将mark设为position + buffer.mark(); + char c1 = buffer.get(); + char c2 = buffer.get(); + // 重置为以前标记的位置 + buffer.reset(); + buffer.put(c2).put(c1); + } + } + + public static void main(String[] args) { + char[] data = "UsingBuffers".toCharArray(); + // 一个字符两个字节 + ByteBuffer bb = ByteBuffer.allocate(data.length * 2); + CharBuffer cb = bb.asCharBuffer(); + cb.put(data); + // 重绕此缓冲区 + System.out.println(cb.rewind()); + symmetricScaramble(cb); + // 重绕此缓冲区 + System.out.println(cb.rewind()); + symmetricScaramble(cb); + System.out.println(cb.rewind()); + } +} diff --git a/src/main/java/org/javacore/nio/ViewBuffers.java b/src/main/java/org/javacore/nio/ViewBuffers.java new file mode 100644 index 0000000..2e7e0a9 --- /dev/null +++ b/src/main/java/org/javacore/nio/ViewBuffers.java @@ -0,0 +1,77 @@ +package org.javacore.nio; + +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.DoubleBuffer; +import java.nio.FloatBuffer; +import java.nio.IntBuffer; +import java.nio.LongBuffer; +import java.nio.ShortBuffer; + +/* + * Copyright [2015] [Jeff Lee] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author Jeff Lee + * @since 2015-10-13 20:40:35 + * 不同视图下的缓冲区 + */ +public class ViewBuffers { + public static void main(String[] args) { + ByteBuffer bb = ByteBuffer.wrap(new byte[]{0,0,0,0,0,0,0,'a'}); + bb.rewind(); + System.out.print("Byte Buffer "); + while (bb.hasRemaining()) + System.out.print(bb.position() + " -> " + bb.get() + ", ");
+ System.out.println();
+
+ CharBuffer cb = ((ByteBuffer)bb.rewind()).asCharBuffer();
+ System.out.print("Char Buffer ");
+ while (cb.hasRemaining())
+ System.out.print(cb.position() + " -> " + cb.get() + ", ");
+ System.out.println();
+
+ ShortBuffer sb = ((ByteBuffer)bb.rewind()).asShortBuffer();
+ System.out.print("Short Buffer ");
+ while (sb.hasRemaining())
+ System.out.print(sb.position() + " -> " + sb.get() + ", ");
+ System.out.println();
+
+ IntBuffer ib = ((ByteBuffer)bb.rewind()).asIntBuffer();
+ System.out.print("Int Buffer ");
+ while (ib.hasRemaining())
+ System.out.print(ib.position() + " -> " + ib.get());
+ System.out.println();
+
+ FloatBuffer fb = ((ByteBuffer)bb.rewind()).asFloatBuffer();
+ System.out.print("Float Buffer ");
+ while (fb.hasRemaining())
+ System.out.print(fb.position() + " -> " + fb.get() + ", ");
+ System.out.println();
+
+ LongBuffer lb = ((ByteBuffer)bb.rewind()).asLongBuffer();
+ System.out.print("Long Buffer ");
+ while (lb.hasRemaining())
+ System.out.print(lb.position() + " -> " + lb.get() + ", ");
+ System.out.println();
+
+ DoubleBuffer db = ((ByteBuffer)bb.rewind()).asDoubleBuffer();
+ System.out.print("Double Buffer ");
+ while (db.hasRemaining())
+ System.out.print(db.position() + " -> " + db.get() + ", ");
+ System.out.println();
+ }
+}
diff --git a/src/main/java/org/javacore/reflection/ArrayCopy.java b/src/main/java/org/javacore/reflection/ArrayCopy.java
new file mode 100644
index 0000000..e68b396
--- /dev/null
+++ b/src/main/java/org/javacore/reflection/ArrayCopy.java
@@ -0,0 +1,51 @@
+package org.javacore.reflection;
+
+import java.lang.reflect.Array;
+import java.util.Arrays;
+
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年11月9日 10:45:19
+ * 反射扩容对象数组
+ */
+public class ArrayCopy {
+ public static void main(String[] args) {
+ int[] a = {1,2,3};
+ a = (int[]) goodCopyOf(a,10);
+ System.out.println(Arrays.toString(a));
+
+ String[] str = {"a","b","c"};
+ str = (String[]) goodCopyOf(str,10);
+ System.out.println(Arrays.toString(str));
+ }
+
+ public static Object goodCopyOf(Object a,int newLength){
+ // 获取Class对象
+ Class cl = a.getClass();
+ // 如果不是数组对象,则返回null;
+ if (!cl.isArray()) return null;
+ // 获取数组组件对象
+ Class componentType = cl.getComponentType();
+ int length = Array.getLength(a);
+ Object newArray = Array.newInstance(componentType,newLength);
+ // 复制数组
+ System.arraycopy(a,0,newArray,0,Math.min(length,newLength));
+ return newArray;
+ }
+}
diff --git a/src/main/java/org/javacore/reflection/EmployeeClass.java b/src/main/java/org/javacore/reflection/EmployeeClass.java
new file mode 100644
index 0000000..558bdde
--- /dev/null
+++ b/src/main/java/org/javacore/reflection/EmployeeClass.java
@@ -0,0 +1,46 @@
+package org.javacore.reflection;
+
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年11月9日 10:45:19
+ * 反射在继承中的案例
+ */
+class Employee {
+ private String name;
+ public Employee(String name){
+ this.name = name;
+ }
+
+ public String getName(){
+ return name;
+ }
+}
+class Manager extends Employee {
+ public Manager(String name) {
+ super(name);
+ }
+}
+public class EmployeeClass {
+ public static void main(String[] args) {
+ Employee employee = new Employee("Jeff");
+ Employee manager = new Manager("Boss");
+ System.out.println(employee.getClass().getName() + " " + employee.getName());
+ System.out.println(manager.getClass().getName() + " " + manager.getName());
+ }
+}
diff --git a/src/main/java/org/javacore/reflection/ObjectAnalyzer.java b/src/main/java/org/javacore/reflection/ObjectAnalyzer.java
new file mode 100644
index 0000000..ee6beca
--- /dev/null
+++ b/src/main/java/org/javacore/reflection/ObjectAnalyzer.java
@@ -0,0 +1,84 @@
+package org.javacore.reflection;
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Array;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年11月9日 10:45:19
+ * 反射对象分析工具 @{link test/org.javacore.reflection.ObjectAnalyzerTest}
+ */
+public class ObjectAnalyzer {
+ private ArrayList visited = new ArrayList();
+
+ public String toString(Object obj){
+ if (obj == null) return "null";
+ if (visited.contains(obj)) return "...";
+ visited.add(obj);
+
+ // 获取Class对象
+ Class cl = obj.getClass();
+ if (cl == String.class) return (String)obj;
+ // 如果对象是一个数组类
+ if (cl.isArray()){
+ // 获取数组组件
+ String r = cl.getComponentType() + "[]{";
+ for (int i = 0; i < Array.getLength(obj); i++) { + if (i> 0) r += ",";
+ Object val = Array.get(obj,i);
+ // 是否是一个基本类型
+ if (cl.getComponentType().isPrimitive())
+ r += val;
+ else r += toString(val);
+ }
+ return r + "}";
+ }
+
+ String r =cl.getName();
+ do {
+ r += "[";
+ Field[] fields = cl.getDeclaredFields();
+ AccessibleObject.setAccessible(fields,true);
+ for (Field f : fields){
+ if (!Modifier.isStatic(f.getModifiers())){
+ r += f.getName() + "=";
+ try {
+ Class t = f.getType();
+ Object val = f.get(obj);
+ if (t.isPrimitive())
+ r += val;
+ else
+ r +=toString(val);
+ } catch (Exception e){
+ e.printStackTrace();
+ }
+ }
+ }
+ r += "]";
+ cl = cl.getSuperclass();
+ } while (cl != null);
+
+ return r;
+ }
+
+
+}
\ No newline at end of file
diff --git a/src/main/java/org/javacore/reflection/ReflectionTest.java b/src/main/java/org/javacore/reflection/ReflectionTest.java
new file mode 100644
index 0000000..b057cd9
--- /dev/null
+++ b/src/main/java/org/javacore/reflection/ReflectionTest.java
@@ -0,0 +1,127 @@
+package org.javacore.reflection;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年11月9日 10:45:19
+ * 反射对象构造函数、方法及字段
+ */
+public class ReflectionTest {
+ public final int AGE = 1;
+ public static void main(String[] args) {
+ Class cl = null;
+ try {
+ cl = Class.forName("org.javacore.reflection.ReflectionTest");
+ System.out.println("打印析构函数:");
+ printConstructors(cl);
+ System.out.println("打印方法:");
+ printMethods(cl);
+ System.out.println("打印字段:");
+ printFields(cl);
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 打印Class对象的析构方法
+ * @param cl
+ */
+ public static void printConstructors(Class cl){
+ // 返回类所有的析构方法
+ Constructor[] constructors = cl.getDeclaredConstructors();
+ for (Constructor c : constructors){
+ // 返回析构方法名称
+ String name = c.getName();
+ System.out.print(" ");
+ // 获取Java语言的修饰符
+ // 修饰符由 Java 虚拟机的 public、protected、private、
+ // final、static、abstract 和 interface 对应的常量组成;
+ String modifiers = Modifier.toString(c.getModifiers());
+ if (modifiers.length()> 0)
+ System.out.print(modifiers + " ");
+ System.out.print(name + "(");
+
+ // 获取析构方法的参数对象列表数组
+ Class[] paramTypes = c.getParameterTypes();
+ for (int i = 0; i < paramTypes.length;i++){ + if (i> 0)
+ System.out.print(", ");
+ System.out.print(paramTypes[i].getName());
+ }
+ System.out.println(");");
+ }
+ }
+
+ /**
+ * 打印对象所有的方法
+ * @param cl
+ */
+ public static void printMethods(Class cl){
+ // 获取类所有方法对象数组
+ Method[] methods = cl.getMethods();
+ for (Method m : methods) {
+ // 获取方法返回对象
+ Class retType = m.getReturnType();
+ String name = m.getName();
+
+ System.out.print(" ");
+ // 获取Java语言的修饰符
+ // 修饰符由 Java 虚拟机的 public、protected、private、
+ // final、static、abstract 和 interface 对应的常量组成;
+ String modifiers = Modifier.toString(cl.getModifiers());
+ if (modifiers.length()> 0)
+ System.out.print(modifiers + " ");
+ System.out.print(retType.getName() +" " + name + "(");
+
+ // 获取方法的参数对象列表数组
+ Class[] paramTypes = m.getParameterTypes();
+ for (int i = 0; i < paramTypes.length;i++){ + if (i> 0)
+ System.out.print(", ");
+ System.out.print(paramTypes[i].getName());
+ }
+ System.out.println(");");
+ }
+ }
+
+ public static void printFields(Class clazz){
+ // 获取字段Field对象数组
+ Field[] fields = clazz.getFields();
+ for (Field field : fields){
+ // 获取字段声明类型对象
+ Class type = field.getType();
+ // 获取字段名称
+ String name = field.getName();
+
+ System.out.print(" ");
+ // 获取Java语言的修饰符
+ // 修饰符由 Java 虚拟机的 public、protected、private、
+ // final、static、abstract 和 interface 对应的常量组成;
+ String modifiers = Modifier.toString(field.getModifiers());
+ if (modifiers.length()> 0)
+ System.out.print(modifiers + " ");
+ System.out.print(type.getName() + " " + name);
+ }
+ }
+}
diff --git a/src/main/java/org/javacore/reflection/User.java b/src/main/java/org/javacore/reflection/User.java
new file mode 100644
index 0000000..f537ac4
--- /dev/null
+++ b/src/main/java/org/javacore/reflection/User.java
@@ -0,0 +1,60 @@
+package org.javacore.reflection;
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年9月8日 09:35:14
+ * 反射构造器使用的bean
+ */
+public class User {
+ private int id;
+ private String name;
+
+ // 无参构造器(默认构造器)
+ public User() {
+ }
+
+ public User(int id) {
+ this.id = id;
+ }
+
+ public User(int id, String name) {
+ this.id = id;
+ this.name = name;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String toString() {
+ return "User [id=" + id + ", name=" + name + "]";
+ }
+}
diff --git a/src/main/java/org/javacore/reflection/UserConstructorReflect.java b/src/main/java/org/javacore/reflection/UserConstructorReflect.java
new file mode 100644
index 0000000..7e3eea8
--- /dev/null
+++ b/src/main/java/org/javacore/reflection/UserConstructorReflect.java
@@ -0,0 +1,49 @@
+package org.javacore.reflection;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年9月8日 09:35:35
+ * 利用反射通过构造器创建一个实例
+ */
+public class UserConstructorReflect {
+ public static void main(String[] args) throws NoSuchMethodException,
+ SecurityException, InstantiationException,
+ IllegalAccessException, IllegalArgumentException,
+ InvocationTargetException {
+ // 获取User类型
+ Class> userClass = User.class;
+ // 获取默认构造器
+ Constructor> constructor = userClass.getConstructor();
+ // 获取带int参数的构造器
+ Constructor> intConstructor = userClass.getConstructor(int.class);
+ // 获取带int和String参数的构造器
+ Constructor> bothConstructor = userClass.getConstructor(int.class,String.class);
+
+ // 使用反射,获取新的User对象
+ User u1 = (User) constructor.newInstance();
+ User u2 = (User) intConstructor.newInstance(1);
+ User u3 = (User) bothConstructor.newInstance(2,"BYSocket");
+
+ System.out.println(u1.toString());
+ System.out.println(u2.toString());
+ System.out.println(u3.toString());
+ }
+}
diff --git a/src/main/java/org/javacore/rtti/ClassInitialization.java b/src/main/java/org/javacore/rtti/ClassInitialization.java
new file mode 100644
index 0000000..98a854f
--- /dev/null
+++ b/src/main/java/org/javacore/rtti/ClassInitialization.java
@@ -0,0 +1,67 @@
+package org.javacore.rtti;
+
+import java.util.Random;
+
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年11月2日 16:43:41
+ * Class初始化案例
+ */
+class Initable {
+ static final int staticFinal = 47;
+ static final int staticFinal2 =
+ ClassInitialization.random.nextInt(1000);
+ static {
+ System.out.println("Initializing Initable");
+ }
+}
+
+class Initable2 {
+ static int staticNonFinal = 147;
+ static {
+ System.out.println("Initializing Initable2");
+ }
+}
+
+class Initable3 {
+ static int staticNonFinal = 74;
+ static {
+ System.out.println("Initializing Initable3");
+ }
+}
+
+public class ClassInitialization {
+ public static Random random = new Random(47);
+
+ public static void main(String[] args) throws ClassNotFoundException {
+ // 类中有编译期常量 static Final,则暂时不需要初始化
+ Class initable = Initable.class;
+ System.out.println("After creating Initable ref");
+ System.out.println(Initable.staticFinal);
+ // 调用非编译期常量,强制进行类Initable初始化
+ System.out.println(Initable.staticFinal2);
+
+ // 先进行初始化
+ System.out.println(Initable2.staticNonFinal);
+
+ // 无编译期常量,直接初始化
+ Class initable3 = Class.forName("org.javacore.rtti.Initable3");
+ System.out.println("After creating Initable ref");
+ System.out.println(Initable3.staticNonFinal);
+ }
+}
diff --git a/src/main/java/org/javacore/rtti/ShowMethods.java b/src/main/java/org/javacore/rtti/ShowMethods.java
new file mode 100644
index 0000000..9316df9
--- /dev/null
+++ b/src/main/java/org/javacore/rtti/ShowMethods.java
@@ -0,0 +1,40 @@
+package org.javacore.rtti;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年11月2日 16:43:41
+ * 获取Class方法案例
+ */
+public class ShowMethods {
+ public static void main(String[] args) {
+ try {
+ Class> c = Class.forName("org.javacore.rtti.ShowMethods");
+ Method[] methods = c.getMethods();
+ Constructor[] constructors = c.getConstructors();
+ for (Method m : methods)
+ System.out.println(m.toGenericString());
+ for (Constructor constructor : constructors)
+ System.out.println(constructor.toGenericString());
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/src/main/java/org/javacore/scheduler/SchedulerExecutorTest.java b/src/main/java/org/javacore/scheduler/SchedulerExecutorTest.java
new file mode 100644
index 0000000..c6c4d0b
--- /dev/null
+++ b/src/main/java/org/javacore/scheduler/SchedulerExecutorTest.java
@@ -0,0 +1,46 @@
+package org.javacore.scheduler; /*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * ScheduledExecutorService的使用
+ * @author BYSocket
+ * @since 2016年01月10日 14:20:00
+ */
+public class SchedulerExecutorTest implements
+ Runnable {
+ private final String jobName;
+
+ public SchedulerExecutorTest(String jobName) {
+ this.jobName = jobName;
+ }
+
+ @Override
+ public void run() {
+ System.out.println("running => " + jobName);
+ }
+
+ public static void main(String[] args) {
+ ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
+ // 一秒
+ executor.scheduleAtFixedRate(new SchedulerExecutorTest("job1"), 1, 1, TimeUnit.SECONDS);
+ // 两秒
+ executor.scheduleWithFixedDelay(new SchedulerExecutorTest("job2"),1,2,TimeUnit.SECONDS);
+ }
+}
diff --git a/src/main/java/org/javacore/scheduler/SchedulerExecutorTest2.java b/src/main/java/org/javacore/scheduler/SchedulerExecutorTest2.java
new file mode 100644
index 0000000..4b413ed
--- /dev/null
+++ b/src/main/java/org/javacore/scheduler/SchedulerExecutorTest2.java
@@ -0,0 +1,116 @@
+package org.javacore.scheduler; /*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * ScheduledExecutorService的使用
+ * @author BYSocket
+ * @since 2016年01月10日 22:02:00
+ */
+public class SchedulerExecutorTest2 implements Runnable{
+
+ private final String jobName;
+
+ public SchedulerExecutorTest2(String jobName) {
+ this.jobName = jobName;
+ }
+
+ @Override
+ public void run() {
+ System.out.println("Date = " + new Date() + ", running => " + jobName);
+ }
+
+ /**
+ * 计算从当前时间currentDate开始,满足条件dayOfWeek, hourOfDay,
+ * minuteOfHour, secondOfMinite的最近时间
+ * @return
+ */
+ public Calendar getEarliestDate(Calendar currentDate, int dayOfWeek,
+ int hourOfDay, int minuteOfHour, int secondOfMinite) {
+ //计算当前时间的WEEK_OF_YEAR,DAY_OF_WEEK, HOUR_OF_DAY, MINUTE,SECOND等各个字段值
+ int currentWeekOfYear = currentDate.get(Calendar.WEEK_OF_YEAR);
+ int currentDayOfWeek = currentDate.get(Calendar.DAY_OF_WEEK);
+ int currentHour = currentDate.get(Calendar.HOUR_OF_DAY);
+ int currentMinute = currentDate.get(Calendar.MINUTE);
+ int currentSecond = currentDate.get(Calendar.SECOND);
+
+ //如果输入条件中的dayOfWeek小于当前日期的dayOfWeek,则WEEK_OF_YEAR需要推迟一周
+ boolean weekLater = false;
+ if (dayOfWeek < currentDayOfWeek) { + weekLater = true; + } else if (dayOfWeek == currentDayOfWeek) { + //当输入条件与当前日期的dayOfWeek相等时,如果输入条件中的 + //hourOfDay小于当前日期的 + //currentHour,则WEEK_OF_YEAR需要推迟一周 + if (hourOfDay < currentHour) { + weekLater = true; + } else if (hourOfDay == currentHour) { + //当输入条件与当前日期的dayOfWeek, hourOfDay相等时, + //如果输入条件中的minuteOfHour小于当前日期的 + //currentMinute,则WEEK_OF_YEAR需要推迟一周 + if (minuteOfHour < currentMinute) { + weekLater = true; + } else if (minuteOfHour == currentSecond) { + //当输入条件与当前日期的dayOfWeek, hourOfDay, + //minuteOfHour相等时,如果输入条件中的 + //secondOfMinite小于当前日期的currentSecond, + //则WEEK_OF_YEAR需要推迟一周 + if (secondOfMinite < currentSecond) { + weekLater = true; + } + } + } + } + if (weekLater) { + //设置当前日期中的WEEK_OF_YEAR为当前周推迟一周 + currentDate.set(Calendar.WEEK_OF_YEAR, currentWeekOfYear + 1); + } + // 设置当前日期中的DAY_OF_WEEK,HOUR_OF_DAY,MINUTE,SECOND为输入条件中的值。 + currentDate.set(Calendar.DAY_OF_WEEK, dayOfWeek); + currentDate.set(Calendar.HOUR_OF_DAY, hourOfDay); + currentDate.set(Calendar.MINUTE, minuteOfHour); + currentDate.set(Calendar.SECOND, secondOfMinite); + return currentDate; + + } + + public static void main(String[] args) { + SchedulerExecutorTest2 executor = new SchedulerExecutorTest2("job1"); + // 获取当前时间 + Calendar currentDate = Calendar.getInstance(); + long currentDateLong = currentDate.getTime().getTime(); + System.out.println("Current Date = " + currentDate.getTime().toString()); + // 计算满足条件的最近一次执行时间 + Calendar earliestDate = executor.getEarliestDate(currentDate,3,16,38,10); + long earliestDateLong = earliestDate.getTime().getTime(); + System.out.println("Earliest Date = " + earliestDate.getTime().toString()); + // 计算从当前时间到最近一次执行时间的时间间隔 + long delay = earliestDateLong - currentDateLong; + // 计算执行周期为一星期 +// long period = 7 * 24 * 60 * 60 * 1000; + long period = 1000; + ScheduledExecutorService service = Executors.newScheduledThreadPool(10); + // 从现在开始delay毫秒之后,每隔一星期执行一次job1 + service.scheduleAtFixedRate(executor, delay, period, + TimeUnit.MILLISECONDS); + } + +} diff --git a/src/main/java/org/javacore/scheduler/TimerTest.java b/src/main/java/org/javacore/scheduler/TimerTest.java new file mode 100644 index 0000000..c6f6542 --- /dev/null +++ b/src/main/java/org/javacore/scheduler/TimerTest.java @@ -0,0 +1,44 @@ +package org.javacore.scheduler; /* + * Copyright [2015] [Jeff Lee] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.util.Timer; +import java.util.TimerTask; + +/** + * Timer的使用 + * @author BYSocket + * @since 2016-01-09 22:19:00 + */ +public class TimerTest extends TimerTask{ + + private final String jobName; + + public TimerTest(String jobName) { + this.jobName = jobName; + } + + @Override + public void run() { + System.out.println("run the task => " + jobName);
+ }
+
+ public static void main(String[] args) {
+ // 一种工具,线程用其安排以后在后台线程中执行的任务
+ Timer timer = new Timer();
+ timer.schedule(new TimerTest("Job 1") , 1000 , 1000); // 一秒
+ timer.schedule(new TimerTest("Job 2") , 2000 , 2000); // 两秒
+ }
+}
diff --git a/src/main/java/org/javacore/thread/BasicThreads.java b/src/main/java/org/javacore/thread/BasicThreads.java
new file mode 100644
index 0000000..f2aa6bb
--- /dev/null
+++ b/src/main/java/org/javacore/thread/BasicThreads.java
@@ -0,0 +1,32 @@
+package org.javacore.thread;
+
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年11月2日 17:06:48
+ * 线程简单使用-启动LiftOff线程{@link LiftOff}
+ */
+public class BasicThreads {
+ public static void main(String[] args) {
+ // 创建新的线程
+ Thread t = new Thread(new LiftOff());
+ // 执行线程
+ t.start();
+ System.out.println("Waiting for LiftOff");
+ }
+}
diff --git a/src/main/java/org/javacore/thread/CachedThreadPool.java b/src/main/java/org/javacore/thread/CachedThreadPool.java
new file mode 100644
index 0000000..949cb37
--- /dev/null
+++ b/src/main/java/org/javacore/thread/CachedThreadPool.java
@@ -0,0 +1,36 @@
+package org.javacore.thread;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年11月2日 17:21:04
+ * 线程池CachedThreadPool的简单使用-启动LiftOff线程{@link LiftOff}
+ */
+public class CachedThreadPool {
+ public static void main(String[] args) {
+ // 创建新线程的线程池
+ ExecutorService exec = Executors.newCachedThreadPool();
+ for (int i = 0 ; i < 5; i++) + exec.execute(new LiftOff()); // 由线程池Ececutor决定执行给定的线程。 + // 顺序关闭,执行以前提交的线程,不接受新的线程。 + exec.shutdown(); + } +} diff --git a/src/main/java/org/javacore/thread/CallableDemo.java b/src/main/java/org/javacore/thread/CallableDemo.java new file mode 100644 index 0000000..8d57eee --- /dev/null +++ b/src/main/java/org/javacore/thread/CallableDemo.java @@ -0,0 +1,71 @@ +package org.javacore.thread; + +import java.util.ArrayList; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +/** + * Created by BYSocket on 2015/11/2. + * + * Copyright [2015] [Jeff Lee] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author Jeff Lee + * @since 2015-11-2 18:58:36 + * Callable接口的使用 --- 实现带返回值的任务 + */ + +// Callable实现类task,指定其类型参数 +class TaskWithResult implements Callable {
+
+ private int id;
+ public TaskWithResult(int id) {
+ this.id = id;
+ }
+
+ @Override
+ public String call() throws Exception {
+ return "result of TaskWithResult " + id;
+ }
+}
+
+public class CallableDemo {
+ public static void main(String[] args) {
+ // 创建一个新的线程池
+ ExecutorService exec = Executors.newCachedThreadPool();
+ // Callable实现类task的返回结果集
+ ArrayList> results = new ArrayList();
+ for (int i = 0; i < 5 ; i++) + results.add(exec.submit(new TaskWithResult(i)));// 使用submit来启动Tasks + + // 异步计算的结果 + for (Future fs : results)
+ try {
+ // get阻塞,直至获取结果
+ System.out.println(fs.get());
+ } catch (InterruptedException e) {
+ System.out.println(e);
+ e.printStackTrace();
+ } catch (ExecutionException e) {
+ System.out.println(e);
+ e.printStackTrace();
+ } finally {
+ exec.shutdown();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/javacore/thread/DaemonFromFactory.java b/src/main/java/org/javacore/thread/DaemonFromFactory.java
new file mode 100644
index 0000000..702eaea
--- /dev/null
+++ b/src/main/java/org/javacore/thread/DaemonFromFactory.java
@@ -0,0 +1,55 @@
+package org.javacore.thread;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Created by BYSocket on 2015年11月2日.
+ *
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年11月3日 18:17:58
+ * 后台线程工厂类的使用
+ */
+public class DaemonFromFactory implements Runnable {
+ @Override
+ public void run() {
+ try {
+ while (true){
+ TimeUnit.MICROSECONDS.sleep(100);
+ System.out.println(Thread.currentThread() + " " + this);
+ }
+ } catch (InterruptedException e) {
+ System.out.println("sleep() interrupted");
+ }
+ }
+
+ public static void main(String[] args) throws InterruptedException {
+ // 使用提供的线程工厂类,创建线程池
+ ExecutorService exec =
+ Executors.newCachedThreadPool(new DaemonThreadFactory());
+ for (int i = 0 ; i < 10 ; i++) + exec.execute(new DaemonFromFactory());// 此Runnable实现类,经过线程工厂创建 + // 关闭线程池 + exec.shutdown(); + System.out.println("任务已经全部启动"); + TimeUnit.MICROSECONDS.sleep(500); + } + +} diff --git a/src/main/java/org/javacore/thread/DaemonThreadFactory.java b/src/main/java/org/javacore/thread/DaemonThreadFactory.java new file mode 100644 index 0000000..9183815 --- /dev/null +++ b/src/main/java/org/javacore/thread/DaemonThreadFactory.java @@ -0,0 +1,36 @@ +package org.javacore.thread; + +import java.util.concurrent.ThreadFactory; + +/** + * Created by BYSocket on 2015/11/2. + * + * Copyright [2015] [Jeff Lee] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author Jeff Lee + * @since 2015-11-3 18:17:49 + * 线程工厂类 - 将线程设置为后台线程 + */ +public class DaemonThreadFactory implements ThreadFactory { + + @Override + public Thread newThread(Runnable r) { + Thread t = new Thread(r); + t.setDaemon(true); + return t; + } +} diff --git a/src/main/java/org/javacore/thread/DaemonsDontRunFinally.java b/src/main/java/org/javacore/thread/DaemonsDontRunFinally.java new file mode 100644 index 0000000..6794ee6 --- /dev/null +++ b/src/main/java/org/javacore/thread/DaemonsDontRunFinally.java @@ -0,0 +1,50 @@ +package org.javacore.thread; + +import java.util.concurrent.TimeUnit; + +/** + * Created by BYSocket on 2015/11/2. + * + * Copyright [2015] [Jeff Lee] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author Jeff Lee + * @since 2015-11-3 18:17:58 + * 后台线程遇到Finally + */ +class ADaemon implements Runnable { + + @Override + public void run() { + try { + System.out.println("启动ADaemon"); + TimeUnit.SECONDS.sleep(1); + } catch (InterruptedException e ){ + System.out.println("InterruptedException"); + } finally { + // 因为main是非后台线程,main线程结束。ADaemon后台线程也就结束。因此可能没到finally就结束了。 + System.out.println("finally 运行吗?"); + } + } +} +public class DaemonsDontRunFinally { + public static void main(String[] args) { + Thread t = new Thread(new ADaemon()); + // 设置线程为后台线程 + t.setDaemon(true); + t.start(); + } +} diff --git a/src/main/java/org/javacore/thread/FixedThreadPool.java b/src/main/java/org/javacore/thread/FixedThreadPool.java new file mode 100644 index 0000000..99e80a9 --- /dev/null +++ b/src/main/java/org/javacore/thread/FixedThreadPool.java @@ -0,0 +1,36 @@ +package org.javacore.thread; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +/* + * Copyright [2015] [Jeff Lee] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author Jeff Lee + * @since 2015-11-2 17:06:48 + * 线程池FixedThreadPool的简单使用-启动LiftOff线程{@link LiftOff} + */ +public class FixedThreadPool { + public static void main(String[] args) { + // 创建固定线程为5的线程池 + ExecutorService exec = Executors.newFixedThreadPool(5); + for (int i = 0; i < 5 ;i++) + exec.execute(new LiftOff());// 由线程池Ececutor决定执行给定的线程。 + // 顺序关闭,执行以前提交的线程,不接受新的线程。 + exec.shutdown(); + } +} diff --git a/src/main/java/org/javacore/thread/LiftOff.java b/src/main/java/org/javacore/thread/LiftOff.java new file mode 100644 index 0000000..7f36af6 --- /dev/null +++ b/src/main/java/org/javacore/thread/LiftOff.java @@ -0,0 +1,47 @@ +package org.javacore.thread; + +/* + * Copyright [2015] [Jeff Lee] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author Jeff Lee + * @since 2015-11-2 16:56:43 + * Runnable接口的实现类LiftOff + */ +public class LiftOff implements Runnable{ + + protected int countDown = 10; + private static int taskCount = 0; + private final int id = taskCount++; + + public LiftOff(){} + public LiftOff(int countDown){ + this.countDown = countDown; + } + + public String status(){ + return "#" + id + "(" + + (countDown>0 ? countDown : "LiftOff!") + "), ";
+ }
+ @Override
+ public void run() {
+ while (countDown--> 0){
+ System.out.println(status());
+ // 暂停当前正在执行线程,并执行其他线程。
+ Thread.yield();
+ }
+ }
+}
diff --git a/src/main/java/org/javacore/thread/MoreBasicThreads.java b/src/main/java/org/javacore/thread/MoreBasicThreads.java
new file mode 100644
index 0000000..4b31be3
--- /dev/null
+++ b/src/main/java/org/javacore/thread/MoreBasicThreads.java
@@ -0,0 +1,30 @@
+package org.javacore.thread;
+
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年11月2日 17:09:33
+ * 线程简单使用-启动多个LiftOff线程{@link LiftOff}
+ */
+public class MoreBasicThreads {
+ public static void main(String[] args) {
+ for (int i = 0; i < 5 ; i++) + new Thread(new LiftOff()).start(); + System.out.println("Waiting for LiftOff"); + } +} diff --git a/src/main/java/org/javacore/thread/MyRunnable.java b/src/main/java/org/javacore/thread/MyRunnable.java new file mode 100644 index 0000000..ebf817c --- /dev/null +++ b/src/main/java/org/javacore/thread/MyRunnable.java @@ -0,0 +1,31 @@ +package org.javacore.thread; +/* + * Copyright [2015] [Jeff Lee] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author Jeff Lee + * @since 2015-7-4 16:14:47 + * Runnable接口的简单使用 + * 测试 --> {@link MyRunnableTest}
+ */
+public class MyRunnable implements Runnable{
+
+ @Override
+ public void run() {
+ System.out.println("MyRunnable --> run()");
+ }
+
+}
diff --git a/src/main/java/org/javacore/thread/MyThread.java b/src/main/java/org/javacore/thread/MyThread.java
new file mode 100644
index 0000000..9c3af6c
--- /dev/null
+++ b/src/main/java/org/javacore/thread/MyThread.java
@@ -0,0 +1,32 @@
+package org.javacore.thread;
+
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年7月4日 16:14:51
+ * Thread的简单使用
+ * 测试 --> {@link MyThreadTest}
+ */
+public class MyThread extends Thread{
+
+ @Override
+ public void run() {
+ System.out.println("MyThread --> run()");
+ }
+
+}
diff --git a/src/main/java/org/javacore/thread/ProcessBuilderTest.java b/src/main/java/org/javacore/thread/ProcessBuilderTest.java
new file mode 100644
index 0000000..244da77
--- /dev/null
+++ b/src/main/java/org/javacore/thread/ProcessBuilderTest.java
@@ -0,0 +1,36 @@
+package org.javacore.thread; /*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.IOException;
+import java.util.Scanner;
+
+/**
+ * Java进程调用CMD
+ * VM options => -Dfile.encoding="GBK"
+ * @author BYSocket
+ * @since 2016年01月18日 16:08:00
+ */
+public class ProcessBuilderTest {
+ public static void main(String[] args) throws IOException {
+ ProcessBuilder pb = new ProcessBuilder("cmd","/c","ipconfig/all");
+ Process p = pb.start();
+
+ Scanner scanner = new Scanner(p.getInputStream());
+ while (scanner.hasNext())
+ System.out.println(scanner.next());
+ scanner.close();
+ }
+}
diff --git a/src/main/java/org/javacore/thread/SimpleDaemons.java b/src/main/java/org/javacore/thread/SimpleDaemons.java
new file mode 100644
index 0000000..f1bbc21
--- /dev/null
+++ b/src/main/java/org/javacore/thread/SimpleDaemons.java
@@ -0,0 +1,53 @@
+package org.javacore.thread;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Created by BYSocket on 2015年11月2日.
+ *
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @author Jeff Lee
+ * @since 2015年11月3日 18:09:06
+ * Daemon后台线程的简单使用
+ */
+public class SimpleDaemons implements Runnable{
+ @Override
+ public void run() {
+ try {
+ while (true){
+ TimeUnit.MICROSECONDS.sleep(1000);
+ System.out.println(Thread.currentThread() + " " + this);
+ }
+ } catch (InterruptedException e) {
+ System.out.println("sleep() interrupted");
+ }
+ }
+
+ // main是非后台线程
+ public static void main(String[] args) throws InterruptedException {
+ for (int i = 0 ; i < 10 ; i++){ + // 创建一个新线程 + Thread daemon = new Thread(new SimpleDaemons()); + // 设置为后台线程,main为非后台线程 + daemon.setDaemon(true); + daemon.start(); + } + System.out.println("所有任务已启动"); + // 如果main结束,那么同时会杀死所有后台线程,多次运行你会发现,可能打印的后台线程数不定 + TimeUnit.MICROSECONDS.sleep(175); + } +} diff --git a/src/main/java/org/javacore/thread/SimplePriorities.java b/src/main/java/org/javacore/thread/SimplePriorities.java new file mode 100644 index 0000000..340a27b --- /dev/null +++ b/src/main/java/org/javacore/thread/SimplePriorities.java @@ -0,0 +1,68 @@ +package org.javacore.thread; + +/** + * Created by BYSocket on 2015/11/2. + * + * Copyright [2015] [Jeff Lee] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +/** + * @author Jeff Lee + * @since 2015-11-3 09:05:03 + * 线程优先级的使用 + */ +public class SimplePriorities implements Runnable { + private int countDown = 5; + private volatile double d; + private int priority; + + public SimplePriorities(int priority){ + this.priority = priority; + } + + public String toString(){ + // 获取当前执行的线程对象的引用 + return Thread.currentThread() + ": " + countDown; + } + + @Override + public void run() { + // 获取当前执行的线程对象的引用,并设置其优先级。 + Thread.currentThread().setPriority(priority); + + while (true){ + for (int i = 1; i < 100000; i++){ + d += (Math.PI + Math.E) / (double) i; + if (i % 1000 == 0) + Thread.yield(); + } + System.out.println(this); + if (--countDown == 0) return; + } + } + + public static void main(String[] args) { + // 创建新的线程池 + ExecutorService exec = Executors.newCachedThreadPool(); + for (int i = 0; i < 5 ;i++) + exec.execute(new SimplePriorities(Thread.MIN_PRIORITY));// 由线程池决定执行线程,并设置优先级最低 + exec.execute(new SimplePriorities(Thread.MAX_PRIORITY));// 由线程池决定执行线程,并设置优先级最高 + // 顺序关闭,执行以前提交的线程,不接受新的线程 + exec.shutdown(); + } +} diff --git a/src/main/java/org/javacore/thread/SingleThreadExecutor.java b/src/main/java/org/javacore/thread/SingleThreadExecutor.java new file mode 100644 index 0000000..ce69b67 --- /dev/null +++ b/src/main/java/org/javacore/thread/SingleThreadExecutor.java @@ -0,0 +1,38 @@ +package org.javacore.thread; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +/** + * Created by BYSocket on 2015/11/2. + * + * Copyright [2015] [Jeff Lee] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author Jeff Lee + * @since 2015-11-2 18:58:36 + * SingleThreadExecutor的使用-启动LiftOff线程{@link LiftOff} + */ +public class SingleThreadExecutor { + public static void main(String[] args) { + // 创建使用单个worker线程的线程池Executor + ExecutorService exec = Executors.newSingleThreadExecutor(); + for (int i = 0; i < 5; i++) + exec.execute(new LiftOff());// 由Executor决定执行给定的线程 + // 顺序关闭,执行已提交的线程,不准添加新的线程 + exec.shutdown(); + } +} diff --git a/src/main/java/org/javacore/thread/SleepRunThread.java b/src/main/java/org/javacore/thread/SleepRunThread.java new file mode 100644 index 0000000..8ee298b --- /dev/null +++ b/src/main/java/org/javacore/thread/SleepRunThread.java @@ -0,0 +1,43 @@ +package org.javacore.thread; /* + * Copyright [2015] [Jeff Lee] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Thread中start和run的区别 + * @author BYSocket + * @since 2016-01-18 15:55:00 + */ +public class SleepRunThread { + public static void main(String[] args) { + System.out.println("当前线程ID => " + Thread.currentThread().getId());
+
+ SRThread t1 = new SRThread("t1");
+ t1.start();
+ SRThread t2 = new SRThread("t2");
+ t2.run();
+ }
+}
+class SRThread extends Thread {
+ private String name;
+
+ public SRThread(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public void run() {
+ System.out.println("name:" + name +", 线程ID => " + Thread.currentThread().getId());
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/javacore/thread/SleepingTask.java b/src/main/java/org/javacore/thread/SleepingTask.java
new file mode 100644
index 0000000..6d989f4
--- /dev/null
+++ b/src/main/java/org/javacore/thread/SleepingTask.java
@@ -0,0 +1,52 @@
+package org.javacore.thread;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Created by BYSocket on 2015年11月2日.
+ *
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年11月3日 09:04:16
+ * 休眠线程sleep的使用
+ */
+public class SleepingTask extends LiftOff {
+ @Override
+ public void run(){
+ while(countDown--> 0){
+ try {
+ System.out.println(status());
+ // 老版本调用:Thread.sleep(1000);
+ TimeUnit.MICROSECONDS.sleep(100);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public static void main(String[] args) {
+ // 创建新的线程池
+ ExecutorService exec = Executors.newCachedThreadPool();
+ for (int i = 0; i < 5;i++) + exec.execute(new SleepingTask());// 由线程池决定执行线程 + // 顺序关闭,执行以前提交的线程,不接受新的线程 + exec.shutdown(); + } +} diff --git a/src/main/java/org/javacore/thread/ThreadInfo.java b/src/main/java/org/javacore/thread/ThreadInfo.java new file mode 100644 index 0000000..04edc13 --- /dev/null +++ b/src/main/java/org/javacore/thread/ThreadInfo.java @@ -0,0 +1,83 @@ +package org.javacore.thread; + + +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; + +/** + * 描述:线程优先级案例 + * Created by bysocket on 16/2/24. + */ +public class ThreadInfo { + public static void main(String[] args) { + Thread threads[] = new Thread[10]; + Thread.State status[] = new Thread.State[10]; + for (int i = 0; i < 10; i++) { + threads[i] = new Thread(new Calculator(i)); + if ((i % 2) == 0) { + threads[i].setPriority(Thread.MAX_PRIORITY); + } else { + threads[i].setPriority(Thread.MIN_PRIORITY); + } +// threads[i].setName(""); + } + + try { + // 将线程的信息写入log文件 + FileWriter fw = new FileWriter(".\\log.txt"); + PrintWriter pw = new PrintWriter(fw); + + for (int i = 0; i <10 ;i++) { + pw.println("Main: Status of Thread " + i + " : " + + threads[i].getState()); + status[i] = threads[i].getState(); + } + + // 启动线程 + for (int i = 0; i < 10 ;i++) + threads[i].start(); + + boolean finish = false; + while (!finish) { + for(int i = 0;i < 10 ;i++) { + if (threads[i].getState() != status[i]) { + writeThreadInfo(pw,threads[i],status[i]); + status[i] = threads[i].getState(); + } + } + finish = true; + for (int i = 0;i < 10 ;i++) { + finish = finish && (threads[i].getState() == Thread.State.TERMINATED);//中断 + } + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + private static void writeThreadInfo(PrintWriter pw, Thread thread, Thread.State status) { + pw.printf("Main: Id %d - $s\n",thread.getId(),thread.getName()); + pw.printf("Main: Priority: %d\n",thread.getPriority()); + pw.printf("Main: OldState: %s\n",status); + pw.printf("Main: New State: %s\n",thread.getState()); + pw.printf("*****************************************\n"); + } +} +class Calculator implements Runnable { + + private int number; + + public Calculator(int number) { + this.number = number; + } + + @Override + public void run() { + for (int i = 0;i <=10; i++) { + System.out.printf("%s: %d * %d = %d\n", + Thread.currentThread().getName(), + number, i, i * number); + } + } +} diff --git a/src/main/java/org/javacore/thread/ThreadInterrupt.java b/src/main/java/org/javacore/thread/ThreadInterrupt.java new file mode 100644 index 0000000..3d7009d --- /dev/null +++ b/src/main/java/org/javacore/thread/ThreadInterrupt.java @@ -0,0 +1,22 @@ +package org.javacore.thread; + +/** + * Created by bysocket on 16/2/24. + */ +public class ThreadInterrupt { + public static void main(String[] args) throws InterruptedException { + Thread inThread = new Thread(new InterrupThread()); + inThread.start(); + Thread.sleep(1000); + inThread.interrupt(); + } +} +class InterrupThread implements Runnable { + + private int num = 1; + @Override + public void run() { + while (true) + System.out.println("true ----> " + num++);
+ }
+}
diff --git a/src/main/java/org/javacore/thread/daemon/CleanerTask.java b/src/main/java/org/javacore/thread/daemon/CleanerTask.java
new file mode 100644
index 0000000..eba932c
--- /dev/null
+++ b/src/main/java/org/javacore/thread/daemon/CleanerTask.java
@@ -0,0 +1,52 @@
+package org.javacore.thread.daemon;
+
+import java.util.Date;
+import java.util.Deque;
+
+/**
+ * 描述:管理这个队列,如果事件超过10秒钟,就会被移除
+ * Created by bysocket on 16/3/4.
+ */
+public class CleanerTask extends Thread{
+ private Deque deque;
+
+ public CleanerTask(Deque deque) {
+ this.deque = deque;
+ setDaemon(true);
+ }
+
+ @Override
+ public void run() {
+ while (true) {
+ Date date = new Date();
+ clean(date);
+ }
+ }
+
+ /**
+ * 删除该时间前10s内创建的事件对象
+ * @param date
+ */
+ private void clean(Date date) {
+ long difference = 0;
+ boolean delete;
+ if (deque.size() == 0) {
+ return;
+ }
+ delete = false;
+
+ do {
+ Event e = deque.getLast();
+ difference = date.getTime() - e.getDate().getTime();
+ if (difference> 10000) {
+ System.out.printf("Cleaner: %s \n",e.getEvent());
+ deque.removeLast();
+ delete = true;
+ }
+ } while (difference> 10000);
+
+ if (delete) {
+ System.out.printf("Cleaner: Size of the queue: %d\n",deque.size());
+ }
+ }
+}
diff --git a/src/main/java/org/javacore/thread/daemon/DaemonTest.java b/src/main/java/org/javacore/thread/daemon/DaemonTest.java
new file mode 100644
index 0000000..3758870
--- /dev/null
+++ b/src/main/java/org/javacore/thread/daemon/DaemonTest.java
@@ -0,0 +1,23 @@
+package org.javacore.thread.daemon;
+
+import java.util.ArrayDeque;
+import java.util.Deque;
+
+/**
+ * 1. 知道3个WriteTask线程休眠后,CleanerTask才执行
+ * 2. 从结果中,可以看出队列维持在一定数量当中
+ * Created by bysocket on 16/3/4.
+ */
+public class DaemonTest {
+ public static void main(String[] args) {
+ Deque deque = new ArrayDeque();
+ WriterTask writerTask = new WriterTask(deque);
+ for (int i = 0; i < 3 ; i++) { + Thread thread = new Thread(writerTask); + thread.start(); + } + + CleanerTask cleanerTask = new CleanerTask(deque); + cleanerTask.start(); + } +} diff --git a/src/main/java/org/javacore/thread/daemon/Event.java b/src/main/java/org/javacore/thread/daemon/Event.java new file mode 100644 index 0000000..3030ccb --- /dev/null +++ b/src/main/java/org/javacore/thread/daemon/Event.java @@ -0,0 +1,28 @@ +package org.javacore.thread.daemon; + +import java.util.Date; + +/** + * 描述:事件类 + * Created by bysocket on 16/3/4. + */ +public class Event { + private Date date; + private String event; + + public Date getDate() { + return date; + } + + public void setDate(Date date) { + this.date = date; + } + + public String getEvent() { + return event; + } + + public void setEvent(String event) { + this.event = event; + } +} diff --git a/src/main/java/org/javacore/thread/daemon/WriterTask.java b/src/main/java/org/javacore/thread/daemon/WriterTask.java new file mode 100644 index 0000000..70e3e5f --- /dev/null +++ b/src/main/java/org/javacore/thread/daemon/WriterTask.java @@ -0,0 +1,33 @@ +package org.javacore.thread.daemon; + +import java.util.Date; +import java.util.Deque; +import java.util.concurrent.TimeUnit; + +/** + * 描述:写事件到一个队列 + * Created by bysocket on 16/3/4. + */ +public class WriterTask implements Runnable { + private Deque deque;
+
+ public WriterTask(Deque deque) {
+ this.deque = deque;
+ }
+
+ @Override
+ public void run() {
+ for (int i = 1; i < 100; i++) { + Event event = new Event(); + event.setDate(new Date()); + event.setEvent(String.format("The thread %s has generated an event",Thread.currentThread().getId())); + deque.addFirst(event); + + try { + TimeUnit.SECONDS.sleep(1); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } +} diff --git a/src/main/java/org/javacore/thread/join/DSLoader.java b/src/main/java/org/javacore/thread/join/DSLoader.java new file mode 100644 index 0000000..07e8019 --- /dev/null +++ b/src/main/java/org/javacore/thread/join/DSLoader.java @@ -0,0 +1,19 @@ +package org.javacore.thread.join; + +import java.util.concurrent.TimeUnit; + +/** + * Created by bysocket on 16/3/3. + */ +public class DSLoader implements Runnable { + @Override + public void run() { + System.out.println("begining the DSLoader"); + try { + TimeUnit.SECONDS.sleep(4); + } catch (InterruptedException e) { + e.printStackTrace(); + } + System.out.println("DSLoader has finished"); + } +} diff --git a/src/main/java/org/javacore/thread/join/JoinTest.java b/src/main/java/org/javacore/thread/join/JoinTest.java new file mode 100644 index 0000000..d0ed248 --- /dev/null +++ b/src/main/java/org/javacore/thread/join/JoinTest.java @@ -0,0 +1,20 @@ +package org.javacore.thread.join; + +/** + * Created by bysocket on 16/3/3. + */ +public class JoinTest { + public static void main(String[] args) throws InterruptedException { + Thread t1 = new Thread(new DSLoader()); + Thread t2 = new Thread(new NetLoader()); + + t1.start(); + t2.start(); + + //可以注释其中一个加深理解 + t1.join(); + //t2.join(); + + System.out.println("ending all"); + } +} diff --git a/src/main/java/org/javacore/thread/join/NetLoader.java b/src/main/java/org/javacore/thread/join/NetLoader.java new file mode 100644 index 0000000..951b214 --- /dev/null +++ b/src/main/java/org/javacore/thread/join/NetLoader.java @@ -0,0 +1,19 @@ +package org.javacore.thread.join; + +import java.util.concurrent.TimeUnit; + +/** + * Created by bysocket on 16/3/3. + */ +public class NetLoader implements Runnable { + @Override + public void run() { + System.out.println("begining the NetLoader"); + try { + TimeUnit.SECONDS.sleep(6); + } catch (InterruptedException e) { + e.printStackTrace(); + } + System.out.println("NetLoader has finished"); + } +} diff --git a/src/main/java/org/javacore/thread/threadlocal/SafeTask.java b/src/main/java/org/javacore/thread/threadlocal/SafeTask.java new file mode 100644 index 0000000..3037ad8 --- /dev/null +++ b/src/main/java/org/javacore/thread/threadlocal/SafeTask.java @@ -0,0 +1,36 @@ +package org.javacore.thread.threadlocal; + +import java.util.Date; +import java.util.concurrent.TimeUnit; + +/** + * 描述:看类里面说明 + * Created by bysocket on 16/3/8. + */ +public class SafeTask implements Runnable{ + /** + * ThreadLocal对象不会被所有线程共享 + * --> 线程局部变量 <-- + */ + private static ThreadLocal startDate = new ThreadLocal(){
+ /**
+ * 隐式实现初始化对象
+ * @return
+ */
+ @Override
+ protected Date initialValue() {
+ return new Date();
+ }
+ };
+
+ @Override
+ public void run() {
+ System.out.printf("Starting Thread:%s : %s\n",Thread.currentThread().getId(),startDate.get());
+ try {
+ TimeUnit.SECONDS.sleep((int) Math.rint(Math.random() * 10));
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ System.out.printf("Finish Thread:%s : %s\n",Thread.currentThread().getId(),startDate.get());
+ }
+}
diff --git a/src/main/java/org/javacore/thread/threadlocal/SafeTest.java b/src/main/java/org/javacore/thread/threadlocal/SafeTest.java
new file mode 100644
index 0000000..0202b0e
--- /dev/null
+++ b/src/main/java/org/javacore/thread/threadlocal/SafeTest.java
@@ -0,0 +1,23 @@
+package org.javacore.thread.threadlocal;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 描述:可以看到线程每个有不同的启动时间,但是结束时间也会不相同.
+ * Created by bysocket on 16/3/8.
+ */
+public class SafeTest {
+ public static void main(String[] args) {
+ SafeTask task = new SafeTask();
+ for (int i = 0 ; i < 10; i++) { + Thread thread = new Thread(task); + thread.start(); + + try { + TimeUnit.SECONDS.sleep(2); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } +} diff --git a/src/main/java/org/javacore/thread/threadlocal/UnsafeTask.java b/src/main/java/org/javacore/thread/threadlocal/UnsafeTask.java new file mode 100644 index 0000000..2aed77d --- /dev/null +++ b/src/main/java/org/javacore/thread/threadlocal/UnsafeTask.java @@ -0,0 +1,24 @@ +package org.javacore.thread.threadlocal; + +import java.util.Date; +import java.util.concurrent.TimeUnit; + +/** + * 描述:私有变量会被所有线程共享 + * Created by bysocket on 16/3/8. + */ +public class UnsafeTask implements Runnable{ + private Date startDate; + + @Override + public void run() { + startDate = new Date(); + System.out.printf("Starting Thread:%s : %s\n",Thread.currentThread().getId(),startDate); + try { + TimeUnit.SECONDS.sleep((int) Math.rint(Math.random() * 10)); + } catch (InterruptedException e) { + e.printStackTrace(); + } + System.out.printf("Finish Thread:%s : %s\n",Thread.currentThread().getId(),startDate); + } +} diff --git a/src/main/java/org/javacore/thread/threadlocal/UnsafeTest.java b/src/main/java/org/javacore/thread/threadlocal/UnsafeTest.java new file mode 100644 index 0000000..0bb44f9 --- /dev/null +++ b/src/main/java/org/javacore/thread/threadlocal/UnsafeTest.java @@ -0,0 +1,23 @@ +package org.javacore.thread.threadlocal; + +import java.util.concurrent.TimeUnit; + +/** + * 描述:可以看到线程每个有不同的启动时间,但是结束时间会有相同. + * Created by bysocket on 16/3/8. + */ +public class UnsafeTest { + public static void main(String[] args) { + UnsafeTask task = new UnsafeTask(); + for (int i = 0 ; i < 10; i++) { + Thread thread = new Thread(task); + thread.start(); + + try { + TimeUnit.SECONDS.sleep(2); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } +} diff --git a/src/main/java/org/javacore/thread/uncaughtexp/ExceptionHadler.java b/src/main/java/org/javacore/thread/uncaughtexp/ExceptionHadler.java new file mode 100644 index 0000000..a60c42c --- /dev/null +++ b/src/main/java/org/javacore/thread/uncaughtexp/ExceptionHadler.java @@ -0,0 +1,19 @@ +package org.javacore.thread.uncaughtexp; + +import java.lang.Thread.UncaughtExceptionHandler; + +/** + * 描述:处理运行时异常的类 + * Created by bysocket on 16/3/4. + */ +public class ExceptionHadler implements UncaughtExceptionHandler{ + @Override + public void uncaughtException(Thread t, Throwable e) { + System.out.printf("An exception has been captured\n"); + System.out.printf("Thread: %s\n",t.getId()); + System.out.printf("Exception: %s: %s\n",e.getClass().getName(),e.getMessage()); + System.out.printf("Stack Trace: \n"); + e.printStackTrace(System.out); + System.out.printf("Thread status: %s\n",t.getState()); + } +} diff --git a/src/main/java/org/javacore/thread/uncaughtexp/UncaughtTask.java b/src/main/java/org/javacore/thread/uncaughtexp/UncaughtTask.java new file mode 100644 index 0000000..696a822 --- /dev/null +++ b/src/main/java/org/javacore/thread/uncaughtexp/UncaughtTask.java @@ -0,0 +1,12 @@ +package org.javacore.thread.uncaughtexp; + +/** + * 描述:抛出运行时异常的线程类 + * Created by bysocket on 16/3/4. + */ +public class UncaughtTask implements Runnable { + @Override + public void run() { + int numero = Integer.parseInt("TTTT"); + } +} diff --git a/src/main/java/org/javacore/thread/uncaughtexp/UncaughtTest.java b/src/main/java/org/javacore/thread/uncaughtexp/UncaughtTest.java new file mode 100644 index 0000000..059f074 --- /dev/null +++ b/src/main/java/org/javacore/thread/uncaughtexp/UncaughtTest.java @@ -0,0 +1,14 @@ +package org.javacore.thread.uncaughtexp; + +/** + * 描述:实现异常类Test + * Created by bysocket on 16/3/4. + */ +public class UncaughtTest { + public static void main(String[] args) { + UncaughtTask uncaughtTask = new UncaughtTask(); + Thread thread = new Thread(uncaughtTask); + thread.setUncaughtExceptionHandler(new ExceptionHadler()); + thread.start(); + } +} diff --git a/src/main/java/org/jee/rpc/EchoService.java b/src/main/java/org/jee/rpc/EchoService.java new file mode 100644 index 0000000..e329980 --- /dev/null +++ b/src/main/java/org/jee/rpc/EchoService.java @@ -0,0 +1,9 @@ +package org.jee.rpc; + +/** + * 描述:服务Echo接口类 + * Created by bysocket on 16/2/28. + */ +public interface EchoService { + String echo(String ping); +} diff --git a/src/main/java/org/jee/rpc/EchoServiceImpl.java b/src/main/java/org/jee/rpc/EchoServiceImpl.java new file mode 100644 index 0000000..0403ea9 --- /dev/null +++ b/src/main/java/org/jee/rpc/EchoServiceImpl.java @@ -0,0 +1,12 @@ +package org.jee.rpc; + +/** + * 描述:服务Echo实现类 + * Created by bysocket on 16/2/28. + */ +public class EchoServiceImpl implements EchoService { + @Override + public String echo(String ping) { + return ping != null ? ping + " --> I am ok." : "I am ok.";
+ }
+}
diff --git a/src/main/java/org/jee/rpc/RpcExporter.java b/src/main/java/org/jee/rpc/RpcExporter.java
new file mode 100644
index 0000000..567e187
--- /dev/null
+++ b/src/main/java/org/jee/rpc/RpcExporter.java
@@ -0,0 +1,107 @@
+package org.jee.rpc;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.lang.reflect.Method;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+
+/**
+ * 描述:RPC服务发布者
+ * Created by bysocket on 16/2/28.
+ */
+public class RpcExporter {
+ // 创建线程池
+ static Executor executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
+
+ public static void exporter(String hostName,int port) throws IOException {
+ ServerSocket serverSocket = new ServerSocket();
+ serverSocket.bind(new InetSocketAddress(hostName,port));
+ try {
+ while (true) {
+ /**
+ * 监听Client的TCP连接,将其封装成Task,由线程池执行.
+ */
+ executor.execute(new ExporterTask(serverSocket.accept()));
+ }
+ } finally {
+ serverSocket.close();
+ }
+ }
+
+ /**
+ * 线程Task:
+ * 1. 将客户端发送的二进制流反序列化成对象,反射调用服务实现者,获取执行结果
+ * 2. 将执行结果对象反序列化,通过Socket发送给客户端
+ * 3. 远程服务调用完成之后,释放Socket等连接资源,防止句柄泄漏
+ */
+ private static class ExporterTask implements Runnable {
+ Socket client = null;
+ public ExporterTask(Socket accept) {
+ this.client = accept;
+ }
+
+ @Override
+ public void run() {
+ ObjectInputStream input = null;
+ ObjectOutputStream output = null;
+ try {
+ // 对象输入流
+ input = new ObjectInputStream(client.getInputStream());
+
+ // 获取接口名
+ String interfaceName = input.readUTF();
+ // 获取方法名
+ String methodName = input.readUTF();
+ // 获取方法的参数数组
+ Class>[] paramTypes = (Class>[]) input.readObject();
+ // 获取传入参数对象数组
+ Object[] arguments = (Object[]) input.readObject();
+
+ // 获取服务对象类
+ Class> service = Class.forName(interfaceName);
+ // 获取服务方法
+ Method method = service.getMethod(methodName,paramTypes);
+ // 获取服务方法返回对象
+ Object result = method.invoke(service.newInstance(),arguments);
+
+ // 对象输出流
+ output = new ObjectOutputStream(client.getOutputStream());
+ output.writeObject(result);
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ // 关闭流的操作
+ if (output != null) {
+ try {
+ output.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ if (input != null) {
+ try {
+ input.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ if (client != null) {
+ try {
+ client.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/org/jee/rpc/RpcImporter.java b/src/main/java/org/jee/rpc/RpcImporter.java
new file mode 100644
index 0000000..c4359fc
--- /dev/null
+++ b/src/main/java/org/jee/rpc/RpcImporter.java
@@ -0,0 +1,60 @@
+package org.jee.rpc;
+
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+
+/**
+ * 描述:Rpc本地服务代理类
+ * 1. 将本地接口调用转化为JDK的动态调用,在动态调用中实现接口的远程调用
+ * 2. 创建Socket客户端,根据制定地址连接远程服务提供者
+ * 3. 将远程服务调用所需的接口类,方法名,参数列表等编码后发送给服务提供者
+ * 4. 同步阻塞等待服务端返回应答,获取应答后返回
+ * Created by bysocket on 16/2/29.
+ */
+public class RpcImporter {
+ public S importer(final Class> serviceClass, final InetSocketAddress address) {
+ // JDK动态代理,实现接口的远程调用
+ return (S) Proxy.newProxyInstance(serviceClass.getClassLoader(),
+ new Class>[]{serviceClass.getInterfaces()[0]},
+ new InvocationHandler() {
+
+ @Override
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ Socket socket = null;
+ ObjectOutputStream output = null;
+ ObjectInputStream input = null;
+
+ try {
+ // 连接远程服务提供者
+ socket = new Socket();
+ socket.connect(address);
+
+ // 对象输出流
+ output = new ObjectOutputStream(socket.getOutputStream());
+ output.writeUTF(serviceClass.getName());
+ output.writeUTF(method.getName());
+ output.writeObject(method.getParameterTypes());
+ output.writeObject(args);
+
+ input = new ObjectInputStream(socket.getInputStream());
+ return input.readObject();
+ } finally {
+ if (socket != null) {
+ socket.close();
+ }
+ if (output != null) {
+ output.close();
+ }
+ if (input != null) {
+ input.close();
+ }
+ }
+ }
+ });
+ }
+}
diff --git a/src/main/java/org/jee/rpc/RpcTest.java b/src/main/java/org/jee/rpc/RpcTest.java
new file mode 100644
index 0000000..07fef5b
--- /dev/null
+++ b/src/main/java/org/jee/rpc/RpcTest.java
@@ -0,0 +1,31 @@
+package org.jee.rpc;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+
+/**
+ * 描述:RPC测试代码类
+ * Created by bysocket on 16/2/29.
+ */
+public class RpcTest {
+ public static void main(String[] args) {
+ // 启动服务提供者
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ RpcExporter.exporter("localhost",8088);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }).start();
+
+ // 创建服务本地代理
+ RpcImporter importer = new RpcImporter();
+
+ // 从服务本地代理获取服务对象类
+ EchoService echo = importer.importer(EchoServiceImpl.class,new InetSocketAddress("localhost",8088));
+ System.out.println(echo.echo("Are you OK?"));
+ }
+}
diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..e69de29