。File
。字节流
。InputStream
。OutputStream
。字符流
。Reder
。Writer
。RandomAccessFile
。Properties类的使用
。序列化
1,java.io 包API解释: 通过数据流,序列化和文件系统提供系统输入和输出。(主要针对文件的读写)
-
编码问题,一个字符串放入文本文件--------->其实是一种序列化,也可以称为字符串的序列胡
从文本读取,-------->可以认为是一种反序列化
文本文件中内容都是以字节的盎司呈现的。
字符串放入文本文件 ,首先将字符串----》转化为字节,转化成字节的时候可以选择很多种编码。
以什么样的编码方式转化为字节的,将来需要转化为字符串也需要改编码的方式转化。
(如:使用gbk转化的 ,后面转化也需要gbk)
2,常用编码
gbk,utf-8,utf-16be
//java语言内部一个字符占两个字节,不管是中文还是英文
package corelesson4;
import java.io.UnsupportedEncodingException;
public class EncodeDemo1 {
public static void main(String[] args) {
String s="ABC沃";
byte[] b = s.getBytes();// 默认会用项目的编码
for (byte b1 : b) {
System.out.print(Integer.toHexString(b1&0xFF)+" ");
}
System.out.println();
try {
s.getBytes("GBK");
for (byte b1 : b) {
System.out.print(Integer.toHexString(b1&0xFF)+" ");
}
// gbk 编码1个英文占用一个字节,一个中文占用两个字节
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
System.out.println("n===========================");
try {
s.getBytes("UTF-8");
for (byte b1 : b) {
System.out.print(Integer.toHexString(b1&0xFF)+" ");
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
// 可以看出 一个英文占用一个字节 ,一个中文占 三个字节。
41 42 43 e6 b2 83
41 42 43 e6 b2 83
2, Java.io.file 类可以表示一个文件也可以表示一个目录。
file 类的常用方法
package corelesson4;
import java.io.File;
import java.io.IOException;
public class FileDemo1 {
public static void main(String[] args) throws IOException {
//代表一个目录 创建方式1
File file = new File("F:\1_java大神之路\全新java分布式软件工程师\13.JavaSECore-IO专题\Filedemo");
//判断一个目录是否存在
//true 表示存在,false 表示不存在
System.out.println(file.exists());
// 创建方式2
File file1 = new File("F:\1_java大神之路\全新java分布式软件工程师\13.JavaSECore-IO专题\Filedemo\aaa");
if (!file1.exists()){
file1.mkdirs();//这个目录不存在就创建
}else
{
file1.delete();//目录存在就删除
}
//创建方式3
File file2 = new File(file, "bbb");
if (!file2.exists()){
file2.mkdirs();//这个目录不存在就创建 mkdirs 创建多级目录
}else
{
file2.delete();//目录存在就删除
}
System.out.println("=================================");
// 判断是否是目录
System.out.println(file2.isDirectory());
//判断是否是文件,如果目录不存在 也返回false
System.out.println(file2.isFile());
System.out.println("==========================================");
// 创建一个文件
File file3 = new File(file, "aaa.txt");
if (!file3.exists())
{
file3.createNewFile();
}
System.out.println(file3.exists());
System.out.println(file3.isFile());
// 得到目录的绝对路径 getAbsolutePath
System.out.println(file.getAbsolutePath());
// 返回的是最后一个文件名
System.out.println(file.getName());
System.out.println(file2.getName());
// 得到他的父目录
System.out.println(file1.getParentFile());
System.out.println(file1.getParentFile().getAbsolutePath());
System.out.println(file2.getParentFile().getAbsolutePath());
}
}
File 文件的过滤器
package corelesson4;
import java.io.File;
import java.io.FilenameFilter;
public class FileDemo2 {
public static void main(String[] args) {
File file = new File("E:\Myeclipse\MyEclipse2014汉化\features");
// listFile(file);
// listFile1(file);
listFile2(file);
}
public static void listFile(File file){
String[] list = file.list();
for (String s : list) {
System.out.println(s);
}
System.out.println("====================================================");
//直接累出目录下的,产生的是File对象
File[] files = file.listFiles();
for (File file1 : files) {
//打印目录的所有名字
System.out.println(file1.getAbsolutePath());
}
}
public static void listFile1(File file){
//拿到file对象
File[] files = file.listFiles();
for (File file1 : files) {
if (file1.isFile()){ //如果是文件就列出来
System.out.println(file1.getAbsolutePath());
}else
{
listFile1(file1);// 如果是目录就递归调用
}
}
}
public static void listFile2(File file){
// String[] list = file.list(new MyFileNameFileter());
String[] list = file.list(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
name.startsWith(".babel"); //过滤以这个开头的
return name.endsWith("724060447");// 过滤以这个结尾的
}
});
for (String s : list) {
System.out.println(file.getAbsolutePath()+"/"+ s);
}
}
//写个内部类实现这个过滤器接口
static class MyFileNameFileter implements FilenameFilter{
// file 列出的每个文件都要调用accept 方法, 返回true 留下,false 被过滤掉
@Override
public boolean accept(File dir, String name) {
//File dir 代表父目录 ,String name 代表直接的文件名或者目录名
// System.out.println(dir.getAbsolutePath() +" "+name);
return name.endsWith("subversive_zh_4.2.0.v20130724060447");
}
}
}
过滤器方式一 :FilenameFilter()
public static void listFile2(File file){ // String[] list = file.list(new MyFileNameFileter()); String[] list = file.list(new FilenameFilter() { @Override public boolean accept(File dir, String name) {
name.startsWith(".babel"); //过滤以这个开头的
return name.endsWith("724060447");// 过滤以这个结尾的
}
});
for (String s : list) {
System.out.println(file.getAbsolutePath()+"/"+ s);
}
}
过滤器方式二 :FileFilter()
package corelesson4;
import java.io.File;
import java.io.FileFilter;
import java.io.FilenameFilter;
public class FileDemo2 {
public static void main(String[] args) {
File file = new File("E:\Myeclipse\MyEclipse2014汉化\features");
// listFile(file);
// listFile1(file);
//listFile2(file);
// listFile3(file);
//listFile4(file);
listFile5(file);
}
public static void listFile(File file){
String[] list = file.list();
for (String s : list) {
System.out.println(s);
}
System.out.println("====================================================");
//直接累出目录下的,产生的是File对象
File[] files = file.listFiles();
for (File file1 : files) {
//打印目录的所有名字
System.out.println(file1.getAbsolutePath());
}
}
public static void listFile1(File file){
//拿到file对象
File[] files = file.listFiles();
for (File file1 : files) {
if (file1.isFile()){ //如果是文件就列出来
System.out.println(file1.getAbsolutePath());
}else
{
listFile1(file1);// 如果是目录就递归调用
}
}
}
public static void listFile2(File file){
// String[] list = file.list(new MyFileNameFileter());
String[] list = file.list(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
name.startsWith(".babel"); //过滤以这个开头的
return name.endsWith("724060447");// 过滤以这个结尾的
}
});
for (String s : list) {
System.out.println(file.getAbsolutePath()+"/"+ s);
}
}
//写个内部类实现这个过滤器接口
static class MyFileNameFileter implements FilenameFilter{
// file 列出的每个文件都要调用accept 方法, 返回true 留下,false 被过滤掉
@Override
public boolean accept(File dir, String name) {
//File dir 代表父目录 ,String name 代表直接的文件名或者目录名
// System.out.println(dir.getAbsolutePath() +" "+name);
return name.endsWith("subversive_zh_4.2.0.v20130724060447");
}
}
public static void listFile3(File file){
// 用匿名类方式实现 过滤器
File[] files = file.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
//File pathname 就是ile下的每个文件or目录的全路径
System.out.println(pathname);
// 只留下java 其他被过滤
return pathname.getAbsolutePath().endsWith(".java");
}
});
System.out.println("===============================");
for (File file1 : files) {
System.out.println(file1.getAbsolutePath());
}
}
public static void listFile4(File file){
File[] files = file.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
if (pathname.isFile()){
return pathname.getAbsolutePath().endsWith(".html");
}else if ( pathname.isDirectory())
listFile4(pathname);
return true;
}
});
for (File file1 : files) {
if (file1.isFile()){
System.out.println(file1.getAbsolutePath());
}
}
}
public static void listFile5(File file){
File[] files = file.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
// System.out.println(dir.getAbsolutePath()+"...."+name);
// 需要重新构造file
File file1=new File(dir,name);
if (file1.isFile()){
return name.endsWith(".html");
}else if(file1.isDirectory()){
listFile5(file1);
}
return true;
}
});
for (File file1 : files) {
if (file1.isFile()){
System.out.println(file1.getAbsolutePath());
}
}
}
}
File类的常用方法
list(), listFiles, list(FilenameFilter) , listFile(FileFilter or FilenameFilter)
注意递归问题!
文件的递归删除
目录必须为空,该目录才能删除。
所以要删除一个目录先删除里面的东西
package corelesson4;
import java.io.File;
public class FileDemo3 {
public static void main(String[] args) {
File file = new File("E:\Myeclipse\MyEclipse2014汉化\features");
deleteFile(file);
}
public static void deleteFile(File file){
File[] files = file.listFiles();
for (File file1 : files) {
if (file1.isFile()){
System.out.println(file1.getAbsolutePath());
file1.delete();// 如果是文件直接删除
}
else if(file1.isDirectory()){
deleteFile(file1);// 递归删除
}
}
//到这里为止删除的都是子目录,下面删除父目录
System.out.println(file.getAbsolutePath());
file.delete();
}
}
3,字节流 (文件读写操作)
字节流-------------- > 读写以字节单位(各种类型 mp3,MP4
,图片 文本等)
字符流-----------------> 读写以字符单位(只适合 文本文件的读写)
输入流----》读操作的
输出流----》写操作的
3,1 以字节为单位的输入输出流 FileInputStream输入流: InputStream(读)(它是一个抽象类)
read() 重载三个重要方法
------->FileInputStream(子类) :把文件作为字节流进行读操作
------->BufferedInputStream(先读到内存,再从内存中读取,多了一个缓冲区的功能)
------->PipedInputStream : 管道流
------->DataInputStream : 可以直接输出很多数据类型的方法,,分析读写的原理
------->System.in : 从键盘读
如果是FileOutStream Out
out.write(10000); write 方法只能写一个字节
但是10000 是32 个字节,所以它只写后8位;
所以DataOutputStream dos 对象的writeInt 方法一定是利用out 对象的write 方法写4 次写8位
writeInt 方法内部一定是:
out.write(10000>>24)
out.write(10000>>16)
out.write(10000>>8)
out.write(10000)
输出流 : OutputStream(写) 同理读也是读4次
write () 重载三个写的方法
------->FileOutputStream(子类) :把文件作为字节流进行写操作
------->BufferedOutputStream
------->PipedOutputStream
------->DataOutputStream
------->System.out :-------> PrintStream 输出流
package corelesson4;
import javax.print.DocFlavor;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class StreamDemo1 {
public static void main(String[] args) throws IOException {
// test1();
//test2();
test3();
}
// 所有的IO操作都会产生 IOEx产品提on
public static void test1(){
FileInputStream in=null;
try {
in = new FileInputStream("H:\WorkspacesMyEclipse2014\ssh_test1\src\org\sshtest\entities\UserInfo.java");
FileOutputStream out = new FileOutputStream("D:\1.txt"); // 读文件 然后写到这个文件中
//1.txt 不存在就创建,如果存在先删除 在创建
int c;
while ((c=in.read())!=-1){
//怎么读的就怎么写
out.write(c);
System.out.print((char)c);
}
out.close();
} catch (IOException e) {
e.printStackTrace();
}
finally {
if (in!=null){
try {
// 最后关闭
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
// 这里先不关心异常
public static void test2() throws IOException {
FileInputStream in = new FileInputStream("H:\WorkspacesMyEclipse2014\ssh_test1\src\org\sshtest\entities\UserInfo.java");
FileOutputStream out = new FileOutputStream("D:\11.txt"); // 读文件 然后写到这个文件中
byte[] b = new byte[1024 * 5];
//读到这个数组,从第0个位置开始放 放到哪里,
//int bytes = in.read(b, 0, b.length);//返回读到字节的个数
// 往b字节数组中放 最多放b.length个
// 相当于开辟了一个内存空间,把读到的放进去
// 相当于批量读取,效率高
// String s = new String (b,0,bytes);
//System.out.println(s);
// 方式二
int bytes;
// 这样写的话就是bytes 中放满了 输出 然后清空 再放 ,在放满再输出,在放
while ((bytes=in.read(b,0,b.length))!=-1){
// 然后构造字符串, 从内存中读,如果不是文本文件 可以不用打印到控制台
String s=new String(b,0,bytes);
// 写的话就直接卸载文件中 不需要构造再写
out.write(b,0,bytes);
System.out.println(s);
}
}
//方式三
public static void test3() throws IOException {
FileInputStream in = new FileInputStream("H:\WorkspacesMyEclipse2014\ssh_test1\src\org\sshtest\entities\UserInfo.java");
FileOutputStream out = new FileOutputStream("D:\21.txt"); // 读文件 然后写到这个文件中
int length = in.available();// 返回可读的字节数
// 构造字节数组
byte[] b = new byte[length];
int read = in.read(b);
String s= new String (b,0,b.length);
System.out.println(s);
//这里直接写在文件中
out.write(b);
in.close();
}
//不管是读写 建议使用 第二种方式。
public static void test4(){
FileInputStream in = null;
try {
in = new FileInputStream("D:\aa.txt");
FileOutputStream out = new FileOutputStream("D:\bb.txt"); // 读文件 然后写到这个文件中
byte[] b = new byte[1024 * 5];
int bytes;
while ((bytes=in.read(b,0,b.length))!=-1){
String s=new String(b,0,bytes,"utf-8");//这里解决字符编码不一样的问题
out.write(b,0,bytes);
System.out.println(s);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
------->BufferedInputStream
------->BufferedInputStream(先读到内存,再从内存中读取,多了一个缓冲区的功能)
内部源码有一个:protected volatile byte buf[]; 数组
package corelesson4;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class StreamDemo2 {
public static void main(String[] args) {
try {
BufferedInputStream in = new BufferedInputStream(new FileInputStream("D:\1.txt"));
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream("D:\a1.txt"));
byte[] bytes = new byte[10000];
int c;
//内部操作先把文件放置到 内存中(缓冲区字节数组),所以也不太适合太大的文件
//我们读的时候充内存中读取。
while ((c=in.read(bytes,0,bytes.length))!=-1){
//把缓冲区中读到的内容写入磁盘,刷新缓冲区才会写入磁盘
out.write(bytes,0,c);
out.flush();//刷新缓冲区 ,缓冲区大小满了 会自动刷新。
}
in.close();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
------->PipedInputStream : 管道流
PipedInputStream (PipedOutputStream())
PipedInputStream (PipedInputStream() )
out写出的数据正好被in 读到
package corelesson4;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
public class StreamDemo3 {
public static void main(String[] args) {
// 管道流
try {
PipedInputStream in = new PipedInputStream();
PipedOutputStream out = new PipedOutputStream(in);
Send send = new Send(out);
Receive rec = new Receive(in);
send.send();
rec.rec();
in.close();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
class Send{
OutputStream out;
public Send(OutputStream out) {
super();
this.out = out;
}
public void send(){
byte value=(byte)(Math.random()*100);
try {
System.out.println("send the value is: "+value);
out.write(value);//写出去
} catch (IOException e) {
e.printStackTrace();
}
}
}
class Receive{
InputStream in;
public Receive(InputStream in) {
super();
this.in = in;
}
public void rec(){
try {
byte value = (byte)in.read();
System.out.println("rec the value is: "+value);
} catch (IOException e) {
e.printStackTrace();
}
}
}
将来 两个需要交互的时候 一边写,正好被一边读到。
------->DataInputStreampackage corelesson4;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class StreamDemo4 {
public static void main(String[] args) {
wirte();
read();
}
public static void wirte(){
try {
//把1.txt文件作为字节输出流,并且直接写java的数据类型
// DataOutputStream dos = new DataOutputStream(new FileOutputStream("D:\1.txt"));
// 都是一个字节流装饰出来的,称装饰模式
// 把 1.txt 文件作为字节输出流,并且先写入缓冲区,可以直接写数据类型
// DataOutputStream dos1 = new DataOutputStream(new BufferedOutputStream(new FileOutputStream("D:\1.txt")));
// 发现 特殊功能流类都是基本的流,嵌套构造出来,其实是一种装饰模式。
// 优点 直接写数据类型
DataOutputStream dos = new DataOutputStream(new FileOutputStream("D:\1.txt"));
// 写一个int 类型
dos.writeInt(10000);
//写一个Boolean 类型
dos.writeBoolean(true);
//写一个Double类型
dos.writeDouble(10.03);
//写一个字符串类型
dos.writeUTF("HELLO");
dos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void read(){
try {
DataInputStream dis = new DataInputStream(new FileInputStream("D:\1.txt"));
// 对应的读出来
System.out.println(dis.readInt());
System.out.println(dis.readBoolean());
System.out.println(dis.readDouble());
System.out.println(dis.readUTF());
} catch (IOException e) {
e.printStackTrace();
}
}
}
------->System.in : 从键盘读
package corelesson4;
import java.io.IOException;
public class StreamDemo5 {
public static void main(String[] args) {
byte[] bytes = new byte[10000];
System.out.println("请输入: ");
try {
while (true){
int read = System.in.read(bytes, 0, bytes.length);
String str = new String(bytes, 0, read);
if ("end".equals(str)){
break;
}
System.out.println(str);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
-------> PrintStream 输出流
文件找那个追加写内容
FileOutputStream("D:2.txt"),true); //后面这里为true 如果文件存在 就会追加写在里面
package corelesson4;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
public class StreamDemo6 {
public static void main(String[] args) {
try {
PrintStream ps = new PrintStream(new FileOutputStream("D:\2.txt"));
//FileOutputStream("D:\2.txt"),true); //后面这里为true 如果文件存在 就会追加写在里面
// System.out 目标是标准输出设备 System.in 标准输入设备 就是我们的控制台
ps.println("hello");
ps.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
4 字符流,(文本操作)
字符流(文本操作)------>都是有字节流构造出来的(用到的是适配器模式)
输入流 ------->Reader
---------------->InputStreamReader
----------------> FileReader
----------------> BufferedReafer 一次可以读一行字符字符串
输出流-------->Writer
---------------->OutputStreamReader
----------------> FileWriter
----------------> BufferedWriter一次可以写一行字符字符串
---------------------------------PrintWriter
主要的方式也是读和写
不管是字符流还是字节流我们需要关注的是输入和输出的方法。
1, ------>InputStreamReaderbufferedReader
package corelesson4;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class RWDemo1 {
public static void main(String[] args) {
RWStream1();
RWStream2();
}
public static void RWStream1(){
try {
InputStreamReader in = new InputStreamReader(new FileInputStream("D:\11.txt"));
OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream("D:\11w.txt"));
// 一个字符一个字符的读
int c;
while ((c=in.read())!=-1){
// c 读到的是一个字符 这样读取没有乱码 ,默认是一样的
System.out.print((char)c);
out.write(c);
out.flush();// 字符流都是有缓冲区的 不要忘记了刷新
}
in.close();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void RWStream2(){
try {
InputStreamReader in = new InputStreamReader(new FileInputStream("D:\11.txt"));
OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream("D:\11w1.txt"));
char[] c = new char[1000];
int len;
while ((len=in.read(c,0,c.length))!=-1){
// 然后拿字符数组来构造成字符串
String s= new String (c,0,c.length);
System.out.print(s);
out.write(c,0,len);
out.flush();
}
in.close();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
2, ---------------> FileReader
package corelesson4;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class RWDemo2 {
public static void main(String[] args) {
RWStream1();
}
public static void RWStream1(){
try {
//这样构造就很方便,缺点 不能指定编码
FileReader fr = new FileReader("D:\11.txt");
FileWriter fw = new FileWriter("D:\11w2");
char[] chars = new char[1000];
int len;
while ((len=fr.read(chars,0,chars.length))!=-1) {
// 构造成字符串打印熬控制台
String s = new String(chars, 0, chars.length);
System.out.print(s);
fw.write(chars,0,len);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
3,-----> BufferedReafer 一次可以读一行字符字符串
Filewriter
注意: 读一行readLine ,换行 newline,刷新缓冲 bw.flush();
package corelesson4;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
public class RWDemo3 {
public static void main(String[] args) {
try {
// BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("D:\11.txt")));
BufferedReader br = new BufferedReader(new FileReader("D:\11.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("D:\11w3.txt"));
// 有一个重要的方法就是readLine()方法一次可以读一行
String s=null;
while ((s=br.readLine())!=null){
System.out.print(s);// 一次读一行不读取换行
// 读一行写一行
bw.write(s);
// 读一行还下一行开始写
bw.newline();
// 读完一行刷新依稀缓存
bw.flush();
}
br.close();
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
PrintWriter也比较常用
package corelesson4;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
public class RWDemo4 {
public static void main(String[] args) {
try {
// BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("D:\11.txt")));
BufferedReader br = new BufferedReader(new FileReader("D:\11.txt"));
PrintWriter pw = new PrintWriter(new FileOutputStream("D:\44.txt"),true);//加true 自动刷新 不用非手动flush了
// 有一个重要的方法就是readLine()方法一次可以读一行
String s=null;
while ((s=br.readLine())!=null){
System.out.print(s);// 一次读一行不读取换行
// 读一行写一行
pw.println(s);
}
br.close();
pw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
字节流决定 输入输出的目标, 字符流呢就是适配它自己的类型。
从键盘一次读一行 读到end 及结束
最内层决定了它的输入输出目标
package corelesson4;
import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
public class RWDemo5 {
public static void main(String[] args) {
try {
// 从键盘一次读一行 读到end 及结束
// 输入输出 是由最内层来决定的。 这个过程就是一个适配器的过程。
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
while (true){
String str=br.readLine();
System.out.println(str);
if("end".equals(str)){
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
5,RandomaccessFile 随机访问的流类
一种比较早的方式
package corelesson4;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
public class RWDemo6 {
public static void main(String[] args) {
try {
RandomAccessFile raf = new RandomAccessFile("D:\44.txt","rw");
System.out.println(raf.getFilePointer());
raf.writeInt(1000);
System.out.println(raf.getFilePointer());
// 相当于写了
raf.write(1000>>24);
raf.write(1000>>16);
raf.write(1000>>8);
raf.write(1000);
System.out.println(raf.getFilePointer());
raf.writeUTF("hello"); //写入hello
System.out.println(raf.getFilePointer());// 查看hello 所在的位置
byte[] b=new byte[10000];
int bytes = raf.read(b, 0, b.length);// 返回的是字节的个数
} catch (IOException e) {
e.printStackTrace();
}
}
}
6.java.util.Properties(并不是IO种的类)
实际使用需要和IO结合在一起
资源文件已properties 作为文件的扩展名
文件的内容 是以key =value 的方式进行存放的
properties 的使用
package corelesson4;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
public class PropertiesDemo1 {
public static void main(String[] args) {
Properties prop = new Properties();
//加载这个文件, 把这个文件转化为输入流。
try {
prop.load(new FileInputStream("这里 放properties 文件"));
for (Object o : prop.keySet()) {
String key=(String)o;
System.out.println(key+"="+prop.get(key));
}
// 资源文件中的内容是可以看见的 key 就是已知的
//可以直接这样用
System.out.println( prop.getProperty("key"));// 直接拿到里面的值
} catch (IOException e) {
e.printStackTrace();
}
}
}
properties 基本使用 升级2
package corelesson4;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
public class PropertiesDemo2 {
public static void main(String[] args) {
Properties prop = new Properties();
//加载这个文件, 把这个文件转化为输入流。
try {
// 缺点 : 这样写 路径就写死了 项目一旦移动就找不到路径了
// prop.load(new FileInputStream("这里 放properties 文件"));
// 使用class 得到当前类的字节流
//getResourceAsStream 得到的是classPath 路径
// 用哪个类的 类类型呢? 都是可以的在同一包下什么类的类类型 的classpath 都是一样的
prop.load(PropertiesDemo2.class.getResourceAsStream("")); // 这种方式 用的多一些
// 还有一种 是加载包下的properties 文件 直接输入包下的文件
//class.getClassLoader() 获得的是类加载器
prop.load(PropertiesDemo2.class.getClassLoader().getResourceAsStream("corelesson4/aa.properties"));
//可以直接这样用
System.out.println( prop.getProperty("key"));// 直接拿到里面的值
} catch (IOException e) {
e.printStackTrace();
}
}
}
资源文件 将来 在设计中 用来解耦的。 一般和反射结合使用。
7, IO 序列化问题
序列化---->对象系列化
(对象进行存储or 在网络中进行传递,该对象必须进行序列化)
Java.ioObjectOutputStream
Java.ioObjecInputStream
java.io.Serializable 如果一个对象想要 序列化 必须实现这个序列化的接口
该接口只是一个标准规范 ,没有任何方法。
7.2 transient 关键字
如果该对象的属性用transient 关键字来修饰,那么 该属性不会做jvm 默认的序列化工作
package corelesson4;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class SeriDemo1 {
public static void main(String[] args) {
Student stu = new Student(1000,"zhangshan",20);
try {
//写入文件
ObjectOutputStream out = new ObjectOutputStream(
new FileOutputStream("D:\55.txt"));
out.writeObject(stu);//直接写入一个对象
out.flush();
out.close();
//读操作
ObjectInputStream in = new ObjectInputStream(new FileInputStream("D:\44.txt"));
Student stu1=(Student)in.readObject();
System.out.println(stu1);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
7.3 集合中的 类是如何序列化的 比如ArrayList
ArrayList 中有数组,且数组不一定放满元素, 所以没有必要吧整个数组做序列化。只需要序列化有效元素。
用了以下两个方法签名做了 序列化和反序列化的工作。
Private void readObject (java.io.ObjectInputStream stream)
throws IOExcrption,ClassNoFoundException;
Private void writeObject (java.io.ObjectOutputStream stream)
throws IOExcrption;
这样的新能比较高
7.4 java 实现接口,继承 都有传递性
如果父类 实现了Serializable 接口,那么其子类都可以序列化
需要注意的是:
如果父类是可序列化的,那么在反序列化子类的时候不会调用父类
的构造函数,如果父类是不可序列化的,而子类是可以序列化的,那么在子类反序列化时,会调用父类的构造函数。
package corelesson4;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;
public class SeriDemo2 {
public static void main(String[] args) {
// 1 序列化
try {
// ObjectOutputStream out = new ObjectOutputStream(
//
// new FileOutputStream("D:\66.txt"));
// // 2,创建对象
// C c = new C();
// //3 ,接下来 做序列化工作。
// out.writeObject(c);
// out.flush();
// out.close();
//4,以上就是他的序列化
//5 .接下来做反序列化, 保存到那个文件,就到哪个文件去取
ObjectInputStream out = new ObjectInputStream(new FileInputStream("D:\66.txt"));
C c=(C)out.readObject();
System.out.println(c);
} catch (Exception e) {
e.printStackTrace();
}
}
}
class A implements Serializable{
public A() {
System.out.println("a.....");
}
}
class B extends A{
// 这样 B类是可以被序列化的
public B() {
System.out.println("b......");
}
}
class C extends B{
public C() {
System.out.println("c.....");
}
}
7.5 java 中 有一个克隆的功能Object 类中已经提供了
一个类的对象要进行克隆直接实现Cloneable 接口即可
Cloneable 也是一个标准 没有具体的方法;
package corelesson4.prototype;
public class CloneTest {
public static void main(String[] args) {
User user = new User();
User user1=null;
Address address = new Address();
user.setAddress(address);
//现在就可以克隆新的对象
try {
// 这样就克隆 一个新的对象出来了
user1 =(User)user.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
System.out.println(user==user1);
System.out.println(user.getAddress()==user1.getAddress());
}
}
称为: 浅克隆 or 浅拷贝
浅拷贝主要是内部引用指向同一个对象的内存。
比如 A---->b1 ---->C对象
B ------->b2----->C 对象 内部指向的都是C对象同一块内存 称为浅拷贝
深拷贝
1,对当前对象序列化的工作,
深克隆or 深拷贝 , 通过序列化和反序列化的方式
这其实是一个设计模式---》原型模式
7.6 结合集合使用IO
案例 有如下文本文件
1,zhangshan,28 2,lishi,23 3,wangwu,19 4,zhaoliu,24 5,zhangshan,28 6,zhangshan,28 7,lishi,23 8,zhangshan,28 9,tianqi,30
要求统计姓名出现的次数 ,并且按照次数降序输出,如果次数相同,按照名字升序。
思路: 一次读一行,然后进行字符串分割,把名字放入map 集合中
统计次数,然后 用treeSet 排序
package corelesson4;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.HashMap;
public class works {
public static void main(String[] args) {
getStuduens();
}
public static HashMap getStuduens(){
HashMap map = new HashMap<>();
try {
BufferedReader br = new BufferedReader(new FileReader("D:\aa.txt"));
String str= null;
while ((str=br.readLine())!=null){
String[] ss=str.split(",");
for (String s : ss) {
System.out.print(s+" ");
}
System.out.println();
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
IO 专题主要是这些 后续有补充的在补充笔记!



