Properties類:
Properties類概述:
- Properties是hashtable的子類。也就是說它具備map集合的特點。而且它裡面存儲的鍵值對都是字元串,不需要泛型定義。
- Properties是不僅可以操作鍵值對資訊,而且可以操作硬碟上的鍵值對資訊。是集合中和IO技術相結合的集合容器。
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);
//setProperty改變的是記憶體的結果
prop.setProperty("wangwu","39");
FileOutputStream fos = new FileOutputStream("info.txt");
//haha是注入資訊,注釋,#代表注釋資訊,不會被Properties所加載,Properties所加載的資訊必須是鍵值對
//那麼在加載資料時,需要資料有固定的格式,鍵=值
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)
{
//split是切割
String[] arr = line.split("=");
///System.out.println(arr[0]+"...."+arr[1]);
prop.setProperty(arr[0],arr[1]);
}
bufr.close();
System.out.println(prop);
}
//設定和擷取元素。set和get方法
public static void setAndGet()
{
Properties prop = new Properties();
//setProperty設定鍵值對
prop.setProperty("zhangsan","30");
prop.setProperty("lisi","39");
// System.out.println(prop);
String value = prop.getProperty("lisi");
//System.out.println(value);
//89+""轉化成字元型
prop.setProperty("lisi",89+"");
Set<String> names = prop.stringPropertyNames();
for(String s : names)
{
System.out.println(s+":"+prop.getProperty(s));
}
}
}
配置檔案:
用于記錄應用程式的運作次數,當運作次數已到, 給出 注冊的提示。并不再讓該程式執行。
1·很容易想到的是:計數器。
可是該計數器定義在程式中,随着程式的運作而在記憶體中存在,并進行自增。
可是随着該應用程式的退出,該計數器也在記憶體中消失了。
2·下一次在啟動該程式,又重新開始從0計數。
這樣不是我們想要的。
3·程式即使結束,該計數器的值也存在。
下次程式啟動在會先加載該計數器的值并加1後在重新存儲起來。
4·是以要建立一個配置檔案。用于記錄該軟體的使用次數。
5·該配置檔案使用鍵值對的形式。這樣便于閱讀資料,并操作資料。
6·鍵值對資料是map集合。資料是以檔案形式存儲,使用io技術。那麼map+io -->properties.
配置檔案可以實作應用程式資料的共享。
現在要用的配置檔案有兩種:鍵值對的和xml檔案
dom4j: dom for java解析xml檔案
import java.io.*;
import java.util.*;
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();
}
}
/*
name=zhangsan
age=20
<persons>
<person id="001">
<name>zhagnsan</name>
<age>30</age>
<address>bj</address>
</person>
<person>
<name>...
</person>
</persons>
*/
列印流:
列印流概述:
1、列印流包括:PrintStream和PrintWriter
2、該流提供了列印方法,可以将各種資料類型的資料都原樣列印。
位元組列印流:PrintStream
構造方法中可接收的參數類型:
1、file對象。File2、字元串路徑:String 3、字元輸出流:OutputStream
字元串列印流:PrintWriter
構造方法中可接受的參數類型
1、file對象:File2、字元串路徑:String3、位元組輸出流:OutputStream4、字元輸出流:Writer
import java.io.*;
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();
}
}
序列流(合并流):
序列流(合并流)概述:
1.序列流SequenceInputStream沒有直接對應OutputStream,表示其它輸入流的邏輯串聯
2·SequenceInputStream可以将多個流連接配接成一個源
3·構造函數:
SequenceInputStream(Enumeration<? extends FileInputStream> e)
class SequenceDemo
{
public static void main(String[] args) throws IOException
{
Vector<FileInputStream> v = new Vector<FileInputStream>();
v.add(new FileInputStream("c:\\1.txt"));
v.add(new FileInputStream("c:\\2.txt"));
v.add(new FileInputStream("c:\\3.txt"));
//Enumeration是個接口不是類(列舉)為了實作周遊枚舉也用于将輸入流指定到 SequenceInputStream 中。
//注:此接口的功能與 Iterator 接口的功能是重複的。此外,Iterator 接口添加了一個可選的移除操作,并使用較短的方法名。
//新的實作應該優先考慮使用 Iterator 接口而不是 Enumeration 接口。
Enumeration<FileInputStream> en = v.elements();
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();
}
}
切割流資源:
1、先關聯檔案FileInputStream
2、定義寫入流變量:FileOutputStream
3、建立數組,并定義切割所需的大小|
4、循環讀寫資料,并每次建立一個新寫入流,建立完後并寫入檔案中
5、關閉流資源
import java.io.*;
import java.util.*;
class SplitFile
{
public static void main(String[] args) throws IOException
{
//splitFile();
merge();
}
public static void merge()throws IOException
{
ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
for(int x=1; x<=3; x++)
{
al.add(new FileInputStream("c:\\splitfiles\\"+x+".part"));
}
final Iterator<FileInputStream> it = al.iterator();
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("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();
}
}
對象序列化
将堆記憶體中的對象存入硬碟,保留對象中的資料,稱之為對象的持久化(或序列化)
特有方法:
1、write(int val) ---> 寫入一個位元組(最低八位)
2、writeInt(int vale) ---> 吸入一個32為int值
/*
對象的序列化
*/
import java.io.*;
//對象序列化測試
class ObjectStreamDemo
{
public static void main(String[] args) throws Exception
{
//對象寫入流
writeObj();
//對象讀取流
readObj();
}
//定義對象讀取流
public static void readObj()throws Exception
{
//ObjectInputStream對細節對象進行操作
//建立對象讀取流
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();
}
}
/*
沒有方法的接口通常稱為标記
*/
import java.io.*;
//建立Person類,實作序列化
class Person implements Serializable
{
//定義自身的序列化方式
public static final long serialVersionUID = 42L;
/*serialVersion
給類一個可被編譯器識别的的序列号,在編譯類時,會配置設定一個long型UID,通過序列号,
将類存入硬碟中,并序列化,即持久化。序列号根據成員算出的。
靜态不能被序列化。如果非靜态成員也無需序列化,可以用transien修飾。*/
//定義私有屬性
private String name;
//age被transient修飾後就不能被序列化了,保證其值隻在堆記憶體中存在,而不再文本檔案中存在
transient int age;
//靜态成員變量不能被序列化
static String country = "cn";
//構造Person類
Person(String name,int age,String country)
{
this.name = name;
this.age = age;
this.country = country;
}
//覆寫toString方法
public String toString()
{
return name+":"+age+":"+country;
}
}
管道流:
PipedInputStream和PipedOutputStream是涉及到多線程技術的IO流對象。
步驟:
1、要先建立一個讀和寫的兩個類,實作Runnable接口,因為是兩個不同的線程,覆寫run方法,注意,需要在内部抛異常
2、建立兩個管道流,并用connect()方法将兩個流連接配接
3、建立讀寫對象,并傳入兩個線程内,并start執行
/*
管道流技術,涉及多線程技術
*/
import java.io.*;
//建立Read類,實作run方法
class Read implements Runnable
{
private PipedInputStream in;
Read(PipedInputStream in)
{
this.in = in;
}
//實作run方法
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("管道讀取流失敗");
}
}
}
//建立Write類
class Write implements Runnable
{
private PipedOutputStream out;
//Write構造函數
Write(PipedOutputStream out)
{
this.out = out;
}
//實作run方法
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 類
RandomAccessFile 類概述:
1、RandomAccessFile稱之為随機通路檔案的類,自身具備讀寫方法。
2、該類不算是IO體系中的子類,而是直接繼承Object,但是它是IO包成員,因為它具備讀寫功能,内部封裝了一個數組,且通過指針對數組的元素進行操作,同時可通過seek改變指針的位置。
3、可以完成讀寫的原理:内部封裝了位元組輸入流
4、構造函數:RandomAccessFile(File file,String mode),可已從它的構造函數中看出,該類隻能操作檔案(也有字元串),而且操作檔案還有模式。
模式傳入值:”r“:以隻讀方式打開;”rw“:打開以便讀寫
如果模式為隻讀,則不會建立檔案,會去讀一個已存在的檔案,若檔案不存在,則會出現異常,如果模式為rw,且該對象的構造函數要操作的檔案不存在,會自動建立,如果存在,則不會覆寫,也可通過seek方法修改。
5.RandomAccessFile的最大的作用是實作多線程的下載下傳
特有方法:
1、seek(int n):設定指針,可以将指針設定到前面或後面
2、skipBytes(int n):跳過指定位元組數,不可往前跳
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
{
//"r"代表模式,隻讀
RandomAccessFile raf = new RandomAccessFile("ran.txt","r");
//seek和skipBytes的差別是:skipBytes不能往回跳,seek可以前後的跳,可以随意改變指針。
//調整對象中指針。
//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
這兩個讀寫對象,可用于操作基本資料類型的流對象,包含讀寫各種基本資料類型的方法
import java.io.*;
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());
}
}