IO基础知识:
out:标准输出,默认是控制台。
In:标准输入,默认是键盘
获取系统属性信息:Properties getProperties();
System中常用字段、方法:
字段:
static InputStream in “标准”输入流 对应的是键盘
static PrintStream out “标准”输出流,对应的是控制台
方法:
static Properties getProperties(); 确定当前的系统属性
static String getProperty (String key) 获取指定键指示的系统属性
static String setProperty(String key,String value)设置指定键指示的系统属性
举例:
<span style="font-size:14px;">package day08;
import java.util.Properties;
import java.util.Set;
public class SystemDemo {
public static void main(String[] args) {
//获得系统属性,系统属性石以键值对存在
Properties pro =System.getProperties();
//获得键视图
Set set = pro.keySet();
//用高级for循环,根据键取值。
for(Object obj:set)
{
System.out.println(obj+"::"+pro.getProperty((String) obj));
}
// 自定义设置系统属性
pro.setProperty("lisi", "hshss");
//取出指定键值的属性值
System.out.println(pro.getProperty("os.name"));
System.out.println(pro.getProperty("lisi"));
}
}
</span>
Runtime: 每个Java应用程序都有一个Runtime类实例,使应用程序能够与其运行环境相连接。可以通过getRuntime方法获取当前运行时。
该类并没有提供构造函数,说明不可以new对象,那么会直接想到该类中的方法都是静态的,发现该类中没有非静态方法,说明该类肯定会提供了方法获取本类对象,而且该方法是静态的,并且返回值类型是本类类型。由这个特点可以看出该类使用了单例设计模式。
方法:
static Runtime getRuntime() 返回与当前Java程序相关联的运行时
Process exec(String command) 在单独的进程中执行指定的字符串命令
举例: //获取运行时
Runtime rt = Runtime.getRuntime();
//执行window程序
rt.exec("D:\\PPTV\\PPLive.exe");
Date表示特定的瞬间,精确到毫秒。
构造函数 Date()分配Date对象并初始化此对象,以表示分配它的时间(精确到毫秒)
SimpleDateFormat 是一个以与语言环境有关的方式来格式化和解析日期的具体类。它允许进行格式化(日期--->文本)、解析(文本---->日期)和规范化。
常用构造函数:SimpleDateFormat(String pattern)用给定的模式和默认语言环境的日期格式符号构造 SimpleDateFormat
常用方法:
String format(Date Date) 将一个Date格式化为日期/时间字符串。
举例:
<span style="font-size:14px;">package day08;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateDemo {
public static void main(String[] args) {
Date d = new Date();
System.out.println(d);
//将模式封装到SimpleDateFormat对象中
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
//调用format方法让模式格式化指定Date对象
String time = sdf.format(d);
System.out.println(time);
}
}
</span>
结果:
Sat Nov 29 19:05:32 CST 2014
2014年11月29日
Calender
常用方法:
abstract void add(int Field, int amount)根据日历的规则,为给定的日历字段添加或减去指定的时间量
static Calender getInstance() 使用默认的时区和语言环境获得一个日历
int get(int field) 返回给定字段的值
void set(int year,int month,int date)设置日历字段YEAR、MONTH、和DAY_OF_MONTH的值
举例:<span style="font-size:14px;">package day08;
import java.awt.print.Printable;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class DateDemo {
public static void main(String[] args) {
//获得一个实例
Calendar cal= Calendar.getInstance();
// 设置3天之后的日期的偏移量
cal.add(Calendar.DAY_OF_MONTH, 3);
//打印日期
Print(cal);
}
private static void Print(Calendar cal) {
String[] str ={"1月","2月","3月","4月",
"5月","6月","7月","8月",
"9月","10月","11月","12月"};
String[] str1={"","星期日","星期一","星期二","星期三","星期四",
"星期五","星期六"};
//计算机获取month是从o月开始算的,
int month = cal.get(Calendar.MONTH);
int week = cal.get(Calendar.DAY_OF_WEEK);
System.out.println(cal.get(Calendar.YEAR)+"年"+str[month]
+cal.get(Calendar.DAY_OF_MONTH)+"日"
+str1[week]);
}
}
</span>
Math
类
包含用于执行基本数学运算的方法,如初等指数、对数、平方根和三角函数。该类全为静态方法。
方法:
doubleceil(double d);//返回大于指定数据的最小整数
doublefloor(double d);//返回小于指定数据的最大整数
double pow(doublea,double b);//返回a的b次方
long round(doubleb);//返回b四舍五入的值
doublerandom();//返回正号的double值,是一个大于等于0.0且小于1.0的随机数
IO重点解析:
基础掌握
1.IO是inputoutput的缩写。
流概念:
流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。
2.特点:
IO流用来处理设备之间的数据传输
Java对数据的操作是通过流的方式
Java用于操作流的对象都在IO包中
流按操作数据分为两种:字节流与字符流
流按流向分为:输入流,输出流
字符流是为了处理文字数据 可以指定编码表
3.IO的常用基类,这里体现多态的应用,常用父类的引用指向子类对象
字节流的抽象基类:InputStream OutputStream
字符流的抽象基类:Reader Writer
字符流的重点掌握:
字符流的由来: 因为数据编码的不同,而有了对字符进行高效操作的流对象。本质其实就是基于字节流读取时,去查了指定的码表。 字节流和字符流的区别:
· 读写单位不同:字节流以字节(8bit)为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节。
· 处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据。
1.close()和flush()区别:
flush()刷新后,流可以继续使用;
而close()刷新后,将会关闭流,不可再写入字符流。
2.创建一个FileWriter对象,该对象一被初始化,就必须要明确被操作的文件。且该目录下如果已有同名文件,则同名文件将被覆盖。其实该步就是在明确数据要存放的目的地。
3.读取方式两种
第一种:read()一个字符一个字符读
第二种:建立字符数组,再读取,效率稍高。
1).定义文件路径时,可以用“/”或者“\\”。
2).在创建一个文件时,如果目录下有同名文件将被覆盖。
3).在读取文件时,必须保证该文件已存在,否则出异常。
4).文件数据的续写通过构造函数 FileWriter(Strings,boolean append);
举例:文件的copy
<span style="font-size:14px;">package day08;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class CopyDemo {
public static void main(String[] args)
{
BufferedWriter bufw=null;
BufferedReader bufr=null;
try {
//创建写缓冲对象
bufw= new BufferedWriter(new FileWriter("E://lianxi//1.txt"));
//创建读缓冲对象
bufr= new BufferedReader(new FileReader("E://lianxi//b.txt"));
int len=0;
char[] buf=new char[1024];
while((len=bufr.read(buf))!=-1)
{
//把数组的有效部分写入文件中
bufw.write(buf,0,len);
}
} catch (IOException e) {
e.printStackTrace();
}
finally {
if(bufw!=null)
try {
bufw.close();
} catch (IOException e) {
e.printStackTrace();
}
if(bufr!=null)
try {
bufr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
</span>
4.readline工作原理
readLine方法原理:
无论是读一行。或者读取多个字符。其实最终都是在在硬盘上一个一个读取。所以最终使用的还是read方法一次读一个的方法。
5.自定义缓冲区
(1)自定义的字符流读取缓冲区。其实就是内部封装了一个数组,把数组读满,在一个一个取出,其实就是模拟一个BufferedReader.
分析:
缓冲区中无非就是封装了一个数组,
并对外提供了更多的方法对数组进行访问。
其实这些方法最终操作的都是数组的角标。
缓冲技术原理:此对象内部封装了数组,将数据存入,再一次性取出。
在此次取完后,在从源中继续取一批数据进缓冲区。
当源中的数据取光时,用-1作为结束标记。
记住,只要用到缓冲区,就要记得刷新。(关闭流同样会刷新,但为了排除意外事故,保证数据存在,建议写入一次就刷新一次)
举例:
<span style="font-size:14px;">import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
public class MyBufferReader{
//想要Filereader的方法readline就要把Filereader对象传进来
private FileReader r;
//初始化时拥有一个Filereader对象
MyBufferReader(FileReader r){
this.r=r;
}
//自定义一个readline方法,一次可以读一行;
public String myReadLine() throws IOException{
//读一个存起来,可以用数组,但是我们用stringbuilder来模拟
//定义一个临时容器,原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中
sb.append((char)ch);
}
return null;
}
public void myclose() throws IOException
{
r.close();
}
public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("c:1.txt");
MyBufferReader mybuf = new MyBufferReader(fr);
String line = null;
while((line=mybuf.myReadLine())!=null)
{
System.out.println(line);
}
mybuf.myclose();
}
}
</span>
(2)自定义字节流读取缓冲区
是内部封装了一个数组,把数组读满,在一个一个取出。
package Impro;
import java.io.*;
//装饰类
class MyBufferedInputStream
{
//定义一个字节读取流,它是被装饰对象
InputStream in;
//定义字节数组
byte[] buf = new byte[1024];
//定义一个角标,一个计数器
int pos=0,count=0;
//初始化
MyBufferedInputStream(InputStream in)
{
this.in=in;
}
public int myRead() throws IOException
{
if(count==0)
{
//当计数器为0,就向数组读数据,用count记住数组长度,
count=in.read(buf);
pos=0;
//从数组中一个个取;
byte b=buf[pos];
pos++;
count--;
//&255,避免和结束标志重复,而提前复制结束。read方法将字节提升为32位INt型,我们只去低八位
return b&255;
}
else if(count>0)
{
byte b = buf[pos];
pos++;
count--;
return b&255;
}
return -1;
}
//关闭流,
public void myClose() throws IOException
{
in.close();
}
}
public class MyBufferedInputStreamDemo {
public static void main(String[] args) throws IOException {
//建立自定义缓冲区读取流的对象
MyBufferedInputStream mis =
new MyBufferedInputStream(new FileInputStream("E://a.mp3"));
//建立写入流对象,并关联文件
BufferedOutputStream bos =
new BufferedOutputStream(new FileOutputStream("E://a1.mp3"));
int ch =0;
//读一个字节,写入文件中
while((ch=mis.myRead())!=-1)
{
bos.write(ch);
}
//关闭流
mis.myClose();
bos.close();
}
}
6.装饰设计模式
1. 当想对已有对象进行功能增强时,可定义类:将已有对象传入,基于已有对象的功能,并提供加强功能,那么自定义的该类称之为装饰类。
2、特点
装饰类通常都会通过构造方法接收被装饰的对象,并基于被装饰的对象的功能,提供更强的功能。
3、装饰和继承的区别:
1)装饰模式比继承要灵活。避免了继承体系的臃肿,且降低了类与类之间的关系。
2)装饰类因为增强已有对象,具备的功能和已有的是相同的,只不过提供了更强的功能,所以装饰类和被装饰的类通常都是属于一个体系。
3)从继承结构转为组合结构。
注:在定义类的时候,不要以继承为主;可通过装饰设计模式进行增强类功能。灵活性较强,当装饰类中的功能不适合,可再使用被装饰类的功能。
举例:
<span style="font-size:14px;">public class PersonDemo {
public static void main(String[] args) {
Person p =new Person();
SuperPerson p1= new SuperPerson(p);
p1.chifan();
}
}
class Person
{
public void chifan()
{
System.out.println("吃饭");
}
}
//没有继承,自定义一个装饰类;
class SuperPerson
{
private Person p;
public SuperPerson(Person p) {
this.p=p;
}
public void chifan(){
System.out.println("开胃酒");
p.chifan();
System.out.println("甜点");
System.out.println("来一根");
}
}
</span>
注意:自定义的缓冲区也是应用了装饰类。
二、字节流重点掌握
1.字节流和字符流的基本操作是相同的,但字节流还可以操作其他媒体文件。
2、由于媒体文件数据中都是以字节存储的,所以,字节流对象可直接对媒体文件的数据写入到文件中,而可以不用再进行刷流动作。
3、读写字节流:InputStream 输入流(读)
OutputStream 输出流(写)
4、为何不用进行刷流动作:
因为字节流操作的是字节,即数据的最小单位,不需要像字符流一样要进行转换为字节。所以可直接将字节数据写入到指定文件中。
三、流操作规律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
InputStreamReaderisr = new InputStreamReader(System.in);
需要提高效率吗?
需要 BufferedReader
BufferedReaderbufr = new BufferedReader(isr);
目的:OutputStream Writer
是否是纯文本?是 Writer
设备:硬盘 Filewriter
需要提高效率吗? 需要 BufferedWriter
BufferedWriterbufw = new BufferedWriter(
newFileWriter(“d:\\a.txt”));
扩展一下,想要把录入的数据按照指定的编码表(UTF-8),将数据保存在文件中,
目的: OutputStream Writer
是否是纯文本,是 Writer
设备: 硬盘,一个文件 使用FileWriter
但是FileWriter是使用的默认编码表GBK
但是存储时,需要加入指定编码表UTF-8,而指定的编码表只有转换流可以指定
所以要使用的对象时OutputStreamWriter
而该转换流对象要接受一个字节输出流。而且还可以操作文件的字节输出流FileOutputStream
OutputStreamWriter osw = newOutputStreamWriter(new FileOutputStream(“d:\\a.txt”),”UTF-8”);
需要高效吗? 需要
所以,记住,转换流是字节和字符之间的桥梁,通常,涉及到字符编码转换时,需要用到转换流
一、File类:
1.File:文件和目录路径名的抽象表现形式
2.特点:
(1)用来将文件或文件夹封装成对象
(2)方便于对文件与文件夹的属性信息进行操作
(3)File类的实例是不可变的;也就是说,一旦创建,File对象表示的抽象路径名将永不改变
(4)File对象可以作为参数传递给流的构造函数
3.File创建对象的三种方式:
方式一:
File f =new File("a.txt");
将a.txt封装成File对象。可以将已有的和未出现的文件或者文件夹封装成对象。
方式二:
File f2=newFile("c:\\abc","b.txt");
将文件所在目录路径和文件一起传入,指定文件路径。
方式三:
File d=new File("c:\\abc");
File f3=new File(d,"c.txt");
将文件目录路径封装成对象。再创建文件对象。降低了文件于父目录的关联性。
小知识:
File.separator表示目录分隔符,可以跨平台使用。相当于路径中的“\”(双斜杠\\在windows中表示表示转义后的分隔符,但是在linux系统中就不是)。
递归
1、定义
当函数内每一次循环还可以调用本功能来实现,也就是函数自身调用自身。称为递归。
2、递归注意事项
a、限定条件。是来结束循环调用,否则是死循环。
b、注意递归的次数,尽量避免内存溢出。因为每次调用自身的时候都会先执行下一次调用自己的方法,所以会不断在栈内存中开辟新空间,次数过多,会导致内存溢出。
小例子:
package Impro;
public class DiguiDemo {
//十进制转成二进制
public static void toBin(int num)
{
if(num>0)
{
//如果不为0,继续调用自身,num/2,
toBin(num/2);
System.out.println(num%2);
}
}
public static void main(String[] args) {
toBin(20);
}
}
举例:
1.列举多级文件或文件夹,带层级的;
原理:当碰到文件夹时,继续调用自身函数,知道访问到文件为止;
package Impro;
import java.io.*;
public class ListFileDemo {
public static void main(String[] args) {
//关联指定目录
File dir = new File("E://黑马学习");
//列出所有目录
showDir(dir,0);
}
public static void showDir(File dir,int level)
{
//加层级输出
System.out.println(getLevel(level)+dir.getName());
level++;
//调用listFile方法,获取本目录下的所以文件和目录的抽象路径
File[] files=dir.listFiles();
//遍历
for(int i=0;i<files.length;i++)
{
if(files[i].isDirectory())
//如果是目录,继续递归
showDir(files[i], level);
else
//打印文件名
System.out.println(getLevel(level)+files[i].getName());
}
}
//带层级的列表
public static String getLevel(int level)
{
StringBuilder sb = new StringBuilder();
sb.append("|--");
//每多一级目录,就多添加“ ”,
for(int i=1;i<=level;i++)
{
//sb.append("|--");
sb.insert(0, " ");
}
return sb.toString();
}
}
练习2:删除多级文件目录
原理:目录从里往外删,用递归
package Impro;
import java.io.*;
public class RemoveDirDemo {
public static void main(String[] args) {
//指定目录
File dir= new File("E://黑马学习");
//删除目录
removeDir(dir);
}
//删除传入目录
public static void removeDir(File dir)
{
//列出目录下的所以文件和文件夹
File[] files=dir.listFiles();
for(int i=0;i<files.length;i++)
{
//如果还是目录,递归
if(files[i].isDirectory())
removeDir(files[i]);
else
//删除文
System.out.println(files[i].getName()+":::"+files[i].delete());
}
//删除目录
System.out.println(dir.getName()+"::"+dir.delete());
}
}
练习3:copy多级文件夹,先复制文件夹,在复制文件。
package Impro;
import java.io.*;
public class CopyDirDemo {
public static void main(String[] args) throws IOException {
//指定源目录
File dir= new File("E://黑马学习");
//指定目的目录
File d = new File("E://黑马学习2");
//copy目录
copyDir(dir, d);
}
public static void copyDir(File sourceDir, File desDir) throws IOException {
//创建指定目录
String name = sourceDir.getName();
File target = new File(desDir, name);
if (!target.exists())
target.mkdirs();
//列出源目录的所有文件目录或文件
File[] files = sourceDir.listFiles();
//遍历
for (File file : files) {
if (file.isDirectory())
//如果是目录,递归
copyDir(file, target);
else
//如果不是目录,copy文件
copyFile(file, new File(target, file.getName()));
}
}
public static void copyFile(File sourceFile, File desFile) throws IOException {
//建立读取流
BufferedInputStream bis =
new BufferedInputStream(new FileInputStream(sourceFile));
//建立写入流
BufferedOutputStream bos =
new BufferedOutputStream(new FileOutputStream(desFile));
int ch=0;
//读取的文件写入指定的目录
while((ch=bis.read())!=-1)
{
bos.write(ch);
}
//关闭流
bos.close();
bis.close();
}
}
练习4:将一个指定目录下的txt文件的绝对路径,存储到一个文本文件中。建立一个java文件列表的文件。
<span style="color:#000000;">package Impro;
import java.io.*;
import java.util.*;
public class JavaFileListDemo {
public static void main(String[] args) throws IOException {
//指定目录
File dir = new File("E://黑马学习");
//定义一个List集合,用于存储.java文件的File对象
List<File> list = new ArrayList<File>();
//调用获取文件路径方法
fileToList(dir, list);
//指定写入文件
File file = new File("E://heima.txt");
if(!file.exists())
file.createNewFile();
//调用写入文件方法
writeToFile(list, file.toString());
}
//获取指定文件夹内的所有java文件的绝对路径,并存入集合中
public static void fileToList(File dir,List<File> list)
{
File[] files=dir.listFiles();
for(File f:files)
{
if(f.isDirectory())
//如果是目录,则继续获取
fileToList(f,list);
else if(f.getName().endsWith(".txt"))
//将是.txt文件的绝对路径存入
list.add(f);
}
}
//将集合中元素写入到一个文本文件中
public static void writeToFile(List<File> list,String name) throws IOException
{
//建立字符流缓冲对象指定写入对象
BufferedWriter bw = new BufferedWriter(new FileWriter(name));
for(File f:list)
{
//写入
bw.write(f.getAbsolutePath());
//换行
bw.newLine();
//刷新
bw.flush();
}
bw.close();
}
}
</span>
一、Properties类
1、Properties是Hashtable的子类,它具备Map集合的特点。而且它里面还有存储的键值对,都是字符串,无泛型定义。是集合中和IO技术想结合的集合容器。简单说,Properties=map+IO;
2、特点:
1)可用于键值对形式的配置文件
2)在加载时,需要数据有固定的格式,常用的是:键=值
举例1:
//演示,如何将流中的数据存储到集合中。
//想要将info.txt中键值数据存到集合中进行操作。
/*
1,用一个流和info.txt文件关联。
2,读取一行数据,将该行数据用"="进行切割。
3,等号左边作为键,右边作为值。存入到Properties集合中即可。
*/
//将文件数据存储进Properties集合方法
public static void method()throws IOException
{
//使用字符读取缓冲流关联文件
BufferedReader bufr = new BufferedReader(new FileReader("info.txt"));
String line = null;
//定义Properties集合
Properties prop = new Properties();
while((line=bufr.readLine())!=null)
{
String[] arr = line.split("=");//将一行数据以“=”号进行分割
//将=左边作为键存入,将=右边作为值存入
prop.setProperty(arr[0],arr[1]);
}
bufr.close();//关流
System.out.println(prop);
}
举例2
/*
练习:用于记录应用程序运行次数。如果使用次数已到,那么给出注册提示。
原理:
很容易想到的是:计数器。可是该计数器定义在程序中,随着该应用程序的退出,该计数器也在内存中消失了。
所以要建立一个配置文件,用于记录该软件的使用次数。该配置文件使用键值对的形式。键值对数据是map集合。数据是以文件形式存储。使用io技术。那么map+io——>Properties。
思路:1、用读取流关联文本信息文件。如果存在则读取,如果不存在,则创建
2、每次运行,将文件数据存入集合中,读取值,判断次数,如果小于等于5次,则次数增加1次,如果大于则输出提示信息。
3、将值小于等于5次的信息数据存入文件中
*/
import java.util.*;
import java.io.*;
class RunCount
{
public static void main(String[] args)throws IOException
{
int count=runCount();
if(count>5)//如果程序被使用了超过5次,则终止使用,并提示
{
System.out.println("次数到了,交钱!!!!!");
return ;
}
else
System.out.println("程序第"+count+"次Run!");
}
//获取程序运行的次数
public static int runCount()throws IOException
{
Properties ps=new Properties();//创建集合对象
File file=new File("info.ini");//将文件进行封装
if(!file.exists())//判断是否存在
file.createNewFile();
FileReader fr=new FileReader(file);//将文件于读取流进行关联
ps.load(fr);//加载流中的文件数据到集合中
int count=0;//定义计数器
String value=ps.getProperty("time");//获取次数值
if(value!=null)//如过值不等于null,则将其赋值给count
{
count=Integer.parseInt(value);
}
count++;//每启动一次自增
ps.setProperty("time",count+"");//将次数记录住集合
FileWriter fw=new FileWriter(file);
ps.store(fw,"");//将集合中的数据存入硬盘文件中
fr.close();//关流
fw.close();
return count;//返回程序启动的次数
}
}
二、打印流
1.打印流包括:PrintStream和PrintWriter,该流提供了打印方法,可将各种类型的数据都原样打印。
字节打印流:PrintStream
构造方法中可接收的参数类型:
1、File对象。File
2、字符串路径:String
3、字符输出流:OutputStream
2.字符串打印流:PrintWriter
构造方法中可接受的参数类型
1、File对象:File
2、字符串路径:String
3、字节输出流:OutputStream 注意:很特殊,字符流的构造函数可以接受字节流。没有使用转换流
4、字符输出流:Writer
二、 序列流
SequenceInputStream对多个流进行合并,而且构造函数定义了泛型上限;
举例:
1.将三个文件中的数据合并到一个文件来
步骤:
1.创建vector集合。是为了获取Enumeration对象;
2.把三个文件添加进集合中,加入合并流
3.成为一个流后,和一般复制文件一样
import java.util.*;
import java.io.*;
class SequenceInputStreamDemo
{
public static void main(String[] args)throws IOException
{
//创建vector集合,并添加相关流对象
Vector<InputStream> ve=new Vector<InputStream>();
ve.add(new FileInputStream("E://1.txt"));
ve.add(new FileInputStream("E://2.txt"));
ve.add(new FileInputStream("E://3.txt"));
//创建枚举对象
Enumeration<InputStream> en=ve.elements();
//合并流
SequenceInputStream sis=new SequenceInputStream(en);
//关联写入文件
FileOutputStream fos=new FileOutputStream("E://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();
}
}
举例2:
切割文件
需求:将一个mp3文件按1M大小切割成几部分
步骤:
1、使用文件字节流关联mp3文件
2、定义一个容器存储1M大小的数据,当存储满时,写入一个新文件中
import java.util.*;
import java.io.*;
class SplitFile
{
public static void main(String[] args) throws IOException
{
//指定要切割的文件
File file=new File("E://a.mp3");
//将指定文件进行切割
splitFile(file);
//指定要合并到的文件
File file1=new File("E://a1.mp3");
//将部分文件进行合并指定文件中
merge(file1);
}
//接收一个文件,将其按1M大小进行切割
public static void splitFile(File file)throws IOException
{
//关联要切割的文件
BufferedInputStream bis=new BufferedInputStream(new FileInputStream(file));
BufferedOutputStream bos=null;
//定义1M大小存储容器
byte[] buf=new byte[1024*1024];
int len=0,x=0;
while ((len=bis.read(buf))!=-1)
{
//每满1M就写入一个新文件中
bos=new BufferedOutputStream(new FileOutputStream("E:\\"+(++x)+".part"));
bos.write(buf,0,len);
//每次写完一个文件要记得关流
bos.close();
}
//关流
bis.close();
}
//将部分文件合并为一个文件
public static void merge(File file)throws IOException
{
//定义一个集合存储这些部分文件关联路径数据
ArrayList<FileInputStream> al=new ArrayList<FileInputStream>();
for (int x=1;x<=6 ; x++)
{
al.add(new FileInputStream("E:\\"+x+".part"));
}
//因为Enumeration是Vector特有的迭代方法,所以这里创建一个Enumeration类型的匿名内部类
final ListIterator<FileInputStream> it=al.listIterator();
Enumeration<FileInputStream> 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(file);
//定义临时存储数据的数组
byte[] buf=new byte[1024];
int len=0;
while((len=sis.read(buf))!=-1)
{
fos.write(buf,0,len);//写数据
}
//关流
fos.close();
sis.close();
}
}