Java IO流详尽解(二)
来源:互联网 发布:企业邮箱绑定域名 编辑:程序博客网 时间:2024/06/06 02:22
【案例】使用System.err重定向
import
java.io.File;
import
java.io.FileNotFoundException;
import
java.io.FileOutputStream;
import
java.io.PrintStream;
/**
*System.err重定向这个例子也提示我们可以使用这种方法保存错误信息
* */
public
class
systemErr{
public
static
void
main(String[] args){
File file =
new
File(
"d:"
+ File.separator +
"hello.txt"
);
System.err.println(
"这些在控制台输出"
);
try
{
System.setErr(
new
PrintStream(
new
FileOutputStream(file)));
}
catch
(FileNotFoundException e){
e.printStackTrace();
}
System.err.println(
"这些在文件中才能看到哦!"
);
}
}
【案例】System.in重定向
import
java.io.File;
import
java.io.FileInputStream;
import
java.io.FileNotFoundException;
import
java.io.IOException;
/**
*System.in重定向
* */
public
class
systemIn{
public
static
void
main(String[] args){
File file =
new
File(
"d:"
+ File.separator +
"hello.txt"
);
if
(!file.exists()){
return
;
}
else
{
try
{
System.setIn(newFileInputStream(file));
}
catch
(FileNotFoundException e){
e.printStackTrace();
}
byte
[] bytes =
new
byte
[
1024
];
int
len =
0
;
try
{
len = System.in.read(bytes);
}
catch
(IOException e){
e.printStackTrace();
}
System.out.println(
"读入的内容为:"
+
new
String(bytes,
0
, len));
}
}
}
5.字符输入流Reader
定义和说明:
在上面的继承关系图中可以看出:
Reader 是所有的输入字符流的父类,它是一个抽象类。
CharReader、StringReader是两种基本的介质流,它们分别将Char 数组、String中读取数据。PipedReader 是从与其它线程共用的管道中读取数据。
BufferedReader 很明显就是一个装饰器,它和其子类负责装饰其它Reader 对象。
FilterReader 是所有自定义具体装饰流的父类,其子类PushbackReader 对Reader 对象进行装饰,会增加一个行号。
InputStreamReader 是一个连接字节流和字符流的桥梁,它将字节流转变为字符流。FileReader可以说是一个达到此功能、常用的工具类,在其源代码中明显使用了将FileInputStream 转变为Reader 的方法。我们可以从这个类中得到一定的技巧。Reader 中各个类的用途和使用方法基本和InputStream 中的类使用一致。后面会有Reader 与InputStream 的对应关系。
实例操作演示:
【案例】从文件中读取内容
/**
* 字符流
* 从文件中读出内容
* */
import
java.io.*;
class
hello{
public
static
void
main(String[] args)
throws
IOException {
String fileName=
"D:"
+File.separator+
"hello.txt"
;
File f=
new
File(fileName);
char
[] ch=
new
char
[
100
];
Reader read=
new
FileReader(f);
int
count=read.read(ch);
read.close();
System.out.println(
"读入的长度为:"
+count);
System.out.println(
"内容为"
+
new
String(ch,
0
,count));
}
}
注意:当然最好采用循环读取的方式,因为我们有时候不知道文件到底有多大。
【案例】以循环方式从文件中读取内容
/**
* 字符流
* 从文件中读出内容
* */
import
java.io.*;
class
hello{
public
static
void
main(String[] args)
throws
IOException {
String fileName=
"D:"
+File.separator+
"hello.txt"
;
File f=
new
File(fileName);
char
[] ch=
new
char
[
100
];
Reader read=
new
FileReader(f);
int
temp=
0
;
int
count=
0
;
while
((temp=read.read())!=(-
1
)){
ch[count++]=(
char
)temp;
}
read.close();
System.out.println(
"内容为"
+
new
String(ch,
0
,count));
}
}
【案例】BufferedReader的小例子
注意:BufferedReader只能接受字符流的缓冲区,因为每一个中文需要占据两个字节,所以需要将System.in这个字节输入流变为字符输入流,采用:
BufferedReader buf = new BufferedReader(newInputStreamReader(System.in));
下面是一个实例:
import
java.io.BufferedReader;
import
java.io.IOException;
import
java.io.InputStreamReader;
/**
* 使用缓冲区从键盘上读入内容
* */
public
class
BufferedReaderDemo{
public
static
void
main(String[] args){
BufferedReader buf =
new
BufferedReader(
newInputStreamReader(System.in));
String str =
null
;
System.out.println(
"请输入内容"
);
try
{
str = buf.readLine();
}
catch
(IOException e){
e.printStackTrace();
}
System.out.println(
"你输入的内容是:"
+ str);
}
}
【案例】Scanner类实例
import
java.util.Scanner;
/**
*Scanner的小例子,从键盘读数据
* */
public
class
ScannerDemo{
publicstatic
void
main(String[] args){
Scanner sca =
new
Scanner(System.in);
// 读一个整数
int
temp = sca.nextInt();
System.out.println(temp);
//读取浮点数
float
flo=sca.nextFloat();
System.out.println(flo);
//读取字符
//...等等的,都是一些太基础的,就不师范了。
}
}
【案例】Scanner类从文件中读出内容
import
java.io.File;
import
java.io.FileNotFoundException;
import
java.util.Scanner;
/**
*Scanner的小例子,从文件中读内容
* */
public
class
ScannerDemo{
public
static
void
main(String[] args){
File file =
new
File(
"d:"
+ File.separator +
"hello.txt"
);
Scanner sca =
null
;
try
{
sca =
new
Scanner(file);
}
catch
(FileNotFoundException e){
e.printStackTrace();
}
String str = sca.next();
System.out.println(
"从文件中读取的内容是:"
+ str);
}
}
6.字符输出流Writer
定义和说明:
在上面的关系图中可以看出:
Writer 是所有的输出字符流的父类,它是一个抽象类。
CharArrayWriter、StringWriter 是两种基本的介质流,它们分别向Char 数组、String 中写入数据。
PipedWriter 是向与其它线程共用的管道中写入数据,
BufferedWriter 是一个装饰器为Writer 提供缓冲功能。
PrintWriter 和PrintStream 极其类似,功能和使用也非常相似。
OutputStreamWriter 是OutputStream 到Writer 转换的桥梁,它的子类FileWriter 其实就是一个实现此功能的具体类(具体可以研究一SourceCode)。功能和使用和OutputStream 极其类似,后面会有它们的对应图。
实例操作演示:
【案例】向文件中写入数据
/**
* 字符流
* 写入数据
* */
import
java.io.*;
class
hello{
public
static
void
main(String[] args)
throws
IOException {
String fileName=
"D:"
+File.separator+
"hello.txt"
;
File f=
new
File(fileName);
Writer out =
new
FileWriter(f);
String str=
"hello"
;
out.write(str);
out.close();
}
}
注意:这个例子上之前的例子没什么区别,只是你可以直接输入字符串,而不需要你将字符串转化为字节数组。当你如果想问文件中追加内容的时候,可以使用将上面的声明out的哪一行换为:
Writer out =new FileWriter(f,true);
这样,当你运行程序的时候,会发现文件内容变为:hellohello如果想在文件中换行的话,需要使用“\r\n”比如将str变为String str="\r\nhello";这样文件追加的str的内容就会换行了。
7.字符流的输入与输出的对应
8.字符流与字节流转换
转换流的特点:
(1)其是字符流和字节流之间的桥梁
(2)可对读取到的字节数据经过指定编码转换成字符
(3)可对读取到的字符数据经过指定编码转换成字节
何时使用转换流?
当字节和字符之间有转换动作时;
流操作的数据需要编码或解码时。
具体的对象体现:
InputStreamReader:字节到字符的桥梁
OutputStreamWriter:字符到字节的桥梁
这两个流对象是字符体系中的成员,它们有转换作用,本身又是字符流,所以在构造的时候需要传入字节流对象进来。
字节流和字符流转换实例:
【案例】将字节输出流转化为字符输出流
/**
* 将字节输出流转化为字符输出流
* */
import
java.io.*;
class
hello{
public
static
void
main(String[] args)
throws
IOException {
String fileName=
"d:"
+File.separator+
"hello.txt"
;
File file=
new
File(fileName);
Writer out=
new
OutputStreamWriter(
new
FileOutputStream(file));
out.write(
"hello"
);
out.close();
}
}
【案例】将字节输入流转换为字符输入流
/**
* 将字节输入流变为字符输入流
* */
import
java.io.*;
class
hello{
public
static
void
main(String[] args)
throws
IOException {
String fileName=
"d:"
+File.separator+
"hello.txt"
;
File file=
new
File(fileName);
Reader read=
new
InputStreamReader(
new
FileInputStream(file));
char
[] b=
new
char
[
100
];
int
len=read.read(b);
System.out.println(
new
String(b,
0
,len));
read.close();
}
}
9.File类
File类是对文件系统中文件以及文件夹进行封装的对象,可以通过对象的思想来操作文件和文件夹。 File类保存文件或目录的各种元数据信息,包括文件名、文件长度、最后修改时间、是否可读、获取当前文件的路径名,判断指定文件是否存在、获得当前目录中的文件列表,创建、删除文件和目录等方法。
【案例 】创建一个文件
import
java.io.*;
class
hello{
public
static
void
main(String[] args) {
File f=
new
File(
"D:\\hello.txt"
);
try
{
f.createNewFile();
}
catch
(Exception e) {
e.printStackTrace();
}
}
}
【案例2】File类的两个常量
import
java.io.*;
class
hello{
public
static
void
main(String[] args) {
System.out.println(File.separator);
System.out.println(File.pathSeparator);
}
}
此处多说几句:有些同学可能认为,我直接在windows下使用\进行分割不行吗?当然是可以的。但是在linux下就不是\了。所以,要想使得我们的代码跨平台,更加健壮,所以,大家都采用这两个常量吧,其实也多写不了几行。
【案例3】File类中的常量改写案例1的代码:
import
java.io.*;
class
hello{
public
static
void
main(String[] args) {
String fileName=
"D:"
+File.separator+
"hello.txt"
;
File f=
new
File(fileName);
try
{
f.createNewFile();
}
catch
(Exception e) {
e.printStackTrace();
}
}
}
【案例4】删除一个文件(或者文件夹)
import
java.io.*;
class
hello{
public
static
void
main(String[] args) {
String fileName=
"D:"
+File.separator+
"hello.txt"
;
File f=
new
File(fileName);
if
(f.exists()){
f.delete();
}
else
{
System.out.println(
"文件不存在"
);
}
}
}
【案例5】创建一个文件夹
/**
* 创建一个文件夹
* */
import
java.io.*;
class
hello{
public
static
void
main(String[] args) {
String fileName=
"D:"
+File.separator+
"hello"
;
File f=
new
File(fileName);
f.mkdir();
}
}
【案例6】列出目录下的所有文件
/**
* 使用list列出指定目录的全部文件
* */
import
java.io.*;
class
hello{
public
static
void
main(String[] args) {
String fileName=
"D:"
+File.separator;
File f=
new
File(fileName);
String[] str=f.list();
for
(
int
i =
0
; i < str.length; i++) {
System.out.println(str[i]);
}
}
}
注意使用list返回的是String数组,。而且列出的不是完整路径,如果想列出完整路径的话,需要使用listFiles.它返回的是File的数组。
【案例7】列出指定目录的全部文件(包括隐藏文件):
/**
* 使用listFiles列出指定目录的全部文件
* listFiles输出的是完整路径
* */
import
java.io.*;
class
hello{
public
static
void
main(String[] args) {
String fileName=
"D:"
+File.separator;
File f=
new
File(fileName);
File[] str=f.listFiles();
for
(
int
i =
0
; i < str.length; i++) {
System.out.println(str[i]);
}
}
}
【案例8】判断一个指定的路径是否为目录
/**
* 使用isDirectory判断一个指定的路径是否为目录
* */
import
java.io.*;
class
hello{
public
static
void
main(String[] args) {
String fileName=
"D:"
+File.separator;
File f=
new
File(fileName);
if
(f.isDirectory()){
System.out.println(
"YES"
);
}
else
{
System.out.println(
"NO"
);
}
}
}
【案例9】递归搜索指定目录的全部内容,包括文件和文件夹
* 列出指定目录的全部内容
* */
import
java.io.*;
class
hello{
public
static
void
main(String[] args) {
String fileName=
"D:"
+File.separator;
File f=
new
File(fileName);
print(f);
}
public
static
void
print(File f){
if
(f!=
null
){
if
(f.isDirectory()){
File[] fileArray=f.listFiles();
if
(fileArray!=
null
){
for
(
int
i =
0
; i <filearray.length; i++)=
""
{=
""
递归调用=
""
print(filearray[i]);=
""
}=
""
else
{=
""
system.out.println(f);=
""
}<=
""
pre=
""
>
<p></p>
<h2>
10
.RandomAccessFile类</h2>
<p>该对象并不是流体系中的一员,其封装了字节流,同时还封装了一个缓冲区(字符数组),通过内部的指针来操作字符数组中的数据。该对象特点:</p>
<p>该对象只能操作文件,所以构造函数接收两种类型的参数:a.字符串文件路径;b.File对象。</p>
<p>该对象既可以对文件进行读操作,也能进行写操作,在进行对象实例化时可指定操作模式(r,rw)</p>
<p>注意:该对象在实例化时,如果要操作的文件不存在,会自动创建;如果文件存在,写数据未指定位置,会从头开始写,即覆盖原有的内容。可以用于多线程下载或多个线程同时写数据到文件。</p>
<p align=
"left"
>【案例】使用RandomAccessFile写入文件</p>
<p align=
"left"
></p>
<pre
class
=
"brush:java;"
>
/**
* 使用RandomAccessFile写入文件
* */
import
java.io.*;
class
hello{
public
static
void
main(String[]args)
throws
IOException {
StringfileName=
"D:"
+File.separator+
"hello.txt"
;
File f=
new
File(fileName);
RandomAccessFile demo=newRandomAccessFile(f,
"rw"
);
demo.writeBytes(
"asdsad"
);
demo.writeInt(
12
);
demo.writeBoolean(
true
);
demo.writeChar(
'A'
);
demo.writeFloat(
1
.21f);
demo.writeDouble(
12.123
);
demo.close();
}
}</pre>
<p></p>
<h1>Java IO流的高级概念</h1>
<h2>编码问题</h2>
<p>【案例 】取得本地的默认编码</p>
<p></p>
<pre
class
=
"brush:java;"
>
/**
* 取得本地的默认编码
* */
publicclass CharSetDemo{
public
static
void
main(String[] args){
System.out.println(
"系统默认编码为:"
+ System.getProperty(
"file.encoding"
));
}
}</pre>
<p></p>
<p>【案例 】乱码的产生</p>
<p></p>
<pre
class
=
"brush:java;"
>
import
java.io.File;
import
java.io.FileOutputStream;
import
java.io.IOException;
import
java.io.OutputStream;
/**
* 乱码的产生
* */
public
class
CharSetDemo2{
public
static
void
main(String[] args)
throws
IOException{
File file =
new
File(
"d:"
+ File.separator +
"hello.txt"
);
OutputStream out =
new
FileOutputStream(file);
byte
[] bytes =
"你好"
.getBytes(
"ISO8859-1"
);
out.write(bytes);
out.close();
}
//输出结果为乱码,系统默认编码为GBK,而此处编码为ISO8859-1
}</pre>
<h2>对象的序列化</h2>
<p>对象序列化就是把一个对象变为二进制数据流的一种方法。</p>
<p>一个类要想被序列化,就行必须实现java.io.Serializable接口。虽然这个接口中没有任何方法,就如同之前的cloneable接口一样。实现了这个接口之后,就表示这个类具有被序列化的能力。先让我们实现一个具有序列化能力的类吧:</p>
<p>【案例 】实现具有序列化能力的类</p>
<p></p>
<pre
class
=
"brush:java;"
>
import
java.io.*;
/**
* 实现具有序列化能力的类
* */
public
class
SerializableDemo
implements
Serializable{
public
SerializableDemo(){
}
publicSerializableDemo(String name,
int
age){
this
.name=name;
this
.age=age;
}
@Override
public
String toString(){
return
"姓名:"
+name+
" 年龄:"
+age;
}
private
String name;
private
int
age;
}</pre>
<p></p>
<p>【案例 】序列化一个对象 – ObjectOutputStream</p>
<p></p>
<pre
class
=
"brush:java;"
>
import
java.io.Serializable;
import
java.io.File;
import
java.io.FileOutputStream;
import
java.io.IOException;
import
java.io.ObjectOutputStream;
/**
* 实现具有序列化能力的类
* */
public
class
Person
implements
Serializable{
public
Person(){
}
public
Person(String name,
int
age){
this
.name = name;
this
.age = age;
}
@Override
public
String toString(){
return
"姓名:"
+name +
" 年龄:"
+age;
}
private
String name;
private
int
age;
}
/**
* 示范ObjectOutputStream
* */
public
class
ObjectOutputStreamDemo{
public
static
voidmain(String[] args)
throws
IOException{
File file = newFile(
"d:"
+ File.separator +
"hello.txt"
);
ObjectOutputStream oos=
new
ObjectOutputStream(
new
FileOutputStream(
file));
oos.writeObject(newPerson(
"rollen"
,
20
));
oos.close();
}
}</pre>
<p></p>
<p>【案例 】反序列化—ObjectInputStream</p>
<p></p>
<pre
class
=
"brush:java;"
>
import
java.io.File;
import
java.io.FileInputStream;
import
java.io.ObjectInputStream;
/**
* ObjectInputStream示范
* */
public
class
ObjectInputStreamDemo{
public
static
voidmain(String[] args)
throws
Exception{
File file =
new
File(
"d:"
+File.separator +
"hello.txt"
);
ObjectInputStreaminput =
new
ObjectInputStream(
new
FileInputStream(
file));
Object obj =input.readObject();
input.close();
System.out.println(obj);
}
}</pre>
<p></p>
<p>注意:被Serializable接口声明的类的对象的属性都将被序列化,但是如果想自定义序列化的内容的时候,就需要实现Externalizable接口。</p>
<p>当一个类要使用Externalizable这个接口的时候,这个类中必须要有一个无参的构造函数,如果没有的话,在构造的时候会产生异常,这是因为在反序列话的时候会默认调用无参的构造函数。</p>
<p>现在我们来演示一下序列化和反序列话:</p>
<p>【案例 】使用Externalizable来定制序列化和反序列化操作</p>
<p></p>
<pre
class
=
"brush:java;"
>
package
IO;
import
java.io.Externalizable;
import
java.io.File;
import
java.io.FileInputStream;
import
java.io.FileOutputStream;
import
java.io.IOException;
import
java.io.ObjectInput;
import
java.io.ObjectInputStream;
import
java.io.ObjectOutput;
import
java.io.ObjectOutputStream;
/**
* 序列化和反序列化的操作
* */
public
class
ExternalizableDemo{
public
static
voidmain(String[] args)
throws
Exception{
ser();
// 序列化
dser();
// 反序列话
}
public
static
void
ser()
throws
Exception{
File file = newFile(
"d:"
+ File.separator +
"hello.txt"
);
ObjectOutputStream out=
new
ObjectOutputStream(
new
FileOutputStream(
file));
out.writeObject(newPerson(
"rollen"
,
20
));
out.close();
}
public
static
void
dser()
throws
Exception{
File file = newFile(
"d:"
+ File.separator +
"hello.txt"
);
ObjectInputStreaminput =
new
ObjectInputStream(
new
FileInputStream(
file));
Object obj =input.readObject();
input.close();
System.out.println(obj);
}
}
class
Person
implements
Externalizable{
public
Person(){
}
public
Person(String name,
int
age){
this
.name = name;
this
.age = age;
}
@Override
public
String toString(){
return
"姓名:"
+name +
" 年龄:"
+age;
}
// 复写这个方法,根据需要可以保存的属性或者具体内容,在序列化的时候使用
@Override
public
voidwriteExternal(ObjectOutput out)
throws
IOException{
out.writeObject(
this
.name);
out.writeInt(age);
}
// 复写这个方法,根据需要读取内容 反序列话的时候需要
@Override
public
voidreadExternal(ObjectInput in)
throws
IOException,
ClassNotFoundException{
this
.name = (String)in.readObject();
this
.age =in.readInt();
}
private
String name;
private
int
age;
}</pre>
<p></p>
<p>注意:Serializable接口实现的操作其实是吧一个对象中的全部属性进行序列化,当然也可以使用我们上使用是Externalizable接口以实现部分属性的序列化,但是这样的操作比较麻烦,</p>
<p>当我们使用Serializable接口实现序列化操作的时候,如果一个对象的某一个属性不想被序列化保存下来,那么我们可以使用
transient
关键字进行说明:</p>
<p>【案例 】使用
transient
关键字定制序列化和反序列化操作</p>
<p></p>
<pre
class
=
"brush:java;"
>
package
IO;
import
java.io.File;
import
java.io.FileInputStream;
import
java.io.FileOutputStream;
import
java.io.ObjectInputStream;
import
java.io.ObjectOutputStream;
import
java.io.Serializable;
/**
* 序列化和反序列化的操作
* */
public
class
serDemo{
public
static
voidmain(String[] args)
throws
Exception{
ser();
// 序列化
dser();
// 反序列话
}
public
static
void
ser()
throws
Exception{
File file = newFile(
"d:"
+ File.separator +
"hello.txt"
);
ObjectOutputStream out=
new
ObjectOutputStream(
new
FileOutputStream(
file));
out.writeObject(newPerson1(
"rollen"
,
20
));
out.close();
}
public
static
void
dser()
throws
Exception{
File file = newFile(
"d:"
+ File.separator +
"hello.txt"
);
ObjectInputStreaminput =
new
ObjectInputStream(
new
FileInputStream(
file));
Object obj =input.readObject();
input.close();
System.out.println(obj);
}
}
class
Person1
implements
Serializable{
public
Person1(){
}
public
Person1(Stringname,
int
age){
this
.name = name;
this
.age = age;
}
@Override
public
String toString(){
return
"姓名:"
+name +
" 年龄:"
+age;
}
// 注意这里
private
transient
Stringname;
private
int
age;
}</pre>
<p></p>
<p>【运行结果】:</p>
<p>姓名:
null
年龄:
20
</p>
<p>【案例 】序列化一组对象</p>
<p></p>
<pre
class
=
"brush:java;"
>
import
java.io.File;
import
java.io.FileInputStream;
import
java.io.FileOutputStream;
import
java.io.ObjectInputStream;
import
java.io.ObjectOutputStream;
import
java.io.Serializable;
/**
* 序列化一组对象
* */
public
class
SerDemo1{
public
static
voidmain(String[] args)
throws
Exception{
Student[] stu = { newStudent(
"hello"
,
20
),
new
Student(
"world"
,
30
),
newStudent(
"rollen"
,
40
) };
ser(stu);
Object[] obj = dser();
for
(
int
i =
0
; i <obj.length; ++i){=
""
student=
""
s=
"(Student)"
obj[i];=
""
system.out.println(s);=
""
}=
""
序列化=
""
public
=
""
static
=
""
voidser(object[]=
""
obj)=
""
throws
=
""
exception{=
""
file=
""
+=
""
file.separator=
""
"hello.txt"
);=
""
objectoutputstream=
""
out=
"new"
objectoutputstream(
new
=
""
fileoutputstream(=
""
file));=
""
out.writeobject(obj);=
""
out.close();=
""
反序列化=
""
object[]dser()=
""
objectinputstreaminput=
"new"
objectinputstream(
new
=
""
fileinputstream(=
""
object[]=
""
obj=
"(Object[])"
input.readobject();=
""
input.close();=
""
return
=
""
obj;=
""
class
=
""
implements
=
""
serializable{=
""
student(){=
""
student(stringname,=
""
int
=
""
age){=
""
this
.name=
"name;"
this
.age=
"age;"
@override
=
""
string=
""
tostring(){=
""
"姓名:="
" "
=
""
name=
""
年龄:
"="
" age;="
" private="
" name;="
" }<="
" pre="
">
<h1>参考文献:</h1>
<p>
1
、http:
//www.cnblogs.com/rollenholt/archive/2011/09/11/2173787.html</p>
<p>
2
、http:
//www.cnblogs.com/oubo/archive/2012/01/06/2394638.html</p>
<h3></h3> </obj.length;></pre></filearray.length;>
- Java IO流详尽解(二)
- Java IO流详尽解(一)
- Java IO流详尽解析
- Java IO流详尽解析
- Java IO流详尽解析
- Java IO流详尽解析
- Java IO流详尽解析
- Java IO流详尽解析
- Java IO流详尽解析
- java IO流详尽解析
- Java IO流详尽解析
- Java IO流详尽解析
- Java IO流详尽解析
- Java 开发实践 IO流 详尽解析
- java------IO流(二)
- Java IO流(二)
- JAVA--IO流(二)
- JAVA--IO流(二)
- 生成螺旋矩阵
- 1640: [Usaco2007 Nov]Best Cow Line 队列变换
- 软考之后的“四分”总结
- js window对象属性和方法记忆
- oracle的一些杂碎知识点-02
- Java IO流详尽解(二)
- ACM篇:POJ 1928--The Peanuts
- LeetCode #199 - Binary Tree Right Side View - Medium
- Eclipse代码自动提示
- MySQL服务篇
- 最初的一个项目
- Spark系列修炼---入门笔记3
- 基链接<base href="/Ssm2/">的作用
- Hadoop 2.x高可用性部署