Properties
特点:
1,Hashtable的子类,map集合中的方法都可以用。
2,该集合没有泛型。键值都是字符串。
3,它是一个可以持久化的属性集。键值可以存储到集合中,也可以存储到持久化的设备上。
键值的来源也可以是持久化的设备。
4,有和流技术相结合的方法。load(InputStream) load(Reader) store(OutputStream,commonts); stro(Writer,comments);
-------------------------------------------
IO流的规律总结:解决的问题,就是开发中具体要使用哪个流对象的问题。
1,明确数据源,数据汇(数据目的)
其实就是在明确要使用的IO体系。InputStream OutputStream Reader Writer
需求中操作的是源:意味着是读。
InputStream Reader
需求中操作的目的:意味着是写。
OutputStream Writer
2,明确操作的数据是否是纯文本数据?
是,字符流。
否,字节流。
是并且是源。Reader
是并且也是目的,Writer。
通前两个明确,明确了具体要使用的体系。
接下来应该明确具体的体系中要使用哪个对象。
3,明确要操作的具体设备。每个设备都有对应的流对象。
源设备:
硬盘,能操作File的流对象都是。File开头。
键盘,System.in;
内存,数组。
网络,socket流。
目的设备:
硬盘,能操作File的流对象都是。File开头。
显示器,System.out
内存,数组。
网络。socket流。
到第三步明确就可以找到具体的流对象了。
4,需要额外功能吗?
需要高效吗?缓冲区,Buffered开头。
需要编码转换吗?转换流。
需求1:通过键盘录入数据,将数据保存到一个文件中。
明确一:有源吗?有,有目的吗?有。
源:InputStream Reader
目的:OutputStream Writer
明确二:是纯文本数据吗?是。
源:Reader
目的:Writer。
明确三:具体设备。
源设备:System.in;
目的设备:硬盘。
InputStream is = System.in;
FileWriter fw = new FileWriter("a.txt");
//将读取的字节存储到数组 read(byte[])
//将字节数组转成字符串。
//通过fw.write(string)写入到文件中。
//但是麻烦。因为明确源是Reader,需要将字节流转成字符流,这样操作文字就便捷了。
明确四:需要功能吗?
需要,转换。字节--->字符。InputStreamReader
InputStreamReader isr = new InputStreamReader(System.in);
FileWriter fw = new FileWriter("a.txt");
//一次读取一个字符。
//将读到的字符写入。
//当也可以定义字符数组缓冲区。
需要其他功能 吗?
需要,高效。Buffered
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
Bufferedwriter bufw = new BufferedWriter(new FileWriter("a.txt"));
//line = readLine();
//bufw.write(string); bufw.flush();
需求2:读取文本文件中的数据,将其打印到控制台上。
明确一:有源吗?有,有目的吗?有。
源:InputStream Reader
目的:OutputStream Writer
明确二:是纯文本。
源:Reader
目的:Writer
明确三:明确设备。
源设备:
硬盘:FileXXX
目的设备:
显示器:System.out
FileReader fr = new FileReader("a.txt");
OutputStream(PrintStream) out = System.out;
//fr读取数据到数组中。
//使用PrintStream直接调用println方法就可以打印了。如果使用OutputStream可以调用writer方法就可以将数据写入到显示器上。
//麻烦。
//因为源都是字符数据。可以通过字符流操作,将字符转成字节在给显示器。
需要额外功能吗?
需要转换 字符-->字节。
FileReader fr = new FileReader("a.txt");
OutputStreamWriter osw = new OutputStreamWriter(System.out);
//还需要额外功能吗?
需要高效。
BufferedReader bufr = new BufferedReader(new FileReader("a.txt"));
BufferedWriter bufw = new BufferdWriter(new OutputStreamWriter(System.out));
//读取一行数据。
//写入一行数据。
自己动手将下列需求按照流的规律写出来。
需求3:读取键盘录入的数据,转成大写打印到控制台上。录入over结束。
需求4:读取文本文件,将数据按照U8编码保存到文件中。
IO包中的其他功能流对象。
功能流对象
特点.解决的问题,特有方法。
打印流--输出流
PrintStream (字节流) PrintWriter(字符流)
特点:打印。不抛异常。
打印的目的:File对象,字符串路径,字节输出流。
解决问题:方便地打印各种数据值表示形式。
它的打印方法可以保证数值的表现形式不变。写的是什么样子,目的就是什么样子。
PrintWriter:一样具备打印功能。
目的:File对象,字符串路径,字节输出流,字符输出流。
---
序列流:
特点:流对象的有序的排列。
解决问题:将多个输入流合并成一个输入流。将多个源合并成一个源。对于多个源的操作会变的简单。
功能:特殊之处在构造函数上。一初始化就合并了多个流进来。
使用场景之一:对多个文件进行数据的合并。多个源对应一个目的。
自选题:对一个文件进行切割(一个源对应多个目的),切成碎片,在将碎片进行合并成原来的文件。
-------
用于操作对象的流对象。对象的序列化。
ObjectInputStream,ObjectOutputStream
特点:用于操作对象。
解决问题:可以将对象进行序列化和反序列化。注意:对象序列化一定要实现Serializable接口。为了给类定义一个serialVersionUID。
功能:ObjectInputStream readObject() ObjectOutputStream writeObject()
关键字:瞬态:transient
------
RandomAccessFile:
特点:只能操作文件。
既能读,又能写。
维护了一个byte数组。内部定义了字节流的读取和写入。
通过对指针的操作可以实现对文件的任意位置的读取和写入。
功能:getFilePointer seek用于操作文件指针的方法。
------
管道流。
特点:读取管道和写入管道可以连接。
需要使用多线程技术。单线程容易死锁。
功能:connect()
------------
操作基本数据值的对象。
DataInputStream DataOutputStream
用于操作基本数据类型值。
write基本类型 read基本类型。
----------
操作数组的流对象。
特点:不需要关闭。不抛出IO异常。
用IO的读写思想操作数组。
练习:
按照字节数截取一个字符串。"abc你好"如果截取到半个中文,舍弃。比如 截取4字节,abc。截取5个字节abc你。
定义功能实现。
字符串-->字节数组。编码
字节数组-->字符串。解码。
友情提示:GB2312编码的一个中文是两个字节,而且两个字节的最高位都是1.也就是说是一个负数。
============================================================
IO流的体系:
字节流
OutputStream
|--FileOutputStream:★★★★★
|--FilterOutputStream:no
|--BufferedOutputStream:★★★★★
|--DataOutputStream:
|--PrintStream:
|--ObjectOutputStream:
|--PipedOutputStream:
|--ByteArrayOutputStream:
InputStream
|--FileInputStream:★★★★★
|--FilterInputSteam:no
|--BufferedInputStream:★★★★★
|--DataInputStream:
|--ObjectInputStream:
|--PipedInputStream:
|--ByteArrayInputStream:
|--SequenceInputStream:
字符流
Reader
|--BufferedReader:★★★★★
|--LineNumberReader:
|--InputStreamReader:★★★★★
|--FileReader:★★★★★
|--CharArrayReader:
|--StringReader:
Writer
|--BufferedWriter:★★★★★
|--OutputStreamWriter:★★★★★
|--FileWriter:★★★★★
|--PrintWriter:★★★★★
|--CharArrayWriter:
|--StringWriter:
RandomAccessFile:
File:★★★★
/* *文件分割器 */ if(!srcFile.exists()){ throw new RuntimeException(srcFile.getAbsolutePath()+",源文件不存在"); } if(!destDir.exists()){ destDir.mkdirs(); } //1,读取源文件。 FileInputStream fis = new FileInputStream(srcFile); //2,创建目的引用。 FileOutputStream fos = null; //3,创建一个缓冲区。1M byte[] buf = new byte[1024*1024];//1M int count = 0; int len = 0; //4,往缓冲区存储数据。 while((len=fis.read(buf))!=-1){ //5,创建输出流。并明确要写入的文件对象。 File partFile = new File(destDir,(++count)+".part"); fos = new FileOutputStream(partFile); fos.write(buf,0,len); fos.close(); } //应该在产生碎片文件时,需要产生一个配置文件。记录碎片的个数和源文件的名字。 //partcount = 5; filename = 1.mp3; //配置文件中存储的键值信息。使用Properties集合。 Properties prop = new Properties(); prop.setProperty("partcount", Integer.toString(count)); prop.setProperty("filename", srcFile.getName()); File configFile = new File(destDir,(++count)+".properties"); fos = new FileOutputStream(configFile); prop.store(fos, "save part file info"); fos.close(); fis.close();
public class PipedStreamDemo { /** * @param args * @throws IOException */ public static void main(String[] args) throws IOException { //创建管道对象。 PipedInputStream pis = new PipedInputStream(); PipedOutputStream pos = new PipedOutputStream(); //将两个流连接上。 pis.connect(pos); new Thread(new Input(pis)).start(); new Thread(new Output(pos)).start(); } } //定义输入任务。 class Input implements Runnable{ private PipedInputStream pis; public Input(PipedInputStream pis) { super(); this.pis = pis; } @Override public void run() { byte[] buf = new byte[1024]; int len; try { len = pis.read(buf); String str = new String(buf,0,len); System.out.println(str); pis.close(); } catch (IOException e) { e.printStackTrace(); } } } //定义输出任务。 class Output implements Runnable{ private PipedOutputStream pos; public Output(PipedOutputStream pos) { super(); this.pos = pos; } @Override public void run() { //通过write写方法完成。 try { pos.write("hi,管道来了!".getBytes()); pos.close(); } catch (IOException e) { e.printStackTrace(); } } }
public class RandomAccessFileDemo { /** * @param args * @throws IOException */ public static void main(String[] args) throws IOException { /* * RandomAccessFile: * 特点: * 1,只能操作文件。 * 2,既能读,又能写。 * 3,维护了一个byte数组。内部定义了字节流的读取和写入。 * 4,通过对指针的操作可以实现对文件的任意位置的读取和写入。 */ writeFile(); readFile(); } public static void readFile() throws IOException { RandomAccessFile raf = new RandomAccessFile("tempfile\random.txt", "r"); //随机读取,只要通过设置指针的位置即可。 raf.seek(8*1); byte[] buf = new byte[4]; raf.read(buf); String name = new String(buf); int age = raf.readInt(); System.out.println(name+":"+age); raf.close(); } public static void writeFile() throws IOException { //1,创建一个随机访问文件的对象。文件不存在,则创建,存在,则不创建不覆盖。 RandomAccessFile raf = new RandomAccessFile("tempfile\random.txt", "rw"); //2,写入姓名和年龄。 raf.write("张三".getBytes()); raf.writeInt(97);//保证整数的字节原样性。 raf.write("李四".getBytes()); raf.writeInt(99);//保证整数的字节原样性。 //3,随机写入。 raf.seek(8);//设置指针的位置。 raf.write("王武".getBytes()); raf.writeInt(100); System.out.println(raf.getFilePointer()); raf.close(); } }