JavaSE前半部分

有main()方法的的类一定是主类,主类不一定是public类
任何一种可运行.class文件的都可称为JVM
若有public类,文件名要与之相同,没有则可以任意命名
DOS下运行需要java 主类名

数据类型

数据通过变量名来调用,用变量名来代表该数据的内存位置
由于数据所需内存容量不同,所以通过数据类型来区分
数据类型不同–>数据结构/存储方式不同–>算法不同

byte8位范围-128(-27)~127(27-1)
short16位范围-215~215-1
int32位范围-231~231-1
long64位范围-263~263-1
float32位
double(默认)64位
char字符型存储单字符 占据两个字节,是16位无符号的整数,有216=65536个,范围为0~65535。在Unicode码中用16进制表示,范围为\u0000到\uFFFF。

所有关系运算的返回值均为boolean类型的值(1Byte)

常量以final修饰,表示不可更改
整数相除默认为整数
字符串转数值型:Xxx.parseXxx(String s),Xxx表示包装类
数值型转字符串:String s = “”+数值

Scanner类

next()方法以回车、空格、Tab键作为结束符,nextLine()方法以回车作为结束符

逻辑运算符

简洁运算符(&&、||),非简洁运算符(&、|)
异或:^,异者,不同也,不能为同,同则错
位运算符

流程控制

switch

switch(表达式){	//表达式为字符或整数类型
	case	常量表达式:
		语句;
		break;
	default:	//默认执行
		语句;
}

while

while(条件表达式){	//需要为逻辑值
   循环体;
} 

do-while

do{
	循环体;
}while(条件表达式)

while与if区别:

while判断为真后执行循环体,接着再判断,若为真则继续执行循环体,直到判断为假再跳出循环(多次循环直至为错)
if判断为真后执行,错误则不执行(只判断一次)

for

for(表达式1;条件表达式;表达式2){
	循环体;
}

多维数组的内存理解

是对某一类事物的描述,是对象的模板、图纸,对象是类的一个实例,是实在的个体。一个类可以对应多个对象
类一般有两个成员:属性(field)和方法(method)
类修饰符:public、abstract、final
抽象类无实现方法,需要子类提供方法,不能创建该类的实例
最终类不能被继承
变量修饰符:public、private、protected、final、static、transient、volatile、private

  • private:只允许自己类访问,其他类包括子类不能访问
  • protected:可被子类、同包下的类访问
  • transient:过渡修饰符,系统保留、无特别作用的临时变量
  • volatile:易失修饰符,可被几个线程同时控制和修改
    方法修饰符注意点:
  • static 不需要实例即可使用
  • final 不能被重载
  • abstract 表明要被子类重写
  • synchronized 同步
    对同步资源加锁,以防止其他线程访问,运行结束后解锁
  • native 本地
    表明方法体由其他编程语言在程序外部编写

局部变量不会自动赋值,必须显式赋值

匿名对象:new一个对象而不定义引用变量。使用情形:作为参数传递给其他方法,或对该对象只进行一次方法调用
静态变量和方法从属于类,为实例所共有。好处在于可节省内存空间。

优先以类名.静态变量/静态方法的形式来访问静态变量/方法
静态方法不能访问非静态变量或方法,不能使用this/super关键字
JVM需要在类外调用main()方法,所以main方法为static,访问权限为public

引用变量的标识符保存的是对象在内存中的首地址,也称句柄

类的继承中,在执行子类的构造方法之前会先调用父类的无参构造器,目的是为了初始化子类

向上转型:创建父类类型的变量指向子类对象
eg:Person per = new Student();
是一个从具体到抽象的过程
向下转型需要强制类型转换
多态不能使用新增方法

final定义成员变量可以在定义时赋值,也可以在构造器中赋值

==比较符用于比较对象在内存中的首地址,equals()方法用于比较内容是否相等

抽象类

起模板作用,抽象出其子类共同的属性和方法

abstract class 类名{
	声明成员变量;
	返回值的数据类型 方法名(参数表){
		···
	}
	//抽象方法没有方法体,用于子类覆盖
	abstract 返回值的类型 方法名(参数表){
	}
}

接口

成员变量修饰符默认为public static final,方法修饰符默认为public abstract,接口的方法无方法体,且不能定义普通方法,变量需要初始化
接口实际上是一种特殊的抽象类

内部类:类中的类,是外部类的成员

enumration
hasMoreElement()与Iterator的hasNext()类似
nextElement()与Iterator的Next()类似

容器

hashtable

与hashmap相比:1.线程安全,效率相对低下
2.hashtable父类是Dictionary,,hashmap父类是AbstractMap
3.hashtable键与值不能为null,hashmap键最多一个null,值可以多个null

子类:properties

作用:读写资源配置文件
要求键与值只能为字符串
存储:setProperty(key, value)
方法getProperty(String key)与getProperty(String key, String defaultValue)比较:前一个如果查不到返回值为空,后一个查不到返回值为defaultValue,看了API自己理解为后一个方法套用了前一个方法
获取:load(InputStream inStream),传入字节流
load(Reader reader)
loadFromXML(InputStream in)
store(OutputStream out, String comments):传入字节流和注释,存储后缀为.properties的流文件
store(Writer writer, String comments):传入字符流和注释,存储后缀为.properties的流文件
存储后缀.xml文件的方法:storeToXML(OutputStream os, String comment)(默认UTF-8字符集)和重载的storeToXML(OutputStream os, String comment, String encoding)(传入指定字符集)
一旦涉及到字符集,则不能使用字符流,只能使用字节流

Collection下的其他常用容器

queue

单向队列
队列通常FIFO(先进先出)
优先级队列和堆栈LIFO(后进先出)
方法:
抛出异常:add()、remove()、element()
特殊值:offer()、poll()、peek()

抛出特殊值一般优于抛异常

Deque(Double-ended queue)

双向队列,两端访问

io流

按流向分为:输入流、输出流
按数据类型分:字节流、字符流

字节流

二进制,可以处理一切文件,包括纯文本、doc、音视频
InputStream、OutputStream

字符流

文本文件,只能处理纯文本
Reader、Writer

FileInputStream/FileOutputStream构造方法

  • FileInputStream/FileOutputStream(File file)
  • FileInputStream/FileOutputStream(FileDescriptor fdObj)
  • FileInputStream/FileOutputStream(String name)
  • FileOutputStream(File file, boolean append)
  • FileOutputStream(String name, boolean append)
    true表示追加,false表示覆盖

以下为Java程序设计基础(第五版)教材

import java.io.*;
/**
 * 读取键盘上的输入字符并输出
 */
public class 文件字节流读取键盘并输出 {
	public static void main(String[] args) throws IOException {
		char c;
		int data;
		/*
		*FileDescriptor类不能被实例化,该类有三个静态成员:in,out和err
		*分别对应标准输入流、标准输出流和标准错误流,利用它们可以在标准
		*输入流和标准输出流上建立文件输入输出流,实现键盘输入或屏幕输出操作
		*/
		InputStream in = new FileInputStream(FileDescriptor.in);
		OutputStream out = new FileOutputStream("A:\\JavaTest\\1.txt");
		System.out.println("输入一串字符,以'#'作为结尾");
		//read(),从该输入流读取一个字节的数据。如果没有输入可用,此方法将阻止。
		while((c=(char)in.read())!='#') {
		//write(int b),将指定的字节写入此文件输出流。
			out.write(c);
		}
		in.close();
		out.close();
		
		in = new FileInputStream("A:\\JavaTest\\1.txt");
		out = new FileOutputStream(FileDescriptor.out);
		//available(),返回从此输入流中可以读取(或跳过)的剩余字节数的估计值,而不会被下一次调用此输入流的方法阻塞。
		//System.out.println(in.available());
		while(in.available()>0) {
			data = in.read();
			out.write(data);
		}
		in.close();
		out.close();
		
	}
}
import java.io.*;
public class 复制文件 {
	public static void main(String[] args) throws IOException {
		FileInputStream in = new FileInputStream("e:/1.txt");
		FileOutputStream out = new FileOutputStream("e:/11.txt");
		System.out.println("1.txt文件的大小:"+in.available());
		byte[] b = new byte[in.available()];
		//read(byte[] b),从该输入流读取最多b.length个字节的数据为字节数组。
		System.out.println(in.read(b));
		//write(byte[] b),将b.length个字节从指定的字节数组写入此文件输出流
		out.write(b);
		
		in.close();
		out.close();
	}
}
import java.io.*;
/**
*DataInputStream(InputStream in)
*DataOutputStream(OutputStream out)
*DataInputStream类方法的传入参数对应方法的返回值
*/
public class 写出不同类型数据 {
	public static void main(String[] args) throws IOException{
		FileOutputStream fout;
	    DataOutputStream dout;
	      fout=new FileOutputStream("e:\\temp");
	      dout=new DataOutputStream(fout);
	      dout.writeInt(10);
	      dout.writeLong(12345);
	      dout.writeFloat(3.1415926f);
	      dout.writeDouble(987654321.123);
	      dout.writeBoolean(true);
	      dout.writeChars("Goodbye! ");
	      dout.close();

	      FileInputStream fin;
		  DataInputStream din;
	      fin=new FileInputStream("e:\\temp");
	      din=new DataInputStream(fin);
	      System.out.println(din.readInt());
	      System.out.println(din.readLong());
	      System.out.println(din.readFloat());
	      System.out.println(din.readDouble());
	      System.out.println(din.readBoolean());
	      din.close();
	}
}

import java.io.*;
/**
 *System.err.println()打出来的是红字 
 */
public class 标准输入输出 {
	public static void main(String[] args) throws IOException{
        //System.err.println("红色,因为是标准错误输出");
		//设置输入缓冲区
		byte[] b = new byte[128];
		System.out.println("输入字符");
		//读取标准输入流,将回车(13)和换行符(10)也一起放到b字节数组
		int count = System.in.read(b);
		//打印b中元素的ASCII值
		for(int i=0;i<count;i++) {
			System.out.print(b[i]+" ");
		}
		System.out.println();
        //字符个数
		System.out.println(count);
		//转为字符型
		for(int i=0;i<count;i++) {
			System.out.print((char)b[i]+" ");
		}
		System.out.println(System.in.getClass().toString());
		
	}
}

System是Object类的直接子类,System.in是InputStream类的对象,System.out是PrintStream类的对象

字符流

java.lang.Object
    java.io.Reader 
        java.io.InputStreamReader
            java.io.FileReader
java.lang.Object
    java.io.Writer
        java.io.OutputStreamWriter
            java.io.FileWriter
FileReader构造方法:
    FileReader(File file)
    FileReader(FileDescriptor fd)
    FileReader(String fileName)
FileWriter构造方法:
    FileWriter(File file)
    FileWriter(File file, boolean append)
    FileWriter(FileDescriptor fd)
    FileWriter(String fileName)
    FileWriter(String fileName, boolean append)
import java.io.*;
/**
 * 字符流创建字符数组,字节流创建字节数组
 */
public class 用FileReader读取文件 {
	public static void main(String[] args) throws IOException {
		char[] c = new char[10];
		FileReader fr = new FileReader("e:/1.txt");
		/**
		1.先调用Reader类的方法:
		public int read(char cbuf[]) throws IOException {
        	return read(cbuf, 0, cbuf.length);
    	}
    	2.上一个方法返回Reader类的抽象方法:
    	abstract public int read(char cbuf[], int off, int len) throws IOException;
    	3.Reader类的子类InputStreamReader重写:
    	public int read(char cbuf[], int offset, int length) throws IOException {
        	return sd.read(cbuf, offset, length);
    	}
    		sd是InputStreamReader类的成员:
    		private final StreamDecoder sd;
    	4.点StreamDecoder无法查看源码,应该又是调用sun.nio.cs.StreamDecoder类的方法
    	public class sun.nio.cs.StreamDecoder extends java.io.Reader	
		 */
		//教材:将数据读入字符数组c,并返回读取的字符数
		int num = fr.read(c);
		//将字符数组转换成字符串
		String str = new String(c,0,num);
        //注:教材上的这个案例只能读取十个字节
		System.out.println(str);
		fr.close();
		
	}
}
import java.io.*;
public class 用FileWriter写文件 {
	public static void main(String[] args) throws IOException {
		FileWriter fw=new FileWriter("d:\\java\\test.txt");
	    char[] c={'H', 'e', 'l', 'l', 'o', '\r', '\n'};
	    String str="欢迎使用Java!";
	    /**
	     * 继承OutputStreamWriter类
	     *  write(char[] cbuf, int off, int len)
	     *  write(int c)
	     *  write(String str, int off, int len)
	     * OutputStreamWriter类的父类Writer
	     * 	write(int c)
	     * 	write(char cbuf[])
	     * 	abstract public void write(char cbuf[], int off, int len)
	     * 	write(String str)
	     * 	write(String str, int off, int len)
	     */
	    fw.write(c);
	    fw.write(str); 
	    fw.close();
	}
}
import java.io.*;
public class 用BufferedReader读文件 {
	public static void main(String[] args) throws IOException{
	      String thisLine;
	      int count=0;
	      FileReader fr=new FileReader("e:/1.txt");
	      BufferedReader bfr=new BufferedReader(fr);
	      //每次读取一行,直到文件结束
	      //读一行文字。 一行被视为由换行符('\ n'),回车符('\ r')中的任何一个或随后的换行符终止。
	      while ((thisLine=bfr.readLine())!=null){
	        count++;
	        System.out.println(thisLine);
	      }
	      System.out.println("共读取了"+count+"行");
	      bfr.close();
	}
}
import java.io.*;
public class 用BufferedWriter写文件 {
	public static void main(String[] args) throws IOException {
		BufferedReader bfr = new BufferedReader(new FileReader("e:/1.txt"));
		BufferedWriter bfw = new BufferedWriter(new FileWriter("e:/11.txt"));
		String str;
		while((str=bfr.readLine())!=null) {
			//输出读取到的内容
			System.out.println(str);
			//将读取的数据写入到输出流
			bfw.write(str);
			//写入回车换行符
			bfw.newLine();
		}
		//将缓冲区的数据全部写入到文件中
		bfw.flush();
		bfr.close();
		bfw.close();
	}
}
File类的构造方法:
    File(File parent, String child)
    File(String pathname)
    File(String parent, String child)
    File(URI uri)
import java.io.*;
/**
* 教材的这个案例不是很好
*/
public class 用File类输出文件夹下内容 {
	public static void main(String[] args) {
		String str=new String();
	    try{
	      InputStreamReader isr=new InputStreamReader(System.in);
	      BufferedReader inp=new BufferedReader(isr);
	      String sdir="d:\\temp";
	      String sfile;
	      //把sdir作为参数
	      File fdir1=new File(sdir);
	      if (fdir1.exists() && fdir1.isDirectory()){
	        	System.out.println("文件夹:"+sdir+"已经存在");
	        	//遍历其下文件夹和文件
              	for (int i=0;i<fdir1.list().length;i++)
                  System.out.println((fdir1.list())[i]);
                File fdir2=new File("d:\\temp\\temp");
                  //如果不存在就创一个文件夹
                if (!fdir2.exists())
                  fdir2.mkdir();
              	System.out.println();
              	System.out.println("建立新文件夹后的文件列表");
              	for (int i=0;i<fdir1.list().length;i++)
                  System.out.println((fdir1.list())[i]);
	      }
	      System.out.print("请输入该文件夹中的一个文件名:");
	      sfile=inp.readLine();
	      File ffile=new File(fdir1,sfile);
	      if (ffile.isFile()){
	        System.out.print("文件名:"+ffile.getName());
	        System.out.print(";所在文件夹:"+ffile.getPath());
	        System.out.println(";文件大小:"+ffile.length()+"字节");
	      }
	    }
	    catch (IOException e){
	      System.out.println(e.toString());
	    }
	}
}
import java.io.*;
/**
* 比较不错的案例
*/
public class RandomAccessFile类对文件进行随机访问 {
	public static void main(String[] args) throws IOException{
		StringBuffer stfDir=new StringBuffer();
	    System.out.println("请输入文件所在的路径");
	    char ch;
	    //通过标准键盘输入读取字符,存入到StringBuffer
	    while ((ch=(char)System.in.read())!='\r')
	      stfDir.append(ch);
	    //把StringBuffer转为字符串
	    File dir=new File(stfDir.toString());
	    System.out.println("请输入欲读取的文件名");
	    StringBuffer stfFileName=new StringBuffer();
	    char c;
	    while ((c=(char)System.in.read())!='\r')
	      stfFileName.append(c);
	    //去掉上次输入并回车后存留在缓冲区中的'\n'
	    stfFileName.replace(0,1,"");
	    //通过输入的文件路径和文件名创建File对象
	    File readFrom=new File(dir,stfFileName.toString());
	    if (readFrom.isFile() && readFrom.canWrite() && readFrom.canRead()){
	      RandomAccessFile rafFile=new RandomAccessFile(readFrom,"rw");
	      //getFilePointer(),返回文件指针的当前位置
	      //若文件指针的位置没有超过文件的长度,则输出文件中的每一行直到结束
	      while (rafFile.getFilePointer()<rafFile.length())
	        System.out.println(rafFile.readLine());
	      rafFile.close();
	    }
	    else
	      System.out.println("文件不可读!");
	}
}

以下为尚学堂

import java.io.*;
public class 字节流写出并复制文件 {
	public static void main(String[] args) throws IOException{
		//第二参数为空或false则是覆盖
		OutputStream os = new FileOutputStream("a:/JavaTest/1.txt",true);
		String str = "\r\nI will success! \r\n";	
		//需要将要写入的内容转为字节数组
		byte[] x = str.getBytes();
		os.write(x);
		//flush用于避免输出流没被写出
		os.flush();
		os.close();
		
		InputStream is = new FileInputStream("a:/JavaTest/1.txt");
		//定义缓冲数组
		byte[] car = new byte[128];
		//接收实际读取大小
		int len = 0;
		//循环读取
		/**
		 * read(byte[] b),从该输入流读取最多b.length字节的数据到字节数组。 此方法将阻塞,直到某些输入可用。
		 * @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.
		 * 理解:从is中一次读取b.lenth字节到字节数组,用while循环读取直到返回值为-1
		 */
		while((len=is.read(car))>0) {
			/**
			 * 一次读取b.lenth个字节的数据,len为实际读取大小
			 * 当读取到最后一次填不满数组时,len返回小于b.length的值
			 */
			String s = new String(car,0,len);
			System.out.println(s);
		}
		is.close();
		
	}
}
import java.io.*;
public class 字符流写入并读取文件 {
	public static void main(String[] args) {
		File src = new File("e:/1.txt");
		try {
			Reader r = new FileReader(src);
			Writer w = new FileWriter(src,true);
			String s = "i will be successful";
			char[] c = new char[128];
			int len = 0;
			String str;
			w.write(s);
			w.flush();
			while((len=r.read(c))>0) {
				//System.out.println(c);
				//字符数组转字符串
				str = new String(c,0,len);
				System.out.println(str);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}
}
import java.io.*;
public class 字节流拷贝文件 {
	public static void main(String[] args) throws IOException{
	    //注意两个路径需要指定到文件名
		InputStream is = new FileInputStream("a:/JavaTest/1.txt");
		OutputStream os = new FileOutputStream("a:/JavaTest/11.txt");
		byte[] b = new byte[128];	
		int len;
		while((len=is.read(b))>0) {
			os.write(b, 0, len);
		}
		os.flush();
		//先打开的后关闭
		os.close();
		is.close();
		
	}
}
import java.io.*;
public class 拷贝文件夹 {
	public static void main(String[] args) {
		//源目录
		String srcPath = "a:/JavaTest";
		//目标目录
		String destPath = "g:/JavaTest";
		copyDir(srcPath,destPath);
	}
	
	public static void copyDir(String srcPath,String destPath) {
		File src = new File(srcPath);
		File dest = new File(destPath);
		copyDir(src,dest);
	}
	
	public static void copyDir(File src,File dest) {
		//如果源目录路径确实为目录
		if(src.isDirectory()) {
			//File(String parent, String child)
			//以目标目录为父路径,源目录名字为子路径创建File实例
			//此时dest为目标目录下的文件夹
			dest = new File(dest, src.getName());
		}
		copyDirDetail(src,dest);
	}
	
	public static void copyDirDetail(File src,File dest) {
		//如果src为文件
		if(src.isFile()) {
			//调用前面写了封装的copyFile方法
			try {
			    //直接把src复制到dest
				copyFile(src, dest);
			} catch (IOException e) {
				e.printStackTrace();
			}
			//如果src是文件夹
		}else if(src.isDirectory()) {
			//创建目录,确保目标文件夹存在
			dest.mkdirs();
			//获取下一级目录
			for(File sub:src.listFiles()) {
				/**
				 * 遍历src文件夹,递归
				 * eg:src下有一个test目录,把它作为源目录,
				 * 第二个参数以dest作为父路径,test的名字作为子路径
				 * 创建File对象进行递归,然后mkdirs创建目录,接着遍历
				 * test目录,若其下为文件则copyFile。
				 * 当递归完src第一个目录后,回到第一层对src的遍历并对src的下一个
				 * 目录递归
				 */
				copyDirDetail(sub,new File(dest,sub.getName()));
			}
		}
	}
	
	public static void copyFile(File src,File dest) throws FileNotFoundException,IOException{
		if(!src.isFile()) {
			throw new IOException("不是文件");
		}
		InputStream is = new FileInputStream(src);
		OutputStream os = new FileOutputStream(dest);
		byte[] b = new byte[128];	
		int len;
		while((len=is.read(b))>0) {
			os.write(b, 0, len);
		}
		os.flush();
		os.close();
		is.close();
	}

}
处理流

从二进制(看不懂)到字符集(看得懂)的过程为编码,从字符集(看得懂)到二进制(看不懂)的过程为解码
不直接连接到数据源或目的地,是处理流的流,通过对其他流的处理提高程序的性能
作用:提高效率和性能

import java.io.*;
public class 缓冲流 {
	public static void main(String[] args) {
		File src = new File("e:/1.txt");
		try {
			BufferedReader r = new BufferedReader(new FileReader(src));
			BufferedWriter w = new BufferedWriter(new FileWriter(src,true));
			String str = null;
			//换行符
			w.newLine();
			//缓冲流的readline方法一行一行读取,直到为空
			while((str=r.readLine())!=null) {
				w.write(str);
			}
			//更快捷的添加方式
			w.append("aaa");
			w.flush();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
import java.io.*;
public class 编码解码 {
	public static void main(String[] args) throws UnsupportedEncodingException {
		String str = "笑着说自己打字速度很快,后面就落泪了";		//默认为GBK
		byte[] b = str.getBytes();
		//因为编码与解码字符集同一,所以没有乱码
		System.out.println(new String(b));
		
		//设定指定编码字符集
		b = str.getBytes("utf-8");
		//编码解码字符集不一致,导致乱码
		System.out.println(new String(b));
		
		//编码解码均指定为unicode
		byte[] b2 = "我喜欢吃肉".getBytes("unicode");
		String str2 = new String(b2,"unicode");
		System.out.println(str2);
	}
}
import java.io.*;
/**
 * 处理乱码问题
 */
public class 字节流转字符流 {
	public static void main(String[] args) {
		try {
			BufferedReader br = new BufferedReader(
					//BufferedReader为字符流,通过InputStreamReader转为字节流
					//并且指定字符集(需要与文件编码一致)
					new InputStreamReader(
							new FileInputStream(new File("e:/1.txt")),"utf-8"
							));
			String str = null;
			while((str=br.readLine())!=null)
				System.out.println(str);
			br.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
/**
 * 文件--文件输入流 ->程序--字节数组输出流 ->字节数组		
 * 字节数组--字节数组输入流 ->程序--文件输出流 ->文件
 */
import java.io.*;
public class 字节数组流 {
	public static void main(String[] args) throws IOException {
		//String str =new String(toByte("A:\\JavaTest\\1.txt"));
		//System.out.println(str);
		//toFile(b,"a:/JavaTest/2.txt");

		toFile(toByte("A:\\JavaTest\\1.png"),"A:\\JavaTest\\2.png");
	}
	/**
	*  将源文件转为字节数组
	*/
	public static byte[] toByte(String srcPath) throws IOException {
		InputStream is = new BufferedInputStream(new FileInputStream(new File(srcPath)));
		ByteArrayOutputStream bos= new ByteArrayOutputStream();
		byte[] flush = new byte[128];
		int len = 0;
		while((len=is.read(flush))>0) {
			bos.write(flush, 0, len);
		}
		bos.flush();
		byte[] dest = bos.toByteArray();
		bos.close();
		is.close();
		return dest;
	}
	/**
	* 以字节数组的形式将数据传到目标路径
	*/
	public static void toFile(byte[] src,String destPath) throws IOException {
		OutputStream os = new BufferedOutputStream(new FileOutputStream(new File(destPath)));
		ByteArrayInputStream bis = new ByteArrayInputStream(src);
		byte[] flush = new byte[128];
		int len = 0;
		while((len=bis.read(flush))>0) {
			os.write(flush,0,len);
		}
		os.flush();
		
		bis.close();
		os.close();
	}
}
import java.io.*;
/**
 * 用于处理数据类型(基本数据类型+String)
 * 输入流:DataInputStream
 * 输出流:DataOutpurtStream
 */
public class 数据类型处理流 {
	public static void main(String[] args) throws IOException {
		写入("a:/JavaTest/0.txt");
		//如果文件不一致,会出现EOFException,(end of file)
		//即文件已到达末尾,没有读取到相关的内容
		读取("a:/JavaTest/0.txt");
	}
	
	public static void 写入(String destPath) throws IOException {
		double point = 2.5;
		long num = 100L;
		String str = "大吉大利";
		
		DataOutputStream dos = new DataOutputStream(
				new BufferedOutputStream(
                    new FileOutputStream(
						new File(destPath))));
		//方法名指定出类型,注意顺序
		//读取顺序与写入顺序要一致
		dos.writeDouble(point);
		dos.writeLong(num);
		dos.writeUTF(str);
		
		dos.flush();
		dos.close();
	}
	
	public static void 读取(String srcPath) throws IOException {
		DataInputStream dis = new DataInputStream(
				new BufferedInputStream(
						new FileInputStream(
                            new File(srcPath))));
		//读取顺序与写入顺序要一致
		//顺序不一致数据会出现问题
		Double n1 = dis.readDouble();
		Long n2 = dis.readLong();
		String s = dis.readUTF();
        dis.close();
		System.out.println(n1+" "+n2+" "+s);
	}
}
import java.io.*;
/**
 * 把字节数组流包装入数据类型处理流
 */
public class 数据类型处理流加字节数组流 {
	public static void main(String[] args) throws IOException {
		byte[] b = 写入();
		System.out.println(b.length);
		读取(b);
	}
	
	public static byte[] 写入() throws IOException {
		double point = 2.5;
		long num = 100L;
		String str = "大吉大利";
		
		byte[] dest = null;
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		DataOutputStream dos = new DataOutputStream(
				new BufferedOutputStream(
						bos));
		dos.writeDouble(point);
		dos.writeLong(num);
		dos.writeUTF(str);
		
		dos.flush();
		//在关闭之前获取数据
		dest = bos.toByteArray();
		dos.close();
		
		return dest;
	}
	
	public static void 读取(byte[] src) throws IOException {
		DataInputStream dis = new DataInputStream(
				new BufferedInputStream(
						new ByteArrayInputStream(src)));
		Double n1 = dis.readDouble();
		Long n2 = dis.readLong();
		String s = dis.readUTF();
		dis.close();
		System.out.println(n1+" "+n2+" "+s);
	}
}

处理引用类型

/**
 * 输入流为反序列化:ObjectInputStream
 * 输出流为序列化:ObjectOutpurStream
 * 先序列化后反序列化,反序列化顺序必须与序列化一致
 * 不是所有对象都可以序列化,必须要实现java.io.Serializable接口
 * 不是所有属性都需要序列化,通过transient来避免
 * Serializable是一个空接口,用于标识序列化
 */
public class Employee implements java.io.Serializable{
	//表示这个属性不需要序列化
	private transient String name;
	private double salary;
	public Employee(String name, double salary) {
		super();
		this.name = name;
		this.salary = salary;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public double getSalary() {
		return salary;
	}
	public void setSalary(double salary) {
		this.salary = salary;
	}
	public Employee() {
	}
}


import java.io.*;
public class Test {
	//序列化
	public static void seri(String destPath) throws IOException {
		Employee emp = new Employee("有钱人",20000);
		ObjectOutputStream dos = new ObjectOutputStream(
				new BufferedOutputStream(
						new FileOutputStream(
								new File(destPath))));
		dos.writeObject(emp);
		dos.flush();
		dos.close();
	}
	
	//反序列化
	public static void read(String destPath) throws IOException, ClassNotFoundException {
		ObjectInputStream ois = new ObjectInputStream(
				new BufferedInputStream(
						new FileInputStream(
								new File(destPath))));
		Object obj = ois.readObject();
		if(obj instanceof Employee) {
			Employee emp = (Employee)obj;
			System.out.println(emp.getName());
			System.out.println(emp.getSalary());
		}
		ois.close();
	}
	
	public static void main(String[] args) throws IOException, ClassNotFoundException {
		//结果为null和20000,name加上了transient关键字避免序列化
		read("a:/JavaTest/2.txt");
	}
}
import java.io.*;
import java.util.Scanner;
public class 用Scanner读取文件 {
	public static void main(String[] args) throws IOException {
		//System类的属性in为InputStream类型
		InputStream is = System.in;
		//创建文件输入流,指定文件路径
		is = new BufferedInputStream(new FileInputStream(new File("a:/JavaTest/1.txt")));
		//将文件路径作为参数。注意Scanner为util类
		Scanner sc = new Scanner(is);
		//实现用Scanner类读取文件内容
		while(sc.hasNext())
			System.out.println(sc.nextLine());
	}
}
/**
 * 使用System类的重定向方法写入
 */
import java.io.*;
public class 重定向 {
	public static void main(String[] args) throws IOException {
		System.setOut(new PrintStream(
				new BufferedOutputStream(
						new FileOutputStream(
								//前面的true为追加内容
								//后面的true为PrintStream打印流的第二个参数,是否自动flush
								new File("a:/JavaTest/1.txt"),true)),true));
		System.out.println("YES");
		System.out.println("成功");
		
		//回到控制台
		System.setOut(new PrintStream(new BufferedOutputStream(
						new FileOutputStream(
								FileDescriptor.out)),true));
		System.out.println("aaa");
	}
}
import java.io.*;
public class System的in属性与缓冲流应用 {
	public static void main(String[] args) throws IOException {
		InputStream is =System.in;
		BufferedReader bf = new BufferedReader(
				//需要先将字节流转为字符流,然后添加参数
				new InputStreamReader(is));
		System.out.println("请输入");
		System.out.println(bf.readLine());
		
	}
}

装饰设计模式

public class Voice {
	//音量为10
	private int voice = 10;
	public Voice() {
	}
	public int getVoice() {
		return voice;
	}
	public void setVoice(int voice) {
		this.voice = voice;
	}
	
	public void say() {
		System.out.println(voice);
	}
}

/**
 * 扩音器,对声音进行放大
 */
public class Amplifier {
	private Voice voice;
	public Amplifier() {
	}
	public Amplifier(Voice voice) {
		super();
		this.voice = voice;
	}
	public void say() {
		System.out.println(voice.getVoice()*1000);
	}
}

/**
 * 应用
 */
public class App {
	public static void main(String[] args) {
		Voice v = new Voice();
		v.say();
		//放大
		Amplifier am = new Amplifier(v);
		am.say();
	}
}

RandomAccessFile使用

import java.io.*;
public class 使用seek方法 {
	public static void main(String[] args) throws IOException {
		//第二个参数有r w rw 三种选择
		RandomAccessFile rnd = new RandomAccessFile(new File("a:/JavaTest/1.txt"),"rw");
		//seek(),Sets the file-pointer offset,
		//从哪里开始读取
		rnd.seek(10);
		byte[] flush = new byte[128];
		int len = 0;
		while((len=rnd.read(flush))>0) {
			System.out.println(new String(flush,0,len));
		}
		rnd.close();
	}
}
/**
 * 思路:确定分割块数n、各块的大小blockSize
 * 最后一块的大小为 总文件大小减去(n-1)*blockSize
 */
import java.io.*;
import java.util.*;
public class 文件分割 {
	//文件名字、路径、大小、分割块数、每块的大小
	private String fileName;
	private String filePath;
	private long length;
	private int size;
	private long blockSize;
	//每块的名称
	private List<String> blockPath;
	//分割后存放的目录
	private String destPath;
	//注意理解这三个构造器间的调用关系
	public 文件分割() {
		blockPath = new ArrayList<String>();
	}
	public 文件分割(String filePath,long blockSize,String destPath) {
		this();
		this.filePath = filePath;
		this.blockSize = blockSize;
		this.destPath = destPath;
		//初始化在构造时完成
		init();
	}
	public 文件分割(String filePath,String destPath) {
		this(filePath,1024,destPath);
	}
	
	/**
	 * 初始化操作。确定文件名、计算块数、确定每块名称
	 */
	public void init() {
		File src = null;
		//如果filePath为空,或者filePath不存在,或者src是文件夹
		if(filePath==null||!((src=new File(filePath)).exists())||src.isDirectory()) {
			return;
		}
		fileName = src.getName();
		/**
		 * 计算块数
		 */
		//文件实际大小
		length = src.length();
		//如果块的大小大于文件实际大小
		if(blockSize>length) {
			blockSize = length;
		}
		
		//确定块数
		//ceil():返回大于或等于参数的最小(最接近负无穷大) double值,并等于数学整数。 
		//即取最大的整数,返回double型,要乘1.0避免类型错误
		//最后强转为int
		size = (int)(Math.ceil(length*1.0/blockSize));
		initPathName();
	}
	
	/**
	 * 确定每块名称
	 */
	public void initPathName() {
		for(int i=0;i<size;i++) {
			blockPath.add(destPath+File.separator+fileName+".part"+i);
		}
	}
	
	public void split() throws IOException {
		long beginPos = 0;
		long actualBlockSize = blockSize;
		for(int i=0;i<size;i++) {
			//最后一块
			if(i==size-1) {
				actualBlockSize = length-beginPos;
			}
			splitDetail(i,beginPos,actualBlockSize);
			beginPos += actualBlockSize; 
		}
	}
	
	/**
	 * 与文件拷贝的思路一致
	 * @param idx:第几块
	 * @param beginPos:每一块开始时的文件大小
	 * @param actualBlockSize:剩余的实际大小
	 */
	public void splitDetail(int idx,long beginPos,long actualBlockSize) throws IOException {
		RandomAccessFile raf = null;
		BufferedOutputStream bos = null;
		try {
			//要分割的文件
			raf = new RandomAccessFile(new File(filePath),"r");
			bos = new BufferedOutputStream(
					new FileOutputStream(
							new File(blockPath.get(idx))));
			//读取文件
			raf.seek(beginPos);
			byte[] flush = new byte[(int)length];
			int len = 0;
			while((len=raf.read(flush))>0) {
				if(actualBlockSize-len>=0) {
					bos.write(flush,0,len);
					actualBlockSize-=len;
				}else {
					bos.write(flush,0,(int)(actualBlockSize));
					break;
				}
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			bos.flush();
			bos.close();
			raf.close();
		}
	}
	
	public void 合并思路1(String destPath) {
		BufferedInputStream bis = null;
		BufferedOutputStream bos = null;
		for(int i=0;i<blockPath.size();i++) {
			try {
				bis = new BufferedInputStream(
                    new FileInputStream(
                    	new File(blockPath.get(i))));
				bos = new BufferedOutputStream(
						new FileOutputStream(
								new File(destPath),true));
				byte[] flush = new byte[(int)length];
				int len = 0;
				while((len=bis.read(flush))>0) {
					bos.write(flush, 0, len);
				}
				bos.flush();
				bos.close();
				bis.close();
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * 通过枚举使用sequenceInputStream
	 */
	public void 合并思路2(String destPath) throws IOException {
		BufferedOutputStream bos = null;
		Vector<InputStream> vi= new Vector<InputStream>();
		for(int i=0;i<blockPath.size();i++)
			vi.add(new BufferedInputStream(
                new FileInputStream(
                    new File(blockPath.get(i)))));
		SequenceInputStream sis = new SequenceInputStream(vi.elements());
		bos = new BufferedOutputStream(
				new FileOutputStream(
						new File(destPath),true));
		byte[] flush = new byte[(int)length];
		int len = 0;
		while((len=sis.read(flush))>0) {
			bos.write(flush, 0, len);
		}
		bos.flush();
		bos.close();
		sis.close();
		
	}
	
	public static void main(String[] args) throws IOException {
		文件分割 w = new 文件分割("a:/JavaTest/1.txt",21,"g:/JavaTest");
		//结果为文件的字节数除以构造器的第二个参数的向上取整
		//System.out.println(w.size);
		w.split();
		w.合并思路2("g:/1.txt");
	}
    
}

IO流总结

节点流
  1. 字节流:可以处理一切(纯文本、音视频等)
    1 输入流 InputStream FileInputStream ByteArrayInputStream
    2 中间容器 byte[] flush = new byte[长度]
    3 接受长度 int len = 0
    4 循环读取 while((len=流.read(flush))>0){}
    5 操作 输出 、拷贝

    1 输出流 OutputStream FileOutputStream ByteArrayOutputStream
    2 操作 write(字节数组,0,长度) 输出

  2. 字符流:只能处理纯文本
    1 输入流 Reader FileReader
    操作 read(字符数组)
    2 中间容器 char[] flush = new char[长度]
    3 接受长度 int len = 0
    4 操作 输出、拷贝

    1 输出流 Writer FileWriter
    2 操作 write(字符数组,0,长度) 输出

处理流 装饰模式

提高性能,增强功能

  1. 转换流:解码与编码字符集问题
    1. 输入流 InputStreamReader --> 解码
    2. 输出流 OutputStreamWriter -->编码
  2. 缓冲流 提高性能
    1. 输入流 BufferedInputStream BufferedReader
    2. 输出流 BufferedOutputStream BufferedWriter
  3. 处理数据+类型
    1. 基本+字符串:必须存在才能读取,读取与写出顺序要一致
      1. 输入流 DataInputStream readXxx
      2. 输出流 DataOutputStream writeXxx
    2. 引用类型 Serializable transient
      1. 反序列化 ObjectInputStream readObject
      2. 序列化 ObjectOutputStream writeObject
  4. 打印流 PrintStream
  5. System.in out err

以下流使用新增方法不能发生多态
6. ByteArrayOutputStream toByteArray()
7. BufferedReader readLine()
8. BufferedWriter newLine()
9. DataInputStream DataoutputStream
10.PrintStream

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值