——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-
Properties:属于map集合,不用指定泛型,内部只能存放字符串类型
方法:
p.put();放入字符串
p.loag(输入流)
p.store(输出流,注释)
p.clear();”清空集合”
p.containsKey(key);”是否包含某个key”
p.containsValue(value);”是否包含某个value”
p.entrySet();”返回Set集合,包含所有键值对信息”
p.keySet();”返回Set集合,包含所有键”
p.get(key);”根据key获取value”
p.getProperty(key);”根据key返回键,返回值是string类型”
p.getProperty(key, defaultValue);”根据key返回键,返回值是string类型,没有值的时候使用默认值”
p.isEmpty();”集合是否为空”
p.size();”集合长度”
public static void propertiesDemo() {
Properties p = new Properties();
p.put("zhangsan", "10");
p.put("zhangsan1", "101");
p.put("zhangsan2", "102");
p.put("zhangsan3", "103");
"//把Properties 内的数据以列表形式输出"
p.list(new PrintStream(System.out));
"/**
* 模拟load()和store()
* load():读取的文件内部必须是键值对的形式,
* a = b
*/"
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
String line = null;
try {
while ((line = br.readLine()) != null) {
if ("over".equals(line))
break;
"//对字符串根据 = 分割"
String[] s = line.split("=");
bw.write(s[0] + " : " + s[1]);
bw.flush();
"//换一行"
bw.newLine();
}
br.close();
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
"/**
* 使用load和stroe来加载文件和输出文件
*/"
try {
"//读取文件"
p.load(new FileInputStream("d://c.txt"));
"//把p对象中的内容写入到文件中"
p.store(new OutputStreamWriter(new FileOutputStream("c://cc.txt"), "utf-8"));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
RandomAccessFile 随机文件读写
(即可以读,也可以写,创建对象时声明权限即可,r:读,w:写)
raf.setLength(newLength);设置一个文件的大小(设置后文件大小立即为设置的大小,凡是内部没有数据)
raf.length();获取文件大小
raf.read();读取文件
raf.write();写文件:可以读写基本数据类型
raf.readLine();读取一行
raf.seek(int);从哪里开始读取或写入
raf.skipBytes(n);跳过多少字节
可以多个RandomAccessFile 对象同时对一个文件进行读写操作(多线程下载)
public static void demo3() {
try {
"通过url获取网络资源对象"
URL url = new URL("http://127.0.0.1:8080/demo.avi");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setReadTimeout(3000);
conn.connect();
InputStream in = conn.getInputStream();
"获取网络文件大小"
long length = conn.getContentLength();
"创建本地文件,并设置大小"
File file = new File("c://demo//t.avi");
if (file.exists()) {
file.delete();
file.createNewFile();
} else {
file.createNewFile();
}
RandomAccessFile raf = new RandomAccessFile(file, "rw");
"设置文件大小,只有RandomAccessFile才有这个方法"
raf.setLength(length);
raf.close();
conn.disconnect();
"开启三个线程,并传入开始和结束位置"
method(0, length / 3);
method(length / 3, length / 3 * 2);
method(length / 3 * 2, length);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void method(final long start, final long end) {
new Thread(new Runnable() {
@Override
public void run() {
File file = new File("c://demo//t.avi");
if (!file.exists()) {
throw new RuntimeException("找不到文件");
}
try {
"三个线程共三个RandomAccessFile对象,
他们同时操作一个文件"
RandomAccessFile raf = new RandomAccessFile(file, "rwd");
"设置URL"
URL url = new URL("http://127.0.0.1:8080/demo.avi");
"获取httpUrlConnextion对象"
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
"连接方法"
conn.setRequestMethod("GET");
"读取超时时间"
conn.setReadTimeout(3000);
"设置提交属性"
conn.setRequestProperty("Range", "bytes=" + start + "-" + end);
conn.connect();
System.out.println("开始下载:" + Thread.currentThread());
System.out.println("开始下载:" + start + " : " + end);
InputStream in = conn.getInputStream();
byte[] by = new byte[1024];
"设置从文件哪个位置开始写入数据"
raf.seek(start);
while ((len = in.read(by)) != -1) {
"写入数据"
raf.write(by, 0, len);
}
System.out.println("关闭:" + Thread.currentThread());
raf.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
PrintStream
只有输出流,没有输入流
可以操作字节流和字符流,一般经常使用字符流
一般使用在打印日志信息中,方便
public static void demo2() {
try {
File f = new File("c://demo//b.txt");
int[] i = new int[1];
i[3] = 4;
} catch (Exception e) {
try {
"获取时间"
Date date = new Date();
"当参数是输出流的时候,可以指定自动刷新,指定自动刷新后只有println(),printf(),formar()方法有用,若参数是file,不能设置自动刷新
print()不会自动刷新"
"FileOutputStream 若文件已经存在采用追加模式,我不是覆盖"
PrintStream ps = new PrintStream(new FileOutputStream("c://demo//d.txt",true),
true);
"打印的是字节流"
ps.write(date.toString().getBytes());
"打印时间,打印的是字符流"
ps.println(date);
"把异常信息打印到ps对象中"
e.printStackTrace(ps);
} catch (FileNotFoundException e1) {
throw new RuntimeException("日志文件创建失败!");
}
}
}
LinenumberReader:
没有LinenumberWriter
使用lnr.getLineNumber()获取行号,默认从0开始
使用lnr.setLineNumber(10);这是行号的起始位置
LinenumberReader自带缓存,有readLine()方法
public static void lineNum() {
LineNumberReader lnr = null;
BufferedWriter bw = null;
try {
lnr = new LineNumberReader(new FileReader("d://demo.txt"));
bw = new BufferedWriter(new FileWriter("c://demo.txt"));
String line = null;
"设置行号从10开始"
lnr.setLineNumber(10);
while ((line = lnr.readLine()) != null) {
bw.write(lnr.getLineNumber() + " : " + line);
"// 最好使用自带的方法换行,这样可以跨平台"
bw.newLine();
bw.flush();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
"关闭资源"
try {
if (lnr != null)
lnr.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if (bw != null)
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
流的切割和合并
序列流:
对流进行合并,只有InputStream,不能使用字符流(Reader,Writer)
输入流是一个有序集合,当读取到第一个流的末尾处,会继续读第二个流的开始,直到结束
public static void sequenceInputStream() {
"/**
* 文件的切割
* 实际上就是在输出时候指定输出的大小
* 例:定义的缓冲区大小是多大,那么分割的就是多大
*/"
FileInputStream fis = null;
FileOutputStream fos = null;
try {
"// 获取文件输入流"
fis = new FileInputStream("d://love.mp3");
int num = 0;
int count = 0;"// 文件名的计数"
"// 缓存大小是1m"
byte[] by = new byte[1024 * 1024];
while ((num = fis.read(by)) != -1) {
count++;
"/**
* 在内部进行创建输出流,当第一个数组存满后
* 创建输出流进行存储,然后立刻关闭
* 当再次循环的时候重新创建输出流,重新放新的数据
*/"
fos = new FileOutputStream("c://" + count + "1.part");
fos.write(by, 0, num);
fos.flush();
fos.close();
}
fis.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
"// 声明集合,内部存放输入流,若是输入流数量小于两个不用创建集合,直接使用构造方法传递就可以"
ArrayList<FileInputStream> list = new ArrayList<FileInputStream>();
try {
"// 添加输入流"
list.add(new FileInputStream("c://11.part"));
list.add(new FileInputStream("c://21.part"));
list.add(new FileInputStream("c://31.part"));
"// 获取每一个输入流,由于被Enumeration使用,他是匿名内部类,要使用final修饰"
final Iterator<FileInputStream> it = list.iterator();
"/**
* SequenceInputStream中只能接收Enumeration集合,不能使用Iterator
* 使用Enumeration集合是vector,但是已经被ArrayList代替
* 所以重写Enumeration的方法
*/"
Enumeration<FileInputStream> en = new Enumeration<FileInputStream>() {
@Override
public boolean hasMoreElements() {
return it.hasNext();"// 是否有下一个"
}
@Override
public FileInputStream nextElement() {
return it.next();"// 获取下一个对象"
}
};
FileOutputStream fos2 = new FileOutputStream("c://lov1.mp3");
SequenceInputStream sis = new SequenceInputStream(en);
"/**
* 最后进行输出
*/"
int num = 0;
byte[] by = new byte[1024];
while ((num = sis.read(by)) != -1) {
fos2.write(by, 0, num);
}
sis.close();
fos2.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
对象的持久化存储:
ObjectOutputStream,ObjectInputStream
将一个对象进行持久化存储,存储的对象必须实现Serializable接口,打上标记
实现Serializable的类默认会生成一个UId:
public static final long serialVersionUID = 10;
它会根据这个值进行判断是不是原来的对象,默认是根据类中的成员进行计算,也可以手工指定
当对象进行持久化存储后,这时候修改了类中的一些值,例如添加了一个成员等
这时候再读取对象文件的时候会报错:java.io.InvalidClassException
静态不能被序列化
非静态不想被序列化使用关键字:transient
public static void serializable() {
ObjectOutputStream oos = null;
ObjectInputStream ois = null;
try {
oos = new ObjectOutputStream(new FileOutputStream("d://demo2.txt"));
ois = new ObjectInputStream(new FileInputStream("d://demo2.txt"));
"// 写入一个对象"
oos.writeObject(new Persion("lisi", 31));
oos.writeObject(new Persion("lisi1", 31));
oos.writeObject(new Persion("lisi2", 32));
oos.close();
"// 读取一个对象,并进行强转"
Persion p = (Persion) ois.readObject();
Persion p1 = (Persion) ois.readObject();
Persion p2 = (Persion) ois.readObject();
System.out.println(p.getName() + " " + p.getAge());
System.out.println(p1.getName() + " " + p1.getAge());
System.out.println(p2.getName() + " " + p2.getAge());
} catch (Exception e) {
e.printStackTrace();
}
}
import java.io.Serializable;
public class Persion implements Serializable {
private static final long serialVersionUID = 1;
private String name;
private int age;
public Persion(String name, int age) {
super();
this.name = name;
this.age = age;
}
}
管道流:
PipedInputStream PipedOutputStream
一般应用在多线程中,一个线程负责输入,而另一个线程负责输出
当一段连接线程提前结束的时候:会报错
public static void guanDaoDemo() {
"创建一个输入管道流,这里使用了匿名内部类,局部变量要声明为final"
final PipedInputStream pis = new PipedInputStream();
"创建一个输出管道流"
final PipedOutputStream pos = new PipedOutputStream();
try {
"两个流进行连接"
pis.connect(pos);
} catch (IOException e) {
e.printStackTrace();
}
"输出管道流"
new Thread(new Runnable() {
@Override
public void run() {
int num = 0;
System.out.println("正在读取数据...");
try {
while ((num = pis.read()) != -1) {
System.out.println(num);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
"输入管道流"
new Thread(new Runnable() {
@Override
public void run() {
try {
System.out.println("正在写入数据...");
Thread.sleep(3000);
pos.write("--------".getBytes());
System.out.println("写入完成...");
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
存储基本数据类型
DataInputStream,DateOutputStream
注意:
写入顺序和读取顺序必须相同(第一个写入的是int类型,则读取的时候第一个必须是int类型,如果是long类型,则会多读取数据,造成数据错误)
gbk编码表:一个中文占2个字节
utf -8:一个中文占3个字节
utf-8改:一个中文占4个字节
当存储的数据大于256时,最好是用writeInt(),他是直接存储32位,而write()只是存储8位,
会造成损失精度
writeUTF(“你好”);当写入时使用了这个方法,取出时一定要使用readUTF();取出
public static void dataDemo() {
try {
DataInputStream dis = new DataInputStream(new FileInputStream("d://demo3.txt"));
DataOutputStream dos = new DataOutputStream(new FileOutputStream("d://demo3.txt"));
dos.writeInt(78);"// 写入32位"
dos.write(455);"// 写入8位,会造成精度损失"
dos.writeBoolean(true);
dos.writeUTF("你好");
dos.close();
int a = dis.readInt();
int b = dis.read();
boolean c = dis.readBoolean();
String s = dis.readUTF();
System.out.println(a + " " + b + " " + c + " " + s);
} catch (FileNotFoundException e) {
} catch (IOException e) {
e.printStackTrace();
}
}
字节数组操作数据,字符数组,字符串:
ByteArrayInputStream ByteArrayOutputStream
实例:把文件的中内容读取到内存中
不需要关闭,因为没有调用底层资源,关闭也没用
bos.size()获取输出长度
这个是直接输出到内存中
public static void arrayDemo() {
BufferedReader br;
try {
"读取一个文件"
br = new BufferedReader(new FileReader("d://demo.txt"));
"定义输出文件"
FileOutputStream fos = new FileOutputStream("d://demo4.txt");
StringBuilder sb = new StringBuilder();
String line = null;
"把文件读取的内容添加到StringBuilder中"
while ((line = br.readLine()) != null) {
sb.append(line);
}
System.out.println(sb.toString());
"// 读取字节数据"
ByteArrayInputStream bis = new ByteArrayInputStream(sb.toString().getBytes());
"ByteArrayOutputStream 是把数据写入到内存中"
ByteArrayOutputStream bos = new ByteArrayOutputStream();"// 长度自动增加"
int by = 0;
while ((by = bis.read()) != -1) {
"// 输出,这里是输出到内存中"
bos.write(by);
}
"// 输出到outputstream,必须要先执行完上面while循环,把数据写入内存后,才能执行writeTo()"
bos.writeTo(fos);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-