ASP.Net+Android+IO开发S、.Net培训、期待与您交流!
运行以上程序后显示结果如下:(只是一部分)
java.runtime.name::::Java(TM) SE Runtime Environment
sun.boot.library.path::::E:\Java\jdk1.6.0_10\jre\bin
java.vm.version::::11.0-b15
java.vm.vendor::::Sun Microsystems Inc.
java.vendor.url::::http://java.sun.com/
path.separator::::;
java.vm.name::::Java HotSpot(TM) Client VM
file.encoding.pkg::::sun.io
sun.java.launcher::::SUN_STANDARD
user.country::::CN
sun.os.patch.level::::
java.vm.specification.name::::Java Virtual Machine Specification
user.dir::::D:\ceshi
java.runtime.version::::1.6.0_10-rc2-b32
java.awt.graphicsenv::::sun.awt.Win32GraphicsEnvironment
java.endorsed.dirs::::E:\Java\jdk1.6.0_10\jre\lib\endorsed
os.arch::::x86
java.io.tmpdir::::C:\Users\ADMINI~1\AppData\Local\Temp\
想要让虚拟机启动时动态加载属性信息?启动虚拟机用java命令,首先显示该命令的相关参数,在cmd中输入java >c:\2.txt,会将参数信息存入c:\2.txt文件中如下图(部分)
从上图中可以看出-D
/*System:类中的方法和属性都是静态的。上机演示程序一******************************
out:标准输出,默认是控制台。
in:标准输入,默认是键盘。
描述系统一些信息。
获取系统属性信息:Properties getProperties();
//虚拟机在启动时所加载的默认的属性信息。*/
import java.util.*;
class SystemDemo
{ public static void main(String[] args)
{ Properties prop = System.getProperties();
//因为Properties是Hashtable的子类,也就是Map集合的一个子类对象。
//那么可以通过map的方法取出该集合中的元素。
//该集合中存储都是字符串。没有泛型定义。
//如何在系统中自定义一些特有信息呢?
System.setProperty("mykey","myvalue");
//获取指定属性信息。
String value = System.getProperty("os.name");
System.out.println("value="+value);
//可不可以在jvm启动时,动态加载一些属性信息呢?
String v = System.getProperty("haha");
//如果在cmd中输入:java SystemDemo回车,显示v=null
//如果在cmd中输入:java –Dhaha=qqqqq SystemDemo回车,显示qqqqq,因为动态设定。(java -D
System.out.println("v="+v);
/*//获取所有属性信息。
for(Object obj : prop.keySet())
{ String value = (String)prop.get(obj);
System.out.println(obj+"::"+value);
}*/
}
}******************************************************************************
/*Runtime对象。该类并没有提供构造函数。说明不可以new对象。那么会直接想到该类中的方法都是静态的。发现该类中还有非静态方法。
说明该类肯定会提供了方法获取本类对象。而且该方法是静态的,并返回值类型是本类类型。
由这个特点可以看出该类使用了单例设计模式完成。该方式是static Runtime getRuntime();*/
class RuntimeDemo 上机演示程序二**********************************************
{ public static void main(String[] args) throws Exception
{ Runtime r = Runtime.getRuntime();
Process p = r.exec("winmine.exe");//启动扫雷游戏
Process p = r.exec("notepad.exe SystemDemo.java");
//启动记事本后,并在记事本中将“SystemDemo.java”文件打开。
//Thread.sleep(4000);//让进程运行4秒钟
//p.destroy();//杀掉进程
}
}******************************************************************************
import java.util.*;import java.text.*;//因为日期最终格式化后变成文本,所以要导入文本包。
class DateDemo 上机演示程序三***************************************************
{ public static void main(String[] args)
{ Date d = new Date();
System.out.println(d);//打印的时间看不懂,希望有些格式。
//将模式封装到SimpleDateformat对象中。
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日E hh:mm:ss");
//调用format方法让模式格式化指定Date对象。
String time = sdf.format(d);
System.out.println("time="+time);
long l = System.currentTimeMillis();
Date d1 = new Date(l);
System.out.println("d1:"+d1);
}
}******************************************************************************
import java.util.*;import java.text.*;上机演示程序四***********************************
class CalendarDemo
{ public static void main(String[] args)
{ Calendar c = Calendar.getInstance();
String[] mons = {"一月","二月","三月","四月"
,"五月","六月","七月","八月"
,"九月","十月","十一月","十二月"};
String[] weeks = {
"","星期日","星期一","星期二","星期三","星期四","星期五","星期六",
};
int index = c.get(Calendar.MONTH);
int index1 = c.get(Calendar.DAY_OF_WEEK);
sop(c.get(Calendar.YEAR)+"年");
//sop((c.get(Calendar.MONTH)+1)+"月");
sop(mons[index]);
sop(c.get(Calendar.DAY_OF_MONTH)+"日");
//sop("星期"+c.get(Calendar.DAY_OF_WEEK));
sop(weeks[index1]);
/*Date d = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
String year = sdf.format(d);//获得一个日期的年份,但是返回的是字符串,如果变成数字处理
//可以调用Integer.parseInt(d)但是比较麻烦,可找Calendar类帮助实现。
System.out.println(year);*/
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}******************************************************************************
两个练习:
1,获取任意年的二月有多少天。
思路:根据指定年设置一个时间就是
c.set(year,2,1)//某一年的3月1日。
c.add(Calenar.DAY_OF_MONTH,-1);//3月1日,往前推一天,就是2月最后一天。
2,获取昨天的现在这个时刻。
c.add(Calenar.DAY_OF_MONTH,-1);*/
class CalendarDemo2上机演示程序五*********************************************
{ public static void main(String[] args)
{ Calendar c = Calendar.getInstance();
//c.set(2012,2,23);//设置日期
c.add(Calendar.DAY_OF_MONTH,-18);//时间向前或者向后推迟。
c.add(Calendar.YEAR,4); printCalendar(c); }
public static void printCalendar(Calendar c)
{ String[] mons = {"一月","二月","三月","四月"
,"五月","六月","七月","八月"
,"九月","十月","十一月","十二月"};
String[] weeks = {
"","星期日","星期一","星期二","星期三","星期四","星期五","星期六", };
int index = c.get(Calendar.MONTH);
int index1 = c.get(Calendar.DAY_OF_WEEK);
sop(c.get(Calendar.YEAR)+"年");
//sop((c.get(Calendar.MONTH)+1)+"月");
sop(mons[index]);
sop(c.get(Calendar.DAY_OF_MONTH)+"日");
//sop("星期"+c.get(Calendar.DAY_OF_WEEK));
sop(weeks[index1]);
}
public static void sop(Object obj)
{ System.out.println(obj); }
}******************************************************************************
/*练习。给定一个小数。保留该小数的后两位。选作。可以考虑,保留时进行四舍五入。*/
import java.util.*; 上机演示程序五*************************************************
class MathDemo
{ public static void main(String[] args)
{ /*Random r = new Random();
for(int x=0; x<10; x++)
{ //int d = (int)(Math.random()*10+1);
int d = r.nextInt(10)+1;
sop(d);
}*/
saveTwo(12.3456,3,true);//12.34
}
public static void saveTwo(double d,int scale,boolean isRound)
{ double base = Math.pow(10,scale);
double num = isRound?Math.round(d*base)/base:((int)(d*base))/base;
sop("num="+num);
/*double d1 = d*100;
sop("d1="+d1);
d1 = d1+0.5;
double d2 = (int)d1;
sop("d2="+d2);
double d3 = d2/100;
sop("d3="+d3);*/
}
public static void show()
{ double d = Math.ceil(16.34);//ceil返回大于指定数据的最小整数。
double d1 = Math.floor(12.34);//floor返回小于指定数据的最大整数。
long l = Math.round(12.54);//四舍五入
sop("d="+d); sop("d1="+d1); sop("l="+l);
double d2 = Math.pow(2,3); sop("d2="+d2);
}
public static void sop(Object obj)
{ System.out.println(obj); }
}******************************************************************************
IO技术************************************************************************
/*字符流和字节流:字节流两个基类:InputStream OutputStream
字符流两个基类:Reader Writer
先学习一下字符流的特点。IO流是用于操作数据的,数据的最常见体现形式是:文件。
先以操作文件为主来演示。需求:在硬盘上,创建一个文件并写入一些文字数据。
找到一个专门用于操作文件的Writer子类对象。FileWriter。 后缀名是父类名。前缀名是该流对象的功能。*/
class FileWriterDemo上机演示程序六*********************************************
{ public static void main(String[] args) throws IOException//因为New FileWriter()所给出的绝对路径可能不存在如"K:\\demo.txt",所以就可能抛出IOException异常
{ //创建一个FileWriter对象。该对象一被初始化就必须要明确被操作的文件。
//而且该文件会被创建到指定目录下。如果该目录下已有同名文件,将被覆盖。
//其实该步就是在明确数据要存放的目的地。
FileWriter fw = new FileWriter("demo.txt");
//调用write方法,将字符串写入到流中。此时打开deom文件发现为空。
fw.write("abcde");
//刷新流对象中的缓冲中的数据。将数据刷到目的地中。
//fw.flush();
//关闭流资源,但是关闭之前会刷新一次内部的缓冲中的数据。
//将数据刷到目的地中。
//和flush区别:flush刷新后,流可以继续使用,close刷新后,会将流关闭。
fw.close();
}
}******************************************************************************
/*IO异常的处理方式。*/
class FileWriterDemo2上机演示程序七********************************************
{ public static void main(String[] args)
{ FileWriter fw = null;//在try外面建立引用,try内部初始化
try
{ //FileWriter fw = new FileWriter("demo.txt");编译失败,因为在try代码块中定义的fw,在finally代码块中无法访问。
fw = new FileWriter("demo.txt");
fw.write("abcdefg");
}
catch (IOException e)
{ System.out.println("catch:"+e.toString()); }
finally
{
//fw.close();编译失败,因为三句话都会引发IOException,但是只针对性处理了两句,所以必须对fw.close()也做出相应的处理方式
try
{
if(fw!=null)
fw.close();
//直接写:fw.close();
//如果在FileWriter fw = new FileWriter("k:\\demo.txt");
编译通过,但运行时报两个异常(一、FileNotFoundException(系统找不到制定路径)二、NullPointerException(空指针异常,因为对象没有建立成功,fw = null;))空的变量名时不能调用方法的
}
catch (IOException e)
{
System.out.println(e.toString());
} } } }******************************************************
/*演示对已有文件的数据续写。*/上机演示程序八************************************
class FileWriterDemo3
{ public static void main(String[] args) throws IOException
{ //传递一个true参数,代表不覆盖已有的文件。并在已有文件的末尾处进行数据续写。 FileWriter fw = new FileWriter("demo.txt",true);
fw.write("nihao\r\nxiexie");//\n和\r\n的区别
fw.close();
}
}******************************************************************************
class FileReaderDemo上机演示程序九(文本文件读取方式一)*************************
{ public static void main(String[] args) throws IOException
{ //创建一个文件读取流对象,和指定名称的文件相关联。
//要保证该文件是已经存在的,如果不存在,会发生异常FileNotFoundException
FileReader fr = new FileReader("demo.txt");
//调用读取流对象的read方法。 //read():一次读一个字符。而且会自动往下读。
/* int ch1 = fr.read();
System.out.println("ch1="+(char)ch1);
int ch2 = fr.read();
System.out.println("ch2="+(char)ch2);
int ch3 = fr.read();
System.out.println("ch3="+(char)ch3);
int ch4 = fr.read();
System.out.println("ch4="+ch4);//加入已知文件中只有三个字符,但是读了四个,此时ch4的值为-1,返回-1; //-1说明已经到达流的末尾,这样就有了循环条件 */
int ch = 0;
while((ch=fr.read())!=-1)
{ System.out.println("ch="+(char)ch); }
/*while(true)
{ int ch = fr.read();
if(ch==-1)
break;
System.out.println("ch="+(char)ch);
}*/
fr.close();
}
}******************************************************************************
第二种方式:通过字符数组进行读取。上机演示程序十*******************************
class FileReaderDemo2
{ public static void main(String[] args) throws IOException
{ FileReader fr = new FileReader("demo.txt");
//定义一个字符数组。用于存储读到字符。
//该read(char[])返回的是读到字符个数。假设文件中共10个字符
/*char[] buf = new char[3];
int num = fr.read(buf);
System.out.println("num="+num+"..."+new String(buf));
int num1 = fr.read(buf);
System.out.println("num1="+num1+"..."+new String(buf));
int num2 = fr.read(buf);
System.out.println("num2="+num2+"..."+new String(buf));
int num3 = fr.read(buf);//num返回1,
System.out.println("num3="+num3+"..."+new String(buf,0,1));new String(buf,0,1)可写成new String(buf,0,num);
int num4 = fr.read(buf);//已经到达了文件的末尾,num4返回-1
System.out.println("num3="+num3+"..."+new String(buf));
char[] buf = new char[1024];//如果定义长度为3,文件内容非常多,会循环对次,所以一般定义1024的整数倍!*/
int num = 0;
while((num=fr.read(buf))!=-1)
{ System.out.println(new String(buf,0,num)); }
fr.close();
}
}******************************************************************************
//读取一个.java文件,并打印在控制台上。
class FileReaderTest 上机演示程序十一*********************************************
{ public static void main(String[] args) throws IOException
{ FileReader fr = new FileReader("DateDemo.java");
char[] buf = new char[1024];
int num = 0;
while((num=fr.read(buf))!=-1)
{ System.out.print(new String(buf,0,num)); }
fr.close();
}
}******************************************************************************
//将C盘一个文本文件复制到D盘。/*
复制的原理:
其实就是将C盘下的文件数据存储到D盘的一个文件中。
步骤:
1,在D盘创建一个文件。用于存储C盘文件中的数据。
2,定义读取流和C盘文件关联。
3,通过不断的读写完成数据存储。
4,关闭资源。*/
class CopyText上机演示程序十二**************************************************
{ public static void main(String[] args) throws IOException
{ copy_2(); }
public static void copy_2()
{ FileWriter fw = null;
FileReader fr = null;
try
{
fw = new FileWriter("SystemDemo_copy.txt");
fr = new FileReader("SystemDemo.java");
char[] buf = new char[1024];
int len = 0;
while((len=fr.read(buf))!=-1)
{ fw.write(buf,0,len); }
}
catch (IOException e)
{ throw new RuntimeException("读写失败"); }
finally
{
if(fr!=null)
try
{ fr.close(); }
catch (IOException e)
{ }
if(fw!=null)
try
{ fw.close(); }
catch (IOException e)
{ } } }
//从C盘读一个字符,就往D盘写一个字符。
public static void copy_1()throws IOException
{ //创建目的地。 FileWriter fw = new FileWriter("RuntimeDemo_copy.txt");
//与已有文件关联。 FileReader fr = new FileReader("RuntimeDemo.java");
int ch = 0;
while((ch=fr.read())!=-1)
{
fw.write(ch);
} fw.close(); fr.close(); } }**************************************
复制文件原理图(上机演示程序十二)
//去饮水机喝水,但饮水机坏了,只能一滴一滴的滴,所以等你喝饱了………(水滴石穿)
//用个杯子接水(相当于缓冲),等接满了,一饮而尽,很爽,哈哈………
//缓冲区(内部封装了数组)出现是为了提高流的读写效率,所以必须要有输入输出流对象!/*缓冲区的出现是为了提高流的操作效率而出现的。所以在创建缓冲区之前,必须要先有流对象。该缓冲区中提供了一个跨平台的换行符。newLine();*/
class BufferedWriterDemo上机演示程序十二***************************************
{ public static void main(String[] args) throws IOException
{ //创建一个字符写入流对象。
FileWriter fw = new FileWriter("buf.txt");
//为了提高字符写入流效率。加入了缓冲技术。
//只要将需要被提高效率的流对象作为参数传递给缓冲区的构造函数即可。
BufferedWriter bufw = new BufferedWriter(fw);
bufw.write("abcde");//如果加入换行可将字符串改成"ab\r\ncdef",
//但是windows中换行是"\r\n",而lunix中换行是"\n",而"\r"显示为其他符号。
//所以BufferedWriter对象提供了newLine()方法,在windows和linux系统中都显示为换行for(int x=1; x<5; x++)
{ bufw.write("abcd"+x);
bufw.newLine();
bufw.flush();
}//记住,只要用到缓冲区,就要记得刷新。
//bufw.flush();
//其实关闭缓冲区,就是在关闭缓冲区中的流对象。
bufw.close();
}
}******************************************************************************
/*字符读取流缓冲区:该缓冲区提供了一个一次读一行的方法 readLine(返回值为字符串),方便于对文本数据的获取。当返回null时,表示读到文件末尾。
readLine方法返回的时候只返回回车符之前的数据内容。并不返回回车符。*/
class BufferedReaderDemo上机演示程序十三***************************************
{ public static void main(String[] args) throws IOException
{ //创建一个读取流对象和文件相关联。
FileReader fr = new FileReader("buf.txt");
//为了提高效率。加入缓冲技术。将字符读取流对象作为参数传递给缓冲对象的构造函数。BufferedReader bufr = new BufferedReader(fr);
String s1 = bufr.readLine();
System.out.println("s1:"+s1);
String s2 = bufr.readLine();
System.out.println("s2:"+s2);
String line = null;
while((line=bufr.readLine())!=null)
{ System.out.println(line); }//此处写成println(line):变成一行,不包含换行
bufr.close();
}
}******************************************************************************
/*通过缓冲区复制一个.java文件。*/
class CopyTextByBuf上机演示程序十四*******************************************
{ public static void main(String[] args)
{ BufferedReader bufr = null;
BufferedWriter bufw = null;
try
{ bufr = new BufferedReader(new FileReader("BufferedWriterDemo.java"));
bufw = new BufferedWriter(new FileWriter("bufWriter_Copy.txt"));
String line = null;
while((line=bufr.readLine())!=null)
{ bufw.write(line);
bufw.newLine();
bufw.flush();
}
}
catch (IOException e)
{ throw new RuntimeException("读写失败"); }
finally
{ try
{ if(bufr!=null)
bufr.close();
}
catch (IOException e)
{ throw new RuntimeException("读取关闭失败"); }
try
{
if(bufw!=null)
bufw.close();
}
catch (IOException e)
{
throw new RuntimeException("写入关闭失败");
} } } }******************************************************
/*明白了BufferedReader类中特有方法readLine的原理后,
可以自定义一个类中包含一个功能和readLine一致的方法。来模拟一下BufferedReader*/
class MyBufferedReader extends Reader上机演示程序十五******************************
{ private Reader r; //上面继承了Reader后必须重写Reader中的抽象方法
MyBufferedReader(Reader r)//将FileReader 变成Reader能接受更多类型的对象
{ this.r = r; }
//可以一次读一行数据的方法。
public String myReadLine()throws IOException
{ //定义一个临时容器。原BufferReader封装的是字符数组。
//为了演示方便。定义一个StringBuilder容器。因为最终还是要将数据变成字符串。
StringBuilder sb = new StringBuilder(); int ch = 0;
while((ch=r.read())!=-1)
{ if(ch=='\r')
continue;
if(ch=='\n')
return sb.toString();
else
sb.append((char)ch);
}
if(sb.length()!=0)
return sb.toString();
return null; }
/* 覆盖Reader类中的抽象方法。 */
public int read(char[] cbuf, int off, int len) throws IOException
{ return r.read(cbuf,off,len) ; }
public void close()throws IOException
{ r.close(); }
public void myClose()throws IOException
{ r.close(); }
}
class MyBufferedReaderDemo
{ public static void main(String[] args) throws IOException
{ FileReader fr = new FileReader("buf.txt");
MyBufferedReader myBuf = new MyBufferedReader(fr);
String line = null;
while((line=myBuf.myReadLine())!=null)
{ System.out.println(line); }
myBuf.myClose();
} }**********************************************************************
readLine原理图
/*装饰设计模式:当想要对已有的对象进行功能增强时,可以定义类,将已有对象传入,基于已有的功能,并提供加强功能。那么自定义的该类称为装饰类。
装饰类通常会通过构造方法接收被装饰的对象。
并基于被装饰的对象的功能,提供更强的功能。*/
class Person上机演示程序十六*****************************************************
{ public void chifan()
{ System.out.println("吃饭"); }
}
class SuperPerson
{ private Person p ;
SuperPerson(Person p)
{ this.p = p; }
public void superChifan()
{ System.out.println("开胃酒");
p.chifan();
System.out.println("甜点");
System.out.println("来一根");
}
}
class PersonDemo
{ public static void main(String[] args)
{ Person p = new Person();
//p.chifan();
SuperPerson sp = new SuperPerson(p);
sp.superChifan();
}
}******************************************************************************
/*MyReader//专门用于读取数据的类。
|--MyTextReader
|--MyBufferTextReader
|--MyMediaReader
|--MyBufferMediaReader
|--MyDataReader
|--MyBufferDataReader
class MyBufferReader
{ MyBufferReader(MyTextReader text) {}
MyBufferReader(MyMediaReader media) {}
}
上面这个类扩展性很差。找到其参数的共同类型。通过多态的形式。可以提高扩展性。
class MyBufferReader extends MyReader
{
private MyReader r;
MyBufferReader(MyReader r)
{}
}
MyReader//专门用于读取数据的类。
|--MyTextReader
|--MyMediaReader
|--MyDataReader
|--MyBufferReader
以前是通过继承将每一个子类都具备缓冲功能。那么继承体系会复杂,并不利于扩展。
现在优化思想。单独描述一下缓冲内容。将需要被缓冲的对象。传递进来。也就是,谁需要被缓冲,谁就作为参数传递给缓冲区。这样继承体系就变得很简单。优化了体系结构。
装饰模式比继承要灵活。避免了继承体系臃肿。
而且降低了类于类之间的关系。
装饰类因为增强已有对象,具备的功能和已有的是相同的,只不过提供了更强功能。
所以装饰类和被装饰类通常是都属于一个体系中的。
LineNumberReader(带着行号打印,并可以设置起始行号)是BufferedReader的子类
class LineNumberReaderDemo 上机演示程序十七************************************
{ public static void main(String[] args)throws IOException
{ FileReader fr = new FileReader("PersonDemo.java");
LineNumberReader lnr = new LineNumberReader(fr);
String line = null;
lnr.setLineNumber(100);//设置行号的起始编号
while((line=lnr.readLine())!=null)
{ //System.out.println(line);不带行号打印
System.out.println(lnr.getLineNumber()+":"+line);//带着行号打印
}
lnr.close();
}
}******************************************************************************
//自定义类实现LineNumberReader功能,并进行代码的优化。
class MyLineNumberReader上机演示程序十八***************************************
{ private int lineNumber;
MyLineNumberReader(Reader r)
{ super(r); }//因为extends MyBufferedReader,在父类中已经初始化,直接交给父类
public String myReadLine()throws IOException
{ lineNumber++;
return super.myReadLine();//父类已经实现的功能,用super直接调用
}
public void setLineNumber(int lineNumber)
{ this.lineNumber = lineNumber; }
public int getLineNumber()
{ return lineNumber; }
}
/*class MyLineNumberReader
{ private Reader r;
private int lineNumber;
MyLineNumberReader(Reader r)
{ this.r = r; }
public String myReadLine()throws IOException
{ lineNumber++;
StringBuilder sb = new StringBuilder();
int ch = 0;
while((ch=r.read())!=-1)
{ if(ch=='\r')
continue;
if(ch=='\n')
return sb.toString();
else
sb.append((char)ch);
}
if(sb.length()!=0)
return sb.toString();
return null;
}
public void setLineNumber(int lineNumber)
{ this.lineNumber = lineNumber; }
public int getLineNumber()
{ return lineNumber; }
public void myClose()throws IOException
{ r.close(); }
}*/
class MyLineNumberReaderDemo
{ public static void main(String[] args) throws IOException
{ FileReader fr = new FileReader("copyTextByBuf.java");
MyLineNumberReader mylnr = new MyLineNumberReader(fr);
String line = null;
mylnr.setLineNumber(100);
while((line=mylnr.myReadLine())!=null)
{ System.out.println(mylnr.getLineNumber()+"::"+line); }
mylnr.myClose();
}
}******************************************************************************
/*字符流:FileReader:读 FileWriter:写
BufferedReader:含有缓冲技术的读 BufferedWriter:含有缓冲技术的写
字节流:InputStream:读 OutputStream:写
需求,想要操作图片数据。这时就要用到字节流。复制一个图片.*/
class FileStream上机演示程序十九************************************************
{ public static void main(String[] args) throws IOException
{ readFile_3(); }
public static void readFile_3()throws IOException
{ FileInputStream fis = new FileInputStream("fos.txt");
// int num = fis.available();// System.out.println(“num=”+num);显示文件中字符的个数。
byte[] buf = new byte[fis.available()];//定义一个刚刚好的缓冲区。不用在循环了。
fis.read(buf);
System.out.println(new String(buf));
fis.close();
}
public static void readFile_2()throws IOException
{ FileInputStream fis = new FileInputStream("fos.txt");
byte[] buf = new byte[1024];
int len = 0;
while((len=fis.read(buf))!=-1)
{ System.out.println(new String(buf,0,len)); }
fis.close();
}
public static void readFile_1()throws IOException
{ FileInputStream fis = new FileInputStream("fos.txt");
int ch = 0;
while((ch=fis.read())!=-1)
{ System.out.println((char)ch); }
fis.close();
}
public static void writeFile()throws IOException
{ FileOutputStream fos = new FileOutputStream("fos.txt");
fos.write("abcde".getBytes());
fos.close();
}
}******************************************************************************
/*复制一个图片,思路:
1,用字节读取流对象和图片关联。
2,用字节写入流对象创建一个图片文件。用于存储获取到的图片数据。
3,通过循环读写,完成数据的存储。4,关闭资源。*/
class CopyPic上机演示程序二十**************************************************
{ public static void main(String[] args)
{ FileOutputStream fos = null;
FileInputStream fis = null;
try
{
fos = new FileOutputStream("c:\\2.bmp");
fis = new FileInputStream("c:\\1.bmp");
byte[] buf = new byte[1024];
int len = 0;
while((len=fis.read(buf))!=-1)
{ fos.write(buf,0,len); }
}
catch (IOException e)
{ throw new RuntimeException("复制文件失败"); }
finally
{ try
{
if(fis!=null)
fis.close();
}
catch (IOException e)
{ throw new RuntimeException("读取关闭失败"); }
try
{
if(fos!=null)
fos.close();
}
catch (IOException e)
{ throw new RuntimeException("写入关闭失败"); }
}
}
}******************************************************************************
演示mp3的复制。通过缓冲区。BufferedOutputStream BufferedInputStream
class CopyMp3上机演示程序二十一**********************************************
{ public static void main(String[] args) throws IOException
{ long start = System.currentTimeMillis();
copy_2();
long end = System.currentTimeMillis();
System.out.println((end-start)+"毫秒");
}
public static void copy_2()throws IOException
{
MyBufferedInputStream bufis = new MyBufferedInputStream(new FileInputStream("c:\\9.mp3"));
BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream("c:\\3.mp3"));
int by = 0;
//System.out.println("第一个字节:"+bufis.myRead());
while((by=bufis.myRead())!=-1)
{ bufos.write(by); }
bufos.close(); bufis.myClose();
}
//通过字节流的缓冲区完成复制。
public static void copy_1( ) throws IOException
{
BufferedInputStream bufis = new BufferedInputStream(new FileInputStream("c:\\0.mp3"));
BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream("c:\\1.mp3"));
int by = 0;
while((by=bufis.read())!=-1)//将硬盘数据存到缓冲区bufis中,然后再一个一个取出!
{ bufos.write(by); }
bufos.close(); bufis.close();
}
}******************************************************************************
//自定义字节缓冲区复制MP3
class MyBufferedInputStream上机演示程序二十二************************************
{ private InputStream in;
private byte[] buf = new byte[1024*4];
private int pos = 0,count = 0;
MyBufferedInputStream(InputStream in)
{ this.in = in; }
//一次读一个字节,从缓冲区(字节数组)获取。
public int myRead()throws IOException
{ //通过in对象读取硬盘上数据,并存储buf中。
if(count==0)
{
count = in.read(buf);
if(count<0)
return -1;
pos = 0;
byte b = buf[pos];
count--;
pos++;
return b&255;
}
else if(count>0)
{
byte b = buf[pos];
count--;
pos++;
return b&0xff;
}
return -1;
}
public void myClose()throws IOException{ in.close(); } }
11111111-111111110000000000101001001010100101010010101001010
byte: -1 ---> int : -1;
00000000 00000000 00000000 11111111 255
11111111 11111111 11111111 11111111
11111111 -->提升了一个int类型那不还是-1吗?是-1的原因是因为在8个1前面补的是1导致的。
那么我只要在前面补0,即可以保留原字节数据不变,又可以避免-1的出现。
怎么补0呢?
11111111 11111111 11111111 11111111
&00000000 00000000 00000000 11111111
------------------------------------
00000000 00000000 00000000 11111111
0000-0001
1111-1110
000000001
1111-1111 -1
结论:
字节流的读一个字节的read方法为什么返回值类型不是byte,而是int。
因为有可能会读到连续8个二进制1的情况,8个二进制1对应的十进制是-1.
那么就会数据还没有读完,就结束的情况。因为我们判断读取结束是通过结尾标记-1来确定的。
所以,为了避免这种情况将读到的字节进行int类型的提升。
并在保留原字节数据的情况前面了补了24个0,变成了int类型的数值。
而在写入数据时,只写该int类型数据的最低8位。************************************
读取键盘录入。System.out:对应的是标准输出设备,控制台(屏幕)。
System.in:对应的标准输入设备:键盘。
需求:通过键盘录入数据。
当录入一行数据后,就将该行数据进行打印。
如果录入的数据是over,那么停止录入。*/
class ReadIn上机演示程序二十三*************************************************
{ public static void main(String[] args) throws IOException
{ InputStream in = System.in;//System类中有in属性,定义格式:
//public static final InputStream in“标准”输入流。
//此流已打开并准备提供输入数据。通常,此流对应于键盘输入或者
//由主机环境或用户指定的另一个输入源。用System.in
//int by = in.read();//read方法是阻塞式方法,只要没有从键盘输入,
//int by1 = in.read();//就一直等,加入输入的"abc",
//System.out.println(by);//输出97,只读了一个字节
//System.out.println(by1);//输出98,只读第二个字节
//如果有三个输出,但是只输入了a(回车),会显示97,13,10,
//因为回车有有个字节\r和\n
System.out.println('\r'+0);//验证'\r'的值为13
system.out.println((int)'\n');//验证'\n'的值为10
StringBuilder sb = new StringBuilder();
//下面的小程序其实就是读一行数据的原理,也就是readLine方法。
while(true)
{ int ch = in.read();
if(ch=='\r')
continue;
if(ch=='\n')
{ String s = sb.toString();
if("over".equals(s))
break;
System.out.println(s.toUpperCase());
sb.delete(0,sb.length());
}
else
sb.append((char)ch); } }
}******************************************************************************
字符流:FileReader FileWriter BufferedReader BufferedWriter
字节流:FileInputStream FileOutputStream BufferedInputStream BufferedOutputStream
通过刚才的键盘录入一行数据并打印其大写,发现其实就是读一行数据的原理。
也就是readLine方法。
能不能直接使用readLine方法来完成键盘录入的一行数据的读取呢?
readLine方法是字符流BufferedReader类中的方法。
而键盘录入的read方法是字节流InputStream的方法。
那么能不能将字节流转成字符流在使用字符流缓冲去的readLine方法呢?
class TransStreamDemo上机演示程序二十四***************************************
{ public static void main(String[] args) throws IOException
{ //获取键盘录入对象。
//InputStream in = System.in;
//将字节流对象转成字符流对象,使用转换流。InputStreamReader
//InputStreamReader isr = new InputStreamReader(in);
//为了提高效率,将字符串进行缓冲区技术高效操作。使用BufferedReader
//BufferedReader bufr = new BufferedReader(isr);
//键盘的最常见写法。
BufferedReader bufr =
new BufferedReader(new InputStreamReader(System.in));
/* Sring line = null;
while((line = bufr.readLine())!=null)
{
if("over",equals(line))
break;
System.out.println(line.toUpperCase());
}*/
// OutputStream out = System.out;
// OutputStreamWriter osw = new OutputStreamWriter(out);
// BufferedWriter bufw = new BufferedWriter(osw);
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));
String line = null;
while((line=bufr.readLine())!=null)
{ if("over".equals(line))
break;
bufw.write(line.toUpperCase());
bufw.newLine();
bufw.flush();
}
bufr.close();
}
}******************************************************************************
1,源:键盘录入。目的:控制台。
2,需求:想把键盘录入的数据存储到一个文件中。
源:键盘。
目的:文件。
3,需求:想要将一个文件的数据打印在控制台上。
源:文件。
目的:控制台。
流操作的基本规律:
最痛苦的就是流对象有很多,不知道该用哪一个。
通过三个明确来完成。
1,明确源和目的。
源:输入流。InputStream Reader
目的:输出流。OutputStream Writer。
2,操作的数据是否是纯文本。
是:字符流。
不是:字节流。
3,当体系明确后,在明确要使用哪个具体的对象。
通过设备来进行区分:
源设备:内存,硬盘。键盘
目的设备:内存,硬盘,控制台。
1,将一个文本文件中数据存储到另一个文件中。复制文件。
源:因为是源,所以使用读取流。InputStream Reader
是不是操作文本文件。
是!这时就可以选择Reader
这样体系就明确了。
接下来明确要使用该体系中的哪个对象。
明确设备:硬盘。上一个文件。
Reader体系中可以操作文件的对象是 FileReader
是否需要提高效率:是!。加入Reader体系中缓冲区 BufferedReader.
FileReader fr = new FileReader("a.txt");
BufferedReader bufr = new BufferedReader(fr);
目的:OutputStream Writer
是否是纯文本。
是!Writer。
设备:硬盘,一个文件。
Writer体系中可以操作文件的对象FileWriter。
是否需要提高效率:是!。加入Writer体系中缓冲区 BufferedWriter
FileWriter fw = new FileWriter("b.txt");
BufferedWriter bufw = new BufferedWriter(fw);
练习:将一个图片文件中数据存储到另一个文件中。复制文件。要按照以上格式自己完成三个明确。
2,需求:将键盘录入的数据保存到一个文件中。
这个需求中有源和目的都存在。
那么分别分析
源:InputStream Reader
是不是纯文本?是!Reader
设备:键盘。对应的对象是System.in.
不是选择Reader吗?System.in对应的不是字节流吗?
为了操作键盘的文本数据方便。转成字符流按照字符串操作是最方便的。
所以既然明确了Reader,那么就将System.in转换成Reader。
用了Reader体系中转换流,InputStreamReader
InputStreamReader isr = new InputStreamReader(System.in);
需要提高效率吗?需要!BufferedReader
BufferedReader bufr = new BufferedReader(isr);
目的:OutputStream Writer
是否是存文本?是!Writer。
设备:硬盘。一个文件。使用 FileWriter。
FileWriter fw = new FileWriter("c.txt");
需要提高效率吗?需要。
BufferedWriter bufw = new BufferedWriter(fw);
**************
扩展一下,想要把录入的数据按照指定的编码表(utf-8),将数据存到文件中。
目的:OutputStream Writer
是否是存文本?是!Writer。
设备:硬盘。一个文件。使用 FileWriter。
但是FileWriter是使用的默认编码表。GBK.
但是存储时,需要加入指定编码表utf-8。而指定的编码表只有转换流可以指定。
所以要使用的对象是OutputStreamWriter。
而该转换流对象要接收一个字节输出流。而且还可以操作的文件的字节输出流。FileOutputStream
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("d.txt"),"UTF-8");
需要高效吗?需要。 BufferedWriter bufw = new BufferedWriter(osw);
所以,记住。转换流什么使用。字符和字节之间的桥梁,通常,涉及到字符编码转换时,
需要用到转换流。
练习:将一个文本数据打印在控制台上。要按照以上格式自己完成三个明确。
class TransStreamDemo2上机演示程序二十五**************************************
{ public static void main(String[] args) throws IOException
{
System.setIn(new FileInputStream("PersonDemo.java"));
//将默认的键盘输入源改成制定的文件作为输入源
System.setOut(new PrintStream("zzz.txt"));
//将默认的输出流控制台改成制定的文件。
//键盘的最常见写法。
BufferedReader bufr =
new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));
//默认编码表,指定为"GBK"和制定为"UTF-8"所产生的文件大小有区别
String line = null;
while((line=bufr.readLine())!=null)
{
if("over".equals(line))
break;
bufw.write(line.toUpperCase());
bufw.newLine();
bufw.flush();
}
bufr.close();
}
}******************************************************************************
上机演示程序二十六*************************************************************
import java.io.*;//异常信息打印到文件中。异常的日志信息
import java.util.*;
import java.text.*;
class ExceptionInfo
{ public static void main(String[] args)throws IOException
{ try
{
int[] arr = new int[2];
System.out.println(arr[3]);
}
catch (Exception e)
{ try
{
Date d = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String s = sdf.format(d);
PrintStream ps = new PrintStream("exeception.log");
ps.println(s);
System.setOut(ps);
}
catch (IOException ex)
{ throw new RuntimeException("日志文件创建失败"); }
e.printStackTrace(System.out);
}
}
}//log4j************************************************************************
将系统信息显示在屏幕上、输出到文件中。上机演示程序二十七
import java.util.*;import java.io.*;class SystemInfo************************************
{ public static void main(String[] args) throws IOException
{ Properties prop = System.getProperties();
//System.out.println(prop);
prop.list(new PrintStream("sysinfo.txt"));
}
}******************************************************************************
File类常见方法:
1,创建。
boolean createNewFile():在指定位置创建文件,如果该文件已经存在,则不创建,返回false。 和输出流不一样,输出流对象一建立创建文件。而且文件已经存在,会覆盖。
boolean mkdir():创建文件夹。 boolean mkdirs():创建多级文件夹。
2,删除。
boolean delete():删除失败返回false。如果文件正在被使用,则删除不了返回falsel。
void deleteOnExit();在程序退出时删除指定文件。
3,判断。 boolean exists() :文件是否存在.
isFile():
isDirectory();
isHidden();
isAbsolute();
4,获取信息。
getName():
getPath():
getParent():
getAbsolutePath()
long lastModified()
long length()
class FileDemo上机演示程序二十八************************************************
{ public static void main(String[] args) throws IOException
{ method_5(); }
public static void method_5()
{ File f1 = new File("c:\\Test.java");
File f2 = new File("d:\\hahah.java");
sop("rename:"+f2.renameTo(f1));
}
public static void method_4()
{ File f = new File("file.txt");
sop("path:"+f.getPath());
sop("abspath:"+f.getAbsolutePath());
sop("parent:"+f.getParent());//该方法返回的是绝对路径中的父目录。如果获取的是相对路径,返回null。 //如果相对路径中有上一层目录那么该目录就是返回结果。
}
public static void method_3()throws IOException
{ File f = new File("d:\\java1223\\day20\\file2.txt");
//f.createNewFile();
//f.mkdir();
//记住在判断文件对象是否是文件或者目的时,必须要先判断该文件对象封装的内容是否存在。
//通过exists判断。
sop("dir:"+f.isDirectory());
sop("file:"+f.isFile());
sop(f.isAbsolute()); }
public static void method_2()
{ File f = new File("file.txt");
//sop("exists:"+f.exists());//sop("execute:"+f.canExecute()); //创建文件夹
File dir = new File("abc\\kkk\\a\\a\\dd\\ee\\qq\\aaa");
sop("mkdir:"+dir.mkdirs()); }
public static void method_1()throws IOException
{ File f = new File("file.txt");
// sop("create:"+f.createNewFile());
//sop("delete:"+f.delete());
}//创建File对象
public static void consMethod()
{
//将a.txt封装成file对象。可以将已有的和为出现的文件或者文件夹封装成对象。
File f1 = new File("a.txt"); //
File f2 = new File("c:\\abc","b.txt");
File d = new File("c:\\abc");
File f3 = new File(d,"c.txt");
sop("f1:"+f1);
sop("f2:"+f2);
sop("f3:"+f3);
File f4 = new File("c:"+File.separator+"abc"+File.separator+"zzz"+File.separator+"a.txt");
}
public static void sop(Object obj)
{ System.out.println(obj); }
}******************************************************************************
class FileDemo2上机演示程序二十九*********************************************
{ public static void main(String[] args)
{ File dir = new File("c:\\");
File[] files = dir.listFiles();
for(File f : files)
{ System.out.println(f.getName()+"::"+f.length()); }
}
public static void listDemo_2()
{ File dir = new File("d:\\java1223\\day18");
String[] arr = dir.list(new FilenameFilter()
{ public boolean accept(File dir,String name)
{ //System.out.println("dir:"+dir+"....name::"+name);
/* if(name.endsWith(".bmp"))
return true;
else
return false;*/
return name.endsWith(".bmp");
}
}); //用匿名内部类的形式实现
System.out.println("len:"+arr.length);
for(String name : arr)
{ System.out.println(name); }
}
public static void listDemo()
{ File f = new File("c:\\abc.txt");
String[] names = f.list();//调用list方法的file对象必须是封装了一个目录。该目录还必须存在。打印该目录下的文件(所有文件,包含隐藏文件)和文件夹名称
for(String name : names)
{ System.out.println(name); }
}
public static void listRootsDemo()
{ File[] files = File.listRoots();
for(File f : files)
{ System.out.println(f); }
}
}******************************************************************************
列出指定目录下文件或者文件夹,包含子目录中的内容。也就是列出指定目录下所有内容。
因为目录中还有目录,只要使用同一个列出目录功能的函数完成即可。
在列出过程中出现的还是目录的话,还可以再次调用本功能。也就是函数自身调用自身。
这种表现形式,或者编程手法,称为递归。
递归要注意:1,限定条件。2,要注意递归的次数。尽量避免内存溢出。/
class FileDemo3上机演示程序三十*************************************************
{ public static void main(String[] args)
{ File dir = new File("d:\\testdir");
//showDir(dir,0); }
public static String getLevel(int level)
{ StringBuilder sb = new StringBuilder();
sb.append("|--");
for(int x=0; x
{ //sb.append("|--");
sb.insert(0,"| ");
}
return sb.toString();
}
public static void showDir_1(File dir)
{ System.out.println(dir); File[] files = dir.listFiles();
for(int x=0; x
{ if(files[x].isDirectory()) showDir(files[x]);
else System.out.println(files[x]); } }
public static void showDir(File dir,int level)
{ System.out.println(getLevel(level)+dir.getName());
level++;
File[] files = dir.listFiles();
for(int x=0; x
{
if(files[x].isDirectory())
showDir(files[x],level);
else
System.out.println(getLevel(level)+files[x]); } }
public static int getSum(int n)
{
if(n==1)
return 1;
return n+getSum(n-1);
}//递归演示图例(getSum)
public static void toBin(int num)
{ if(num>0)
{ toBin(num/2); System.out.println(num%2); } }///递归演示图例(toBin( ))
删除一个带内容的目录。
删除原理:
在window中,删除目录从里面往外删除的。
既然是从里往外删除。就需要用到递归。
class RemoveDir上机演示程序三十一*********************************************
{ public static void main(String[] args)
{ File dir = new File("d:\\testdir");
removeDir(dir);
}
public static void removeDir(File dir)
{ File[] files = dir.listFiles();
for(int x=0; x
{ if(files[x].isDirectory())
//隐藏目录java无法访问,会导致返回数组为空,会报出空指针异常。最好将判断条件改成:
//“不是隐藏文件并且是目录“if(!files[x].isHidden()&&files[x].isDirectory())”
removeDir(files[x]);
else
System.out.println(files[x].toString()+":-file-:"+files[x].delete());
}
System.out.println(dir+"::dir::"+dir.delete());
}
}******************************************************************************
/*练习
将一个指定目录下的java文件的绝对路径,存储到一个文本文件中。
建立一个java文件列表文件。
思路:
1,对指定的目录进行递归。
2,获取递归过程所以的java文件的路径。
3,将这些路径存储到集合中。
4,将集合中的数据写入到一个文件中。import java.io.*;import java.util.*;
class JavaFileList上机演示程序三十二*********************************************
{ public static void main(String[] args) throws IOException
{ File dir = new File("d:\\java1223");
List
fileToList(dir,list);
//System.out.println(list.size());
File file = new File(dir,"javalist.txt");
writeToFile(list,file.toString());
}
public static void fileToList(File dir,List
{ File[] files = dir.listFiles();
for(File file : files)
{ if(file.isDirectory())
fileToList(file,list);
else
{ if(file.getName().endsWith(".java"))
list.add(file);
}
}
}
public static void writeToFile(List
{ BufferedWriter bufw = null;
try
{ bufw = new BufferedWriter(new FileWriter(javaListFile));
for(File f : list)
{ String path = f.getAbsolutePath();
bufw.write(path);
bufw.newLine();
bufw.flush();
}
}
catch (IOException e)
{ throw e; }
finally
{ try
{ if(bufw!=null)
bufw.close();
}
catch (IOException e)
{ throw e; } } }
}******************************************************************************
Properties是hashtable的子类。
也就是说它具备map集合的特点。而且它里面存储的键值对都是字符串。不需要泛型。
是集合中和IO技术相结合的集合容器。该对象的特点:可以用于键值对形式的配置文件。
那么在加载数据时,需要数据有固定格式:键=值。
练习:限制程序运行次数。当运行次数到达5次时,给出,请您注册的提示。并不再让该程序执行。import java.io.*;import java.util.*;
class PropertiesDemo 上机演示程序三十三******************************************
{ public static void main(String[] args) throws IOException
{ //method_1(); loadDemo(); }
public static void loadDemo()throws IOException
{ Properties prop = new Properties();
FileInputStream fis = new FileInputStream("info.txt");
//将流中的数据加载进集合。
prop.load(fis);
prop.setProperty("wangwu","39");
FileOutputStream fos = new FileOutputStream("info.txt");
prop.store(fos,"haha");
// System.out.println(prop);
prop.list(System.out); fos.close(); fis.close(); }
//演示,如何将流中的数据存储到集合中。
//想要将info.txt中键值数据存到集合中进行操作。
/* 1,用一个流和info.txt文件关联。
2,读取一行数据,将该行数据用"="进行切割。
3,等号左边作为键,右边作为值。存入到Properties集合中即可。 */
public static void method_1()throws IOException
{ BufferedReader bufr = new BufferedReader(new FileReader("info.txt"));
String line = null;
Properties prop = new Properties();
while((line=bufr.readLine())!=null)
{ String[] arr = line.split("=");
///System.out.println(arr[0]+"...."+arr[1]);
prop.setProperty(arr[0],arr[1]);
}
bufr.close();
System.out.println(prop);
}
// 设置和获取元素。
public static void setAndGet()
{ Properties prop = new Properties();
prop.setProperty("zhangsan","30");
prop.setProperty("lisi","39");
// System.out.println(prop);
String value = prop.getProperty("lisi");
//System.out.println(value);
prop.setProperty("lisi",89+"");
Set
for(String s : names)
{ System.out.println(s+":"+prop.getProperty(s)); } }
}**************************************************************************
用于记录应用程序运行次数。如果使用次数已到,那么给出注册提示。很容易想到计数器。
可是该计数器定义在程序中,随着程序的运行而在内存中存在,并进行自增。
可是随着该应用程序的退出,该计数器也在内存中消失了。
下一次在启动该程序,又重新开始从0计数。
这样不是我们想要的。程序即使结束,该计数器的值也存在。
下次程序启动在会先加载该计数器的值并加1后在重新存储起来。
所以要建立一个配置文件。用于记录该软件的使用次数。
该配置文件使用键值对的形式。这样便于阅读数据,并操作数据。
键值对数据是map集合。数据是以文件形式存储,使用io技术。那么map+io -->properties.
配置文件可以实现应用程序数据的共享。
class RunCount上机演示程序三十四**********************************************
{ public static void main(String[] args) throws IOException
{ Properties prop = new Properties();
File file = new File("count.ini");
if(!file.exists())
file.createNewFile();
FileInputStream fis = new FileInputStream(file);
prop.load(fis);
int count = 0;
String value = prop.getProperty("time");
if(value!=null)
{ count = Integer.parseInt(value);
if(count>=5)
{ System.out.println("您好,使用次数已到,拿钱!"); return ; }
}
count++;
prop.setProperty("time",count+"");
FileOutputStream fos = new FileOutputStream(file);
prop.store(fos,"");
fos.close(); fis.close(); } }******************************************
打印流:该流提供了打印方法,可以将各种数据类型的数据都原样打印。
字节打印流:PrintStream
构造函数可以接收的参数类型:
1,file对象。File
2,字符串路径。String
3,字节输出流。OutputStream
字符打印流:PrintWriter
构造函数可以接收的参数类型:
1,file对象。File
2,字符串路径。String
3,字节输出流。OutputStream
4,字符输出流,Writer。
class PrintStreamDemo上机演示程序三十五****************************************
{ public static void main(String[] args) throws IOException
{ BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(new FileWriter("a.txt"),true); String line = null;
while((line=bufr.readLine())!=null)
{ if("over".equals(line))
break;
out.println(line.toUpperCase());
//out.flush();
} out.close(); bufr.close(); }****************************************** }
SequenceInputStream:此字节读取流可以将多条输入流串联成一个输入流,然后一个一个读取,读取玩第一个,读第二个,但是没有SequenceOutputStream,以下程序将3个文本文件中的内容合并到一个文件中。
class SequenceDemo 上机演示程序三十六*******************************************
{ public static void main(String[] args) throws IOException
{ Vector
v.add(new FileInputStream("c:\\1.txt"));
v.add(new FileInputStream("c:\\2.txt"));
v.add(new FileInputStream("c:\\3.txt"));
Enumeration
SequenceInputStream sis = new SequenceInputStream(en);
FileOutputStream fos = new FileOutputStream("c:\\4.txt");
byte[] buf = new byte[1024];
int len =0;
while((len=sis.read(buf))!=-1)
{
fos.write(buf,0,len);
}
fos.close();
sis.close();
}
}******************************************************************************
//文件的切割,将一张图片文件切割成3个文件,分别命名为1.prt 2.part 3.part
然后再将三个碎片文件合并成一个文件。
class SplitFile上机演示程序三十七*************************************************
{ public static void main(String[] args) throws IOException
{ //splitFile(); merge(); }
public static void merge()throws IOException // merge:[mə:dʒ]混合;相融;融入;
{ ArrayList
for(int x=1; x<=3; x++)
{ al.add(new FileInputStream("c:\\splitfiles\\"+x+".part")); }
final Iterator
Enumeration
{ public boolean hasMoreElements()
{
return it.hasNext();
}
public FileInputStream nextElement()
{
return it.next();
}
};
SequenceInputStream sis = new SequenceInputStream(en);
FileOutputStream fos = new FileOutputStream("c:\\splitfiles\\0.bmp");
byte[] buf = new byte[1024];
int len = 0;
while((len=sis.read(buf))!=-1)
{
fos.write(buf,0,len);
}
fos.close();
sis.close(); }
public static void splitFile()throws IOException
{ FileInputStream fis = new FileInputStream("c:\\1.bmp");
FileOutputStream fos = null;
byte[] buf = new byte[1024*1024];
int len = 0;
int count = 1;
while((len=fis.read(buf))!=-1)
{
fos = new FileOutputStream("c:\\splitfiles\\"+(count++)+".part");
fos.write(buf,0,len);
fos.close();
}
fis.close();
}
}******************************************************************************
对象的序列化。对象存储到文件中。
class Person implements Serializable上机演示程序三十八******************************
{ public static final long serialVersionUID = 42L;
private String name;
transient int age;//非静态成员用”transient [ˈtrænziənt] 短暂的;转瞬即逝的;临时的”修饰后也不能被序列化
static String country = "cn";//静态成员不能被序列化
Person(String name,int age,String country)
{
this.name = name;
this.age = age;
this.country = country;
}
public String toString()
{
return name+":"+age+":"+country;
}
}
class ObjectStreamDemo
{ public static void main(String[] args) throws Exception
{ //writeObj();
readObj();
}
public static void readObj()throws Exception//从文件中读取对象
{ ObjectInputStream ois = new ObjectInputStream(new FileInputStream("obj.txt"));
Person p = (Person)ois.readObject();
System.out.println(p);
ois.close();
}
public static void writeObj()throws IOException//将对象存储到文件中
{ ObjectOutputStream oos =
new ObjectOutputStream(new FileOutputStream("obj.txt"));
oos.writeObject(new Person("lisi0",399,"kr")); oos.close();}}****************************************************
class Read implements Runnable上机演示程序三十九**********************************
{ private PipedInputStream in;
Read(PipedInputStream in)
{ this.in = in; }
public void run()
{ try
{ byte[] buf = new byte[1024];
System.out.println("读取前。。没有数据阻塞");
int len = in.read(buf);
System.out.println("读到数据。。阻塞结束");
String s= new String(buf,0,len);
System.out.println(s);
in.close();
}
catch (IOException e)
{ throw new RuntimeException("管道读取流失败"); } } }
class Write implements Runnable
{ private PipedOutputStream out;
Write(PipedOutputStream out)
{ this.out = out; }
public void run()
{ try
{ System.out.println("开始写入数据,等待6秒后。");
Thread.sleep(6000);
out.write("piped lai la".getBytes());
out.close();
}
catch (Exception e)
{ throw new RuntimeException("管道输出流失败"); } } }
class PipedStreamDemo
{ public static void main(String[] args) throws IOException
{ PipedInputStream in = new PipedInputStream();
PipedOutputStream out = new PipedOutputStream();
in.connect(out);
Read r = new Read(in);
Write w = new Write(out);
new Thread(r).start();
new Thread(w).start();
}
}******************************************************************************
RandomAccessFile//随机读写访问文件
该类不算是IO体系中子类。
而是直接继承自Object。但是它是IO包中成员。因为它具备读和写功能。
内部封装了一个数组,而且通过指针对数组的元素进行操作。
可以通过getFilePointer获取指针位置,
同时可以通过seek改变指针的位置。
其实完成读写的原理就是内部封装了字节输入流和输出流。
通过构造函数可以看出,该类只能操作文件。而且操作文件还有模式:只读r,,读写rw等。
如果模式为只读 r。不会创建文件。会去读取一个已存在文件,如果该文件不存在,则会出现异常。如果模式rw。操作的文件不存在,会自动创建。如果存则不会覆盖。
class RandomAccessFileDemo 上机演示程序四十*************************************
{ public static void main(String[] args) throws IOException
{ //writeFile_2();
//readFile();
//System.out.println(Integer.toBinaryString(258));
}
public static void readFile()throws IOException
{ RandomAccessFile raf = new RandomAccessFile("ran.txt","r");
//调整对象中指针。
//raf.seek(8*1);
//跳过指定的字节数
raf.skipBytes(8);
byte[] buf = new byte[4];
raf.read(buf);
String name = new String(buf);
int age = raf.readInt();
System.out.println("name="+name);
System.out.println("age="+age);
raf.close();
}
public static void writeFile_2()throws IOException
{ RandomAccessFile raf = new RandomAccessFile("ran.txt","rw");
raf.seek(8*0);
raf.write("周期".getBytes());
raf.writeInt(103);
raf.close();
}
public static void writeFile()throws IOException
{ RandomAccessFile raf = new RandomAccessFile("ran.txt","rw");
raf.write("李四".getBytes());
raf.writeInt(97);
raf.write("王五".getBytes());
raf.writeInt(99);
raf.close();
}
}******************************************************************************
DataInputStream与DataOutputStream:以用于操作基本数据类型的数据的流对象。
class DataStreamDemo上机演示程序四十一******************************************
{ public static void main(String[] args) throws IOException
{ //writeData();
//readData();
//writeUTFDemo();
//OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("gbk.txt"),"gbk");
// osw.write("你好");
// osw.close();
// readUTFDemo();
}
public static void readUTFDemo()throws IOException
{ DataInputStream dis = new DataInputStream(new FileInputStream("utf.txt"));
String s = dis.readUTF();
System.out.println(s);
dis.close();
}
public static void writeUTFDemo()throws IOException
{ DataOutputStream dos = new DataOutputStream(new FileOutputStream("utfdate.txt"));
dos.writeUTF("你好");
dos.close();
}
public static void readData()throws IOException
{ DataInputStream dis = new DataInputStream(new FileInputStream("data.txt"));
int num = dis.readInt();
boolean b = dis.readBoolean();
double d = dis.readDouble();
System.out.println("num="+num);
System.out.println("b="+b);
System.out.println("d="+d);
dis.close();
}
public static void writeData()throws IOException
{ DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.txt"));
dos.writeInt(234);
dos.writeBoolean(true);
dos.writeDouble(9887.543);
dos.close();
ObjectOutputStream oos = null;
oos.writeObject(new O());
}
}******************************************************************************
用于操作字节数组的流对象。
ByteArrayInputStream :在构造的时候,需要接收数据源,。而且数据源是一个字节数组。
ByteArrayOutputStream:在构造的时候,不用定义数据目的,因为该对象中已经内部封装了可变长度的字节数组。这就是数据目的地。
因为这两个流对象都操作的数组,并没有使用系统资源。所以,不用进行close关闭。
在流操作规律讲解时:
源设备:盘 System.in,硬盘 FileStream,内存 ArrayStream。
目的设备: 控制台 System.out,硬盘FileStream,内存 ArrayStream。
用流的读写思想来操作数据。
class ByteArrayStream 上机演示程序四十二*****************************************
{ ublic static void main(String[] args)
{ //数据源。
ByteArrayInputStream bis = new ByteArrayInputStream("ABCDEFD".getBytes());
//数据目的
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int by = 0;
while((by=bis.read())!=-1)
{ bos.write(by); }
System.out.println(bos.size());
System.out.println(bos.toString());
// bos.writeTo(new FileOutputStream("a.txt"));
}
}******************************************************************************
class EncodeStream上机演示程序四十三********************************************
{ public static void main(String[] args) throws IOException
{ //writeText();
readText();
}
public static void readText()throws IOException
{ InputStreamReader isr = new InputStreamReader(new FileInputStream("utf.txt"),"gbk");
char[] buf = new char[10];
int len = isr.read(buf);
String str = new String(buf,0,len);
System.out.println(str);
isr.close();
}
public static void writeText()throws IOException
{
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("utf.txt"),"UTF-8");
osw.write("你好");
osw.close();
}
}******************************************************************************
编码:字符串变成字节数组。解码:字节数组变成字符串。
String-->byte[]; str.getBytes(charsetName); str.getBytes( ):不指定码表,默认问GBK
byte[] -->String: new String(byte[],charsetName); new String(byte[]):不指定码表,默认问GBK*/
class EncodeDemo上机演示程序四十四********************************************
{ public static void main(String[] args)throws Exception
{ String s = "哈哈";
byte[] b1 = s.getBytes("GBK");
System.out.println(Arrays.toString(b1));
String s1 = new String(b1,"utf-8");
System.out.println("s1="+s1);
//对s1进行iso8859-1编码。
byte[] b2 = s1.getBytes("utf-8");
System.out.println(Arrays.toString(b2));
String s2 = new String(b2,"gbk");
System.out.println("s2="+s2);
}}*************************************************************************
class EncodeDemo2 上机演示程序四十五*******************************************
{ public static void main(String[] args) throws Exception
{ String s = "联通ͨ";
byte[] by = s.getBytes("gbk");
for(byte b : by)
{ System.out.println(Integer.toBinaryString(b&255)); }
System.out.println("Hello World!"); } }**********************************
有五个学生,每个学生有3门课的成绩,
从键盘输入以上数据(包括姓名,三门课成绩),
输入的格式:如:zhagnsan,30,40,60计算出总成绩,
并把学生的信息和计算出的总分数高低顺序存放在磁盘文件"stud.txt"中。
1,描述学生对象。
2,定义一个可操作学生对象的工具类。
思想:
1,通过获取键盘录入一行数据,并将该行中的信息取出封装成学生对象。
2,因为学生有很多,那么就需要存储,使用到集合。因为要对学生的总分排序。
所以可以使用TreeSet。
3,将集合的信息写入到一个文件中。
class Student implements Comparable
{ private String name;
private int ma,cn,en;
private int sum;
Student(String name,int ma,int cn,int en)
{ this.name = name;
this.ma = ma;
this.cn = cn;
this.en = en;
sum = ma + cn + en;
}
public int compareTo(Student s)
{ int num = new Integer(this.sum).compareTo(new Integer(s.sum));
if(num==0)
return this.name.compareTo(s.name);
return num;
}
public String getName()
{ return name; }
public int getSum()
{ return sum; }
public int hashCode()
{ return name.hashCode()+sum*78; }
public boolean equals(Object obj)
{ if(!(obj instanceof Student))
throw new ClassCastException("类型不匹配");
Student s = (Student)obj;
return this.name.equals(s.name) && this.sum==s.sum;
}
public String toString()
{ return "student["+name+", "+ma+", "+cn+", "+en+"]"; }
}
class StudentInfoTool
{ public static Set
{ return getStudents(null); }
public static Set
{ BufferedReader bufr =
new BufferedReader(new InputStreamReader(System.in));
String line = null;
Set
if(cmp==null)
stus = new TreeSet
else
stus = new TreeSet
while((line=bufr.readLine())!=null)
{ if("over".equals(line))
break;
String[] info = line.split(",");
Student stu = new Student(info[0],Integer.parseInt(info[1]),
Integer.parseInt(info[2]),
Integer.parseInt(info[3]));
stus.add(stu);
}
bufr.close();
return stus;
}
public static void write2File(Set
{ BufferedWriter bufw = new BufferedWriter(new FileWriter("stuinfo.txt"));
for(Student stu : stus)
{ bufw.write(stu.toString()+"\t");
bufw.write(stu.getSum()+"");
bufw.newLine();
bufw.flush();
}
bufw.close();
}
}
class StudentInfoTest
{
public static void main(String[] args) throws IOException
{ Comparator
Set
StudentInfoTool.write2File(stus);
}
}******************************************************************************
ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------
详细请查看: