---------------------- android培训、java培训、期待与您交流! ----------------------
一、其他对象
(一)System类
1、获取系统属性信息:Properties getProperties();
import java.util.*;
class SystemDemo
{
public static void main(String[] args)
{
Properties prop = System.getProperties();
//因为Properties是Hashtable的子类,也就是Map集合的一个子类对象。
//那么可以通过Map的方法取出该集合中的元素
//该集合存储的都是字符串,没有泛型定义。
//在系统中自定义系统信息
System.setProperty("myname","beyond");
//获取单个系统信息
String value = System.getProperty("os.name");
System.out.println(value);
//在虚拟机启动时,动态加载一些属性信息 java -Dhaha=qqqq SyetemDemo
String v=System.getProperty("haha");
System.out.println(v);
//或取所有系统信息
for(Object obj:prop.keySet())
{
String values=(String)prop.get(obj);
System.out.println(obj+"::"+value);
}
}
}
(二)Runtime类
每个java应用程序都一个Runtime类实例,是应用程序能够与其运行的环境相连接,可以通过getRuntime方法获取当前运行时。
1、static Runtime getRuntime();
class RuntimeDemo
{
public static void main(String[] args)
{
Runtime r = Runtime.getRuntime();throws Exception
Process p=r.exec("c:\\winmine.exe");//执行一个程序。Process是一个类。
p.destroy();//杀进程
System.out.println("Hello World!");
}
}
(三)Date类
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日hh:mm:ss");
//调用format方法让模式格式化指定Date对象
String time= sdf.format(d);
System.out.println(time);
}
}
(四)Calendar类
import java.util.*;
import java.text*;
class CalendarDemo
{
public static void main(String[] args)
{
Calendar c = Calendar.getInstance();
//获取年月日
sop(c.get(Calendar.YEAR)+"年");
//设置年月日
c.set(2012,3,23);
//对时间量的偏移
c.add(Calendar.DAY_OF_MONTH,-18)//将日期向后退18天,显示18天后的日期
/*
Date d = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
String year =sdf.format(d);
System.out.println(year);
*/
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
(五)Math类
class MathDemo
{
public static void main(String[] args)
{
double b=Math.ceil(12.35);//向上取整
sop(b);
double b1=Math.floor(111.01);//向下取整
double b2=Math.round(15.34);//四舍五入
double b5=Math.pow(2,3);//2的3次方
sop(b5);
double b3 =Math.random();//产生一个>=0.0且<1的一个伪随机数
int b4 =(int)(Math.random()*10+1);//产生一个1到10之间的随机数
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
二、IO(Input Output)流
IO流用来处理设备间的数据传输,Java对数据的操作是通过流的方式,Java用于操作流的对象都在IO包中。流按操作的数据分为两种:字节流和字符流。流按流向分为:输出流和输入流。
(一)IO常用基类
1、字节流的抽象基类:InputStream,OutputSteam
2、字符流的抽象基类:Reader,Writer
(二)字符流事例演示
1、Writer的子类对象FileWriter,是用于专门操作文件的。
import java.io.*;
class FileWriterDemo
{
public static void main(String[] args) throws IOException
{
//创建一个FileWriter对象,该对象一被初始化就必须要明确要操作的文件
//而且该文件会被创建到指定目录下,如果该目录下已有同名文件,会被覆盖。
FileWriter fw=new FileWriter("demo.txt");
//调用write方法,将数据写入到流中
fw.write("abnjfiwfh");
//刷新流对象中的缓冲区中的数据,将数据刷到目的地中
fw.flush();
//关闭流资源,但是关闭之前会刷新一次内部的缓冲区的数据,将数据刷到目的地中
//和flush的区别是:flush刷新后流可以继续使用,close刷新后,会将流关闭。
fw.close();
}
}
2、IO异常的处理方式
import java.io.*;
class FileWriterDemo2
{
public static void main(String[] args)
{
FileWriter fw=null;//在外部建立对象的引用,方便在本方法中使用
try
{
fw = new FileWriter("demo.txt");
fw.write("akjfj");
}
catch (IOException e)
{
System.out.println(e.toString());
}
finally
{
try
{
if(fw!=null)//当fw为空时就不许用关闭流了
fw.close();
}
catch (IOException e)
{
System.out.println(e.toString());
}
}
}
}
3、文件的续写
import java.io.*;
class FileWriterDemo3
{
public static void main(String[] args)
{
FileWriter fw=null;
try
{
//传递一个true参数,代表不覆盖已有的文件,
//并在已有文件的末尾处进行数据续写.
fw=new FileWriter("demo.txt",true);
//在windows中换行\r\n
fw.write("nihao\r\nxiexie");
}
catch (IOException e)
{
System.out.println(e.toString());
}
finally
{
try
{
if(fw!=null)
fw.close()
}
catch (IOException e)
{
System.out.println(e.toString());
}
}
}
}
4、文本文件读取方式一
import java.io.*;
class FileReaderDemo
{
public static void main(String[] args) throws IOException
{
//创建文件读取流对象,和指定名称的文件相关联。
//要保证该文件是已经存在的。如果不存在,会发生异常FileNotFoundException
FileReader fr = new FileReader("demo.txt");
//调用读取对象的read方法,
//read()一次读一个字符。返回的是字符ASCII值,而且会自动往下读,读到末尾时返回-1.
int ch=0;
while((ch=fr.read())!=-1)
{
System.out.println((char)ch);
}
}
}
5、文本文件读取方式二
import java.io.*;
class FileReaderDemo2
{
public static void main(String[] args) throws IOException
{
//创建读取流对象,并且和指定文件相关联
FileReader fr = new FileReader("demo.txt");
//定义一个字符数组,用于存储读到的字符
//该read(char[])返回的是读到的字符个数,读到末尾时返回的是-1
char[] buf = new char{1024};
int num=0;
while((num=fr.read(buf))!=-1)
{
System.out.print(new String(buf,0,num));//将数组变成字符串打印
}
System.out.println("Hello World!");
fr.close();
}
}
6、拷贝文本文件
import java.io.*;
class FileReaderWriterDemo
{
public static void main(String[] args) throws IOException
{
//copy_1();
copy_2();
}
public static void copy_1()throws IOException
{
//创建一个文件写入流和自定义一个目标文件相关联
FileWriter fw = new FileWriter("copy.txt");
//创建一个文件读取流和被操作的文件相关联
FileReader fr= new FileReader("DateDemo.java");
int ch=0;
while((ch=fr.read())!=-1)
{
fw.write(ch);
}
fr.close();
fw.close();
}
public static void copy_2()
{
//首先,分别定义读取流和写入流对象
FileWriter fw = null;
FileReader fr=null;
try
{
fw = new FileWriter("copy1.txt");
fr = new FileReader("DateDemo.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)
{
}
}
}
}
(三)字符流的缓冲区
缓冲区的出现提高了对数据的读写效率。对应类有BufferedWriter和BufferedReader
缓冲区要结合流才能使用。在流的基础上对流功能进行了增强。
1、BufferedWriter 将文本写入字符输出流,缓冲各个字符,从而提供单个字符,数 组和字符串的高效写入。
import java.io.*;
class BufferedWriterDemo
{
public static void main(String[] args) throws IOException
{
//创建一个字符写入流对象,和目标文件相关联
FileWriter fw = new FileWriter("buffer.txt");
//创建一个字符写入流缓冲区对象和对应的流相关联
BufferedWriter bufw = new BufferedWriter(fw);
//开始写数据
for (x=0;x<3;x++)
{
// 使用缓冲区后,操作文件的都是缓冲区的了
bufw.write("feifei"+x);
bufw.newLine();//功能是换行。这是缓冲区提供的跨平台的换行符
bufw.flush();//只要使用缓冲区,就要记得刷新
}
//关闭缓冲区,就是在关闭缓冲区中的流对象
bufw.close();
}
}
2、BufferedReader 从字符输入流中读取文本,缓冲各个字符,从而实现字符,数组和行的搞笑读取。该缓冲区提供了一个一次读一行的方法:readLine()返回的是一个 字符串,不返回回车符,所以没有换行。当读到末尾时,则返回null。
import java.io.*;
class BufferedReaderDemo
{
public static void main(String[] args) throws IOException
{
//创建一个文件读取流和被读的文件相关联
FileReader fr = new FileReader("buffer.txt");
//为了提高效率,加入缓冲技术,将字符读取流对象作为参数传递给缓冲区对象的构造函数
BufferedReader buffr = new BufferedReader(fr);
//开始读,使用缓冲区提供的行读取方法readLine()
String str = null;
while((str=buffr.readLine())!=null)
{
System.out.println(str);
}
buffr.close();
}
}
3、通过缓冲区复制文件
import java.io.*;
class CopyTextByBuf
{
public static void main(String[] args)
{
// 在关闭时,只关闭两个缓冲区,所以只建立两个应用对象
BufferedWriter bufw=null;
BufferedReader bufr = null;
//对异常的处理步骤
try
{
bufw=new BufferedWriter(new FileWriter("copy.txt"));
bufr=new BufferedReader(new FileReader("DateDemo.java"));
String str=null;//两个流之间的中转站
while((str=bufr.readLine())!=null)
{
bufw.write(str);
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("写入关闭失败");
}
}
}
}
4、装饰设计模式
当想要对已有的对象进行功能增强时,可以定义类,将已有对象传入,基于已有功能,并提供加强功能,那么这个自定义的类称为装饰类。装饰类通常会通过构造方法接受被装饰的对象,并基于被装饰的对象的功能,提供更强的功能。下面以readLine方法为例进行分析:readLine方法实际上底层调用的是read方法和数组相结合实现的。
import java.io.*;
class MyBufferedReaderDemo
{
public static void main(String[] args) throws IOException
{
FileReader fr = new FileReader("DateDemo.java");
MyBufferedReader mbufr= new MyBufferedReader(fr);
String len=null;
while((len=mbufr.myReadLine())!=null)
{
System.out.println(len);
}
mbufr.myClose();
}
}
class MyBufferedReader
{
private FileReader r;
MyBufferedReader(FileReader r)
{
this.r=r;
}
public String myReadLine()throws IOException
{
//定义一个缓冲区
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 myClose()throws IOException
{
r.close();
}
}
5、装饰和继承的区别
装饰模式比继承要灵活,避免了继承体系的臃肿,而且降低了类与类之间的关系。装饰类因为增强了已有对象,具备的功能和已有对象的功能是相同的,只不过提供了更强 的功能而已。所以装饰类和被装饰的类都属于同一个体系中。
6、LineNumberReadershi是BufferedReader的子类,也是一个装饰类提供了获取行号和设置行号的方法,其原理如下:
import java.io.*;
class MyLineNumberReaderDemo
{
public static void main(String[] args) throws IOException
{
FileReader fr = new FileReader("DateDemo.java");
MyLineNumberReader mlnr = new MyLineNumberReader(fr);
String len = null;
mlnr.mySetLineNumber(100);
while((len=mlnr.myReadLine())!=null)
{
System.out.println(mlnr.myGetLineNumber()+"::"+len);
}
System.out.println("Hello World!");
}
}
class MyLineNumberReader
{
private Reader r ;
private int lineNumber;
MyLineNumberReader(Reader r)
{
this.r=r;
}
public void mySetLineNumber(int lineNumber)
{
this.lineNumber=lineNumber;
}
public int myGetLineNumber()
{
return lineNumber;
}
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 myClose()throws IOException
{
r.close();
}
}
(四)字节流File读写操作
1、字符文件的字节流操作
import java.io.*;
class FileStreamDemo
{
public static void main(String[] args)throws IOException
{
//writeFile();
readFile_3();
}
public static void writeFile()throws IOException
{
//创建一个字节流写入文件对象,和目的文件相关联
FileOutputStream fos= new FileOutputStream("stream.txt");
//调用写方法,向文件里写数据,因为是字节流对象,
//所以要把字符串变成字节数组
fos.write("abcdef".getBytes());//字符串变成字节数组
//因为是字节流操作,所以不用刷新,
fos.close();
}
public static void readFile_1()throws IOException
{
//创建一个字节流文件读取对象。跟要被操作的文件相关联
FileInputStream fis = new FileInputStream("stream.txt");
//第一种读取方法:一个一个字节的读
int num=0;
while((num=fis.read())!=-1)
{
System.out.println((char)num);
}
fis.close();
}
public static void readFile_2()throws IOException
{
FileInputStream fis = new FileInputStream("stream.txt");
int len = 0;
//定义一个字节流缓冲数组
byte[] buf = new byte[1024];
while((len=fis.read(buf))!=-1)
{
System.out.println(new String(buf,0,len));
}
fis.close();
}
public static void readFile_3()throws IOException
{
FileInputStream fis = new FileInputStream("stream.txt");
//定义了一个根文件大小刚刚好的数组
byte[] buf = new byte[fis.available()];
fis.read(buf);
System.out.println(new String(buf));
fis.close();
}
}
2、图像文件字节流操作
import java.io.*;
class CopyPic
{
public static void main(String[] args)
{
//创建读取流和写入流的对象
FileOutputStream fos = null;
FileInputStream fis = null;
try
{
fos = new FileOutputStream("2.bmp");
fis = new FileInputStream("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("关闭失败");
}
}
}
}
3、字节流的缓冲区
import java.io.*;
class CopyMp3
{
public static void main(String[] args) throws Exception
{
//建立缓冲区对象
FileOutputStream fos = new FileOutputStream("c:\\0.mp3");
BufferedOutputStream bos = new BufferedOutputStream(fos);
FileInputStream fis = new FileInputStream("c:\\1.mp3");
BufferedInputStream bis= new BufferedInputStream(fis);
int by = 0;
while((by=bis.read())!=-1)
{
bos.write(by);
}
bis.close();
bos.close();
}
}
4、读取键盘录入
import java.io.*;
/*
通过键盘录入数据,
当录入一行数据后,就将该行数据进行打印,
如果录入的数据是over,就停止录入。
*/
class ReadIn
{
public static void main(String[] args) throws IOException
{
//创建字节流键盘输入对象
InputStream in = System.in;
//建一个缓冲区,存入一行数据
StringBuilder sb = new StringBuilder();
//循环读取键盘录入
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);
}
}
}
5、读取转换流(InputStreamReader)
InputStreamReader是字节流通向字符流的桥梁,它使用指定的charset读取字节并将其解码为字符。它使用的字符集可以由名称指定或显示给定,或者可以接受平台默认的字符集。
import java.io.*;
class InputStreamDemo
{
public static void main(String[] args) throws IOException
{
//获取键盘录入对象
InputStream in = System.in;
//将字节流对象转换成字符流对象,使用转换流,InputStreamReader
InputStreamReader isr = new InputStreamReader(in);
//为了提高效率,将字符串进行缓冲区技术高效操作,使用BufferedReader
BufferedReader bufr = new BufferedReader(isr);
String len = null;
while((len=bufr.readLine())!=null)
{
if("over".equals(len))
break;
System.out.println(len.toUpperCase());
}
bufr.close();
}
}
6、写入转换流(OutputStreamWriter)
OutputStreamWriter 是字符流通向字节流的桥梁,它使用指定的charset将要写入流中的字符编码成字节。它使用的字符集可以由名称指定或显示给定,否则将接受平台默认的字符集。
import java.io.*;
class OutputStreamDemo
{
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));
//获取写入流对象
OutputStream out = System.out;
//将录入的字符流转换成字节流,
OutputStreamWriter osw = new OutputStreamWriter(out);
//为了提高效率,加入字符流输出缓冲区
BufferedWriter bufw= new BufferedWriter(osw);
String line= null;
while((line=bufr.readLine())!=null)
{
if("over".equals(line))
break;
bufw.write(line.toUpperCase());
bufw.newLine();
bufw.flush();
}
bufr.close();
}
}
7、流操作的规律
a.明确源和目的:源--->输入流:InputStream,Reader。
目的--->输入流:OutputStream,Writer。
b.操作的数据是否是纯文本:
是:字符流。
不是:字节流。
8、 改变标准输入输出设备
import java.io.*;
class OutputStreamDemo
{
public static void main(String[] args) throws IOException
{
//改变输入源
System.setIn(new FileInputStream("DateDemo.java"));
//改变输出目的
System.setOut(new PrintStream("pp.txt"));
//获取键盘录入对象
InputStream in = System.in;
//将字节流对象转换成字符流对象,使用转换流,InputStreamReader
InputStreamReader isr = new InputStreamReader(in);
//为了提高效率,将字符串进行缓冲区技术高效操作,使用BufferedReader
BufferedReader bufr = new BufferedReader(isr);
//键盘录入简写
//BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));
//获取写入流对象
OutputStream out = System.out;
//将录入的字符流转换成字节流,
OutputStreamWriter osw = new OutputStreamWriter(out);
//为了提高效率,加入字符流输出缓冲区
BufferedWriter bufw= new BufferedWriter(osw);
String line= null;
while((line=bufr.readLine())!=null)
{
if("over".equals(line))
break;
bufw.write(line.toUpperCase());
bufw.newLine();
bufw.flush();
}
bufr.close();
}
}
9、异常的日志信息
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("Exception.log");
//调用输出流对象的打印方法,将时间输出到日志文件
ps.println(s);
//修改输出设备
System.setOut(ps);
}
catch (IOException ex)
{
throw new RuntimeException("日志文件建立失败");
}
//将堆栈的异常信息打印到日志文件
e.printStackTrace(System.out);
}
}
}
10、系统信息
import java.io.*;
import java.util.*;
class SystemInfo
{
public static void main(String[] args) throws IOException
{
//获取系统信息
Properties prop = System.getProperties();
//创建打印流对象
PrintStream ps = new PrintStream("systeminfo.txt");
//将系统信息用键值对的形式打出
prop.list(ps);
//关闭流
ps.close();
}
}
三、File类
用来将文件或文件夹封装成对象,方便对文件与文件夹的属性信息进行操作,File对象可以作为参数传递给流的构造函数。
(一)File类方法演示
1、File类的构造方法
import java.io.*;
class FileDemo
{
public static void main(String[] args)
{
constructMethod();
}
public static void constructMethod()
{
//将文件封装成对象
File f1=new File("a.txt");
File f2=new File("D:\\EditPlus 3","a.txt");
//先封装一个父目录对象
File d=new File("D:\\EditPlus 3");
File f3=new File(d,"a.txt");
//使用java分隔符,创建跨平台的文件对象
File f4=
new File("D:"+File.separator+"EditPlus 3"+File.separator+"a.txt");
sop(f1);
sop(f2);
sop(f3);
sop(f4);
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
2、创建、删除、判断、获取信息
创建:boolean createNewFile();在指定位置创建文件,若创建成功,则返回 true。若该文件已经存在,则不创建,返回false。这和输出流不一样,输出流对象 一建立就创建文件,而且会覆盖已经存在的文件。
boolean mkdir();创建文件夹
boolean mkdirs();创建多级文件夹
删除:boolean delete();删除失败返回false。
void deleteOnExit();在程序退出时删除指定文件。
判断:boolean exists();文件是否存在。
isFile();
isDirectory();
isNidden();判断是否被隐藏。
isAbsolute();判断是否绝对的。
获取:getName();
getPath();
getParent();
getAbsolutePath();
long lastModified();获取最后一次修改的时间
long length();获取文件的长度
import java.io.*;
class FileDemo1
{
public static void main(String[] args) throws IOException
{
//method_3();
//fileNameFilter();
//listFiles();
File dir = new File("c:\\");
showDir(dir);
}
public static void method_1()throws IOException
{
File f = new File("a.txt");
//创建文件
System.out.println("create:"+f.createNewFile());
//删除文件
System.out.println("delete:"+f.delete());
//在退出程序时删除文件
f.deleteOnExit();
}
public static void method_2()
{
File f = new File("b.txt");
//记住在判断文件对象是否是文件或者文件夹时,必须要先判断该文件对象封 装的
//内容是否存在,通过exists判断。
//判断是否为文件夹
sop(f.isDirectory());
//判断是否为文件
sop(f.isFile());
}
public static void sop(Object obj)
{
System.out.println(obj);
}
public static void method_3()
{
File f= new File("a.txt");
sop("path"+f.getPath());
sop("Absolutepath"+f.getAbsolutePath());
sop("parent"+f.getParent());//返回的是绝对路径中的父目录,
//如果是相对路径,则返回空。如果相对路径中有上一层目录,那么该目录就 是返回的结果
}
public static void method_4()
{
//列出本机的所有盘符
File[] files= File.listRoots();
for(File f:files)
{
sop(f);
}
}
public static void listDemo()
{
File f = new File("c:\\");
//列出这个盘符下的文件以及文件夹
String[] names = f.list();//调用list方法的file对象必须封装了一个目录,
for(String name:names)//该目录还必须存在
{
sop(name);
}
}
public static void fileNameFilter()//文件过滤
{
File dir = new File("D:\\EditPlus 3");
String[] arr = dir.list(new FilenameFilter()//用匿名内部类实现接口
{
public boolean accept(File dir,String name)
{
return name.endsWith(".txt");
}
});
for(String name:arr)
{
sop(name);
}
}
public static void listFiles()
{
File file = new File("c:\\");
File[] arr = file.listFiles();//获取指定目录下的所有文件对象
for(File f:arr)
{
sop("name:"+f.getName()+"..."+"length::"+f.length());
}
}
/*
列出指定目录下的文件或者文件夹,包含子目录中的内容。也就是列出指定目录下所有内容。
因为目录中还有目录,只要使用同一个列出目录功能的函数完成即可。
在列出过程中出现的还是目录的话,还可以再次调用本功能。也就是函数自身调用自身。
这种表现形式,或者编程手法,称为递归。
*/
public static void showDir(File dir)
{
System.out.println(dir);
File[] arr= dir.listFiles();//列出文件夹下的所有文件对象
for(int x=0;x<arr.length;x++)
{
if(arr[x].isDirectory())
showDir(arr[x]);
else
System.out.println(arr[x]);
}
}
}
三、Properties简述
Properties是Hashtable的子类,也就是说它具备Map集合的特点。而且它里面存储的键值对都是字符串。Properties是集合和IO技术相结合的集合容器,该对象的特点是,可以用于键值对形式的配置文件。
(一)Properties存取
import java.io.*;
import java.util.*;
class PropertiesDemo
{
public static void main(String[] args)
{
setAndGet();
}
public static void setAndGet()
{
Properties prop = new Properties();
//设置集合元素
prop.setProperty("zhangsan","30");
prop.setProperty("lisi","20");
//获取集合元素
Set<String> names = prop.stringPropertyNames();
for(String name:names)
{
System.out.println("name"+name+"::"+prop.getProperty(name));
}
}
}
(二)Properties存取配置文件
1、方式一:自己定义方法
import java.io.*;
import java.util.*;
class PropertiesDemo
{
public static void main(String[] args) throws IOException
{
//setAndGet();
method_1();
}
//把配置文件的键值对读到集合中,
public static void method_1()throws IOException
{
//该操作中。源是文本文件。
BufferedReader bufr = new BufferedReader(new FileReader("info.txt"));
//创建一个Properties集合用于存储取到的键值对
Properties prop= new Properties();
//一次读一行数据
String line = null;
while((line=bufr.readLine())!=null)
{
//将读到的一行数据用等号分割
String[] arr = line.split("=");
//将分割出来的键和值分别存储到集合中
prop.setProperty(arr[0],arr[1]);
}
//关闭读取流
bufr.close();
System.out.println(prop);
}
}
2、Properties的加载方法load()
import java.io.*;
import java.util.*;
class PropertiesDemo
{
public static void main(String[] args) throws IOException
{
//setAndGet();
//method_1();
loadDemo();
}
public static void loadDemo()throws IOException
{
Properties prop = new Properties();
FileInputStream fis = new FileInputStream("info.txt");
//加载读取流
prop.load(fis);
//修改集合中指定键的值
prop.setProperty("wangjiao","20");
//将修改后的结果保存到文件
FileOutputStream fos = new FileOutputStream("info.txt");
prop.store(fos,"feifei");
//列出键值对
prop.list(System.out);
fis.close();
fos.close();
}
}
四、IO包中的其他类
(一)打印流
PrintWriter与PrintStream 可以直接操作输入流和文件。该流提供了打印方法,可以将各种数据类型的数据都原样打印。
1、字节流PrintStream ,构造函数可以接受的参数类型:
a.File对象:File
b、字符串路径,String
c、字节输出流,OutputStream
2、字符流PrintWriter,构造函数可以接受的参数类型:
a.File对象:File
b、字符串路径,String
c、字节输出流,OutputStream
d、字符输出流,Writer
import java.io.*;
class PrintStreamDemo
{
public static void main(String[] args)throws IOException
{
System.out.println("Hello World!");
printWriter();
}
public static void printWriter()throws IOException
{
//读取键盘录入
BufferedReader bufr =
new BufferedReader(new InputStreamReader(System.in));
//将键盘录入打印到指定文件中,使用字符打印流
//当参数为true的情况下,可以自动刷新
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());
}
bufr.close();
out.close();
}
}
(二)序列流(合并流)
SequenceInputStream 对多个流进行合并,SequenceInputstream表示其他输入流的逻辑串联,他从输入流的有序集合开始,并从第一个输入流开始读取,直到到达文件末尾,接着从第二个输入流读取,一次类推,直到到达包含的最后一个输入流的文件末尾为止。
import java.io.*;
import java.util.*;
class SequenceInputStreamDemo
{
public static void main(String[] args) throws IOException
{
System.out.println("Hello World!");
seguenceInputStream();
}
public static void seguenceInputStream()throws IOException
{
//因为要把多个文件合并成一个文件。所以涉及到了多个输入流,
//为了能够简单的输出到同一个文件,使用合并流将这些读取流合并
//首先。创建一个带有枚举的集合将这些输入流存储起来
Vector<FileInputStream> v = new Vector<FileInputStream>();
//第二步。把文件读取流对象存入到集合中
v.add(new FileInputStream("1.txt"));
v.add(new FileInputStream("2.txt"));
v.add(new FileInputStream("3.txt"));
//获取集合中的枚举对象,以便将这些流对象取出
Enumeration<FileInputStream> en = v.elements();
//第三步,创建一合并流,将集合中的流合并一个文件读取流
SequenceInputStream sis = new SequenceInputStream(en);
//第四步。创建一个文件输出流,将读取到的数据存入到指定文件
FileOutputStream fos = new FileOutputStream("4.txt");
byte[] buf = new byte[1024];
int len=0;
while((len=sis.read(buf))!=-1)
{
fos.write(buf,0,len);
}
sis.close();
fos.close();
}
}
(三)切割文件
import java.io.*;
import java.util.*;
class SplitFile
{
public static void main(String[] args)throws IOException
{
splitFile();
}
public static void splitFile()throws IOException
{
//创建一个文件读取流,将要切割的文件读取进来
FileInputStream fis = new FileInputStream("c:\\1.bmp");
//文件分割的思想是将文件分段读取分段存储
byte[] buf = new byte[1024*1024];
FileOutputStream fos=null;
int len= 0;
count=0;
while((len=fis.read(buf))!=-1)
{
fos = new FileOutputStream("c:\\"+(count++)+".part");
fos.write(buf,0,len);
fos.close();
}
fis.close();
}
public static void merge()throws IOException
{
ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
for (int x=1;x<=3;x++)
{
al.add(new FileInputStream("C:\\"+x+".part"));
}
//内部类访问的成员要final修饰
final Iterator<FileInputStream> it = al.iterator();
Enumeration en = new Enumeration<FileInputStream>()
{
public boolean hasMoreElements()
{
return it.hasNext();
}
public FileInputStream nextElement()
{
return it.next();
}
};
SequenceInputStream sis = new SequenceInputStream(en);
FileOutputStream fos = new FileOutputStream("c:\\2.bmp");
byte[] buf = new byte[1024];
int len = 0;
while ((len=sis.read(buf)!=-1)
{
fos.write(buf,0,len);
}
sis.close();
fos.close();
}
}
(四)操作对象(对象的序列化)
ObjectInputStream与ObjectOutputStream 被操作的对象需要实现Serializable(标记接口),此接口中没有方法,这个接口实际上是给类加上UID号。
import java.io.*;
class ObjectStreamDemo
{
public static void main(String[] args)throws Exception
{
//writeObj();
readObj();
}
public static void writeObj()throws IOException
{
//将一个对象数据写到文本文件中
//创建一个能操作对象的写入流对象,该对象实际上是对操作文件对象的一个 装饰
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("obj.txt"));
oos.writeObject(new Person("zhansan",30));
oos.close();
}
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();
}
}
//想要被流对象操作的类必须实现Serializable。注意:静态是不能被序列化的,因为在方法区
//如果给对象的属性加上transient,则该属性也不能被序列化。
class Person implements Serializable
{
//自定义一个序列号,当该类中有改变时,以前存储到文件的对象还能被读取
public static final long serialVersionUID=42L;//给类定义一个固定标示
private String name;
private int age;
Person(String name,int age)
{
this.name=name;
this.age=age;
}
public String toString()
{
return name+":"+age;
}
}
(五)管道流
PipedInputStream和PipedOutputStream 输入输出可以直接进行连接,不需要中转站,通过结合线程使用。
1、PipedInputStream管道输入流应该接到管道输出流;管道输入流提供要写入管道输出流的所有数据字节。通常,数据由某个线程从PipedInputStream对象读取,并由其他线程将其写入到相应的PipedOutputStream。不建议对这两个对象尝试使用单线程,因为这样可能思索线程。
import java.io.*;
class Read implements Runnable
{
private PipedInputStream in;
Read(PipedInputStream in)
{
this.in=in;
}
public void run()
{
try
{
byte[] buf =new byte[1024];
int len = in.read(buf);
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
{
out.write("gai dao lai le".getBytes());
out.close();
}
catch (IOException 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
随机访问文件,自身具备读写方法。随机访问文件的行为类似存储在文件系统中的一个大型的byte数组。通过skipBytes(int x),seek(int x);来达到随机访问。
该类不算是不算是IO体系中的子类,而是直接继承自Object。但是它是IO包中的成员,因为它具备读和写的功能。内部封装了一个数组,而且通过指针对数组进行操作,同时可以通过seek改变指针的位置。
其实完成读写的原理就是内部封装了字节流输入和输出。通过构造函数可以看出,该类只能操作文件。而且操作文件还有模式:只读r,读写rw等。如果模式为只读r,不会创建文件,回去读取一个已存在的文件,如果该文件不存在,则会出现异常。如果模式为rw,操作的文件不存在,会自动创建。如果存在则不会覆盖。
import java.io.*;
class RandomAccessFileDemo
{
public static void main(String[] args) throws IOException
{
//writeFile();
readFile_2();
}
public static void writeFile()throws IOException
{
//创建随机读取文件的对象
RandomAccessFile raf = new RandomAccessFile("raf.txt","rw");
//由于底层操作的是字节流,所以只能写字节数组
raf.write("邓飞飞".getBytes());
raf.writeInt(23);//为了以后的随机读取方便采用int类型的数据表示年龄
raf.write("王泽娇".getBytes());
raf.writeInt(24);
raf.close();
}
public static void readFile_1()throws IOException
{
RandomAccessFile raf= new RandomAccessFile("raf.txt","r");//文件模式 设为只读
//读取方式和字节流文件的操作方式一样
byte[] buf = new byte[6];
raf.read(buf);
String name = new String(buf);
int age = raf.readInt();
System.out.println("name"+name+"::"+age);
raf.close();
}
public static void readFile_2()throws IOException
{
RandomAccessFile raf= new RandomAccessFile("raf.txt","r");//文件模式 设为只读
//读取方式和字节流文件的操作方式一样
//调整对象中的指针的位置
//raf.seek(10);
//跳过指定的字节数读取。该方法只能向前跳
raf.skipBytes(10);
byte[] buf = new byte[6];
raf.read(buf);
String name = new String(buf);
int age = raf.readInt();
System.out.println("name"+name+"::"+age);
raf.close();
}
}
(七)操作基本数据类型的流对象
DataInputStream与DataOutputStream可用与操作基本类型数据的流对象
import java.io.*;
class DataStreamDemo
{
public static void main(String[] args)throws IOException
{
//writeData();
//readData();
writeUTFDemo();
readUTFDemo();
}
public static void writeData()throws IOException
{
//将基本数据类型写到文件中
DataOutputStream dos =
new DataOutputStream(new FileOutputStream("data.txt"));
dos.writeInt(305);
dos.writeDouble(123.04);
dos.writeBoolean(true);
dos.close();
}
public static void readData()throws IOException
{
//将文件中基本数据读出来,注意:读的顺序和写入的顺序要一致
DataInputStream dis =
new DataInputStream(new FileInputStream("data.txt"));
int num = dis.readInt();
double d=dis.readDouble();
boolean b = dis.readBoolean();
System.out.println(num);
System.out.println(d);
System.out.println(b);
dis.close();
}
public static void writeUTFDemo()throws IOException
{
DataOutputStream dos =
new DataOutputStream(new FileOutputStream("utfdata.txt"));
//使用指定编码集的写方法
dos.writeUTF("你好");
dos.close();
}
//用指定编码的写方法写的只能用对应的指定编码读的方法读取
public static void readUTFDemo()throws IOException
{
DataInputStream dis =
new DataInputStream(new FileInputStream("utfdata.txt"));
String s = dis.readUTF();
System.out.println(s);
dis.close();
}
}
(八)操作字节数组:ByteArrayInputstream与ByteArrayOutputstream
1.ByteArrayInputstream 包含一个内部缓冲区,该缓冲区包含从流中读取的字节。内部计数器跟踪read方法要提供的下一个字节。因为是操作字节数组,所以没有调用底层资源,所以不用关闭流。而且也不会发生异常。在构造的时候,需要传入数据源作为参数,而且数据源是一个字节数组。
2.ByteArrayOutputstream 此类实现了一个输出流,其中的数据被写入一个byte数组。缓冲区会随着数据的写入而自动增长。可以使用toByteArray()和toString()获取数据。不用关闭,而且也不会发生异常。在构造的时候,不用定义数据目的,应为该对象已经在内部封装了可边长度的字节数组,这就是数据的目的地。
import java.io.*;
class ByteArrayStream
{
public static void main(String[] args)
{
//数据源
ByteArrayInputStream bis = new ByteArrayInputStream("abcdefg".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());
}
}
(九)字符编码
字符流的出现是为了方便操作字符。更重要的是加入了编码转换。通过子类转换流完成。InputStreamReader和OutputstreamWriter,在两个对象进行构造的时候可以加入字符集
1.编码:字符串变成字节数组 str.getBytes(charsetname);
2.解码:字节数组变成字符串 new String(byte[],charsetname); Arrays.toString(byte[]);
import java.io.*;
class EncodeDemo
{
public static void main(String[] args)
{
String s= "你好";
//编码
byte[] b1 = s.getBytes("GBK");
System.out.println(Arrays.toString(b1));
//解码
String s1 = new String(b1,"GBK");
System.out.println(s1);
}
}
---------------------- android培训、java培训、期待与您交流! ----------------------