IO流

io

(类和接口存在于java.io包中)

一、File类操作:

1File类介绍:

File类是IO包中唯一表示磁盘文件和磁盘目录的对象的路径.

该类包含了创建,删除文件,重命名文件,判断文件读写权限以及文件是否存在,查询等功能方法.

只能设置和获取文件本身的信息,不能设置和获取文件的内容.

 

2路径分隔符,属性分隔符:

1Unix: 使用”/,来分割目录路径.     使用:来分割属性.

2Windows: 使用”\,来分割目录路径.但是在Java中一个”\”表示转义,Windows平台的Java代码中表示一个路径,就得使用两个\\. 但是Windows支持/.                 使用;来分割属性.

(但是我经常用的是Fileseparatoreg:String path2 = "d:"+File.separator+"temptest"+File.separator+"2.txt";)

 

3、File类中的方法

文件操作:

boolean isFile() :是否是文件

boolean createNewFile() :创建新的文件

static File createTempFile(String prefix, String suffix) :创建临时文件

boolean delete() :删除文件

void deleteOnExit() :JVM停止时删除文件

boolean exists():判断文件是否存在

boolean renameTo(File dest) :重新修改名称

目录操作

boolean isDirectory() :判断是否是目录

boolean mkdir()  :创建当前目录

boolean mkdirs() :创建当前目录和上级目录

String[] list() :列出所有的文件名

File[] listFiles() :列出所有文件对象

static File[] listRoots() :列出系统盘符

 

4、需求:列出指定目录中所有的文件,包括子文件夹中的所有文件(使用递归算法(recursion))

Demo:

public class FileDemo {
 
public static void main(String[] args) {
String path = "D:\\Java笔记\\基础笔记";
MyUtils.readAllFile(path);
}
}
 
class MyUtils{
public static void readAllFile(String path){
File f  = new File(path);
File[] fs = f.listFiles();
for(int i=0;i<fs.length;i++){
if(fs[i].isDirectory()){
System.out.println(fs[i]+"------------------------------");
readAllFile(fs[i].toString());
}else{
System.out.println(fs[i]);
}
}
}
}		

 

二、输入和输出:

1、io流分类

1):根据流向划分: 输入流和输出流.

2):根据数据的单位划分: 字节流和字符流.

3):根据功能的划分:节点流和包装流.

2、四大基流:(字节输出流,字节输入流,字符输出流,字符输入流)

四大基流都是抽象类: 其他流都是继承于这四大基流的,我们不能创建四大基流的对象,只能创建其子类对象.

 无论是什么流,close方法,用来关闭资源. 如果操作文件,就得开通一个流对象关联我们得磁盘文件,如果不关闭资源,那么磁盘的文件一直被程序所引用着,不能删除,也不能更改.

 

三、操作io流的模板:

1创建源或者目标对象(挖井).

     拿文件流举例:

     输入操作:    把文件中的数据流向到程序中,此时文件是源,程序是目标.

     输出操作:    把程序中的数据流向到文件中,此时文件是目标,程序是源.

2创建IO流对象(水管)

     输入操作:     创建输入流对象.

     输出操作:     创建输出流对象.

3具体的IO操作:

     输入操作:    输入流对象的read方法.

     输出操作:    输出流对象的write方法.

4关闭资源(勿忘): 一旦资源关闭之后,就不能使用流对象了,否则报错.

     输入操作:    输入流对象.close();

     输出操作:    输出流对象.close().

操作IO流的六字箴言: 读进来,写出去.

 

四、字节流、字符流:

1字符流和字节流的区别:

1)字节流操作的基本单元为字节;字符流操作的基本单元为Unicode码元。

2字节流默认不使用缓冲区;字符流使用缓冲区

3)字节流通常用于处理二进制数据,实际上他可以处理任意类型的数据,但不支持直接写入或读取Unicode码元;字符流通常处理文本数据,但支持写入或读取Unicode码元。

2字节流输出和输入:

Demo:

public class InputStreamDemo {
public static void main(String[] args) throws IOException {
//字节输入流
String path = "d:"+File.separator+"test"+File.separator+"002.txt";
//当需要使用file中的函数时就创建file
File f = new File(path);
InputStream in = new FileInputStream(path);
/*byte[] b = new byte[(int) len];
long len = f.length();
in.read(b);
in.close();
System.out.println(new String(b));*/
//不能确定那个文件内容有多少
byte[] b = new byte[1024];
int len = 0;
while((len=in.read(b))!=-1){
System.out.println(new String(b,0,len));
}
}
}


public class OutputStreamDemo1 {
//字节输出流:
public static void main(String[] args) throws IOException {
String info = "我是好人!";//D:\test\001.txt
String data = "\r\n大家都知道。";
//字节输出:是输入还是输出以程序为参考,将数据输入程序中就为输入流,反只将数据从程序中输出到其他地方就是输出流
String path = "D:"+File.separator+"test"+File.separator+"001.txt";
OutputStream out  = new FileOutputStream(path,true);//表示追加文件内容。
out.write(data.getBytes());
//out.close();
}
 
}
 


3字符流输出和输入:

Demo:

//输出流:
File f =  new File("d:"+File.separator+"text"+File.separator+"test2.text");
Writer out = new FileWriter(f,true);
String t = "\r\n我爱我的祖国";
out.write(t);
out.close();
//输入流:
FileReader in = new FileReader(f);
char[] c = new char[(int)f.length()];
//第一种方式
//int len=in.read(c);
//第二种方式
int temp;
int len = 0;
while((temp = in.read()) != -1){
c[len] = (char)temp;
len++;
}


五、flush操作(输出流中都有):

计算机访问外部设备(磁盘文件),要比直接访问内存慢很多,如果每次write都要直接写出到磁盘文件中,CPU都会花更多的时间,此时我们可以准备一个内存缓冲区,程序每次write方法都是直接写到内存缓冲区中,当内存缓冲区满后,系统才把缓冲区内容一次性写出给磁盘文件.

使用缓冲区的好处:

1:提高CPU使用率.

2:有机会回滚写入的数据.

对于字节流,flush方法不是都有作用(部分字节流才有作用,缓冲流),对于字符流都起作用.

如果我们调用close方法,系统在关闭资源前,会先调用flush方法.

操作系统使用-1表示磁盘文件的结尾标记.

缓冲区大小一般使用容量整数倍,可以提高IO性能.

 

六、内存操作流(适配器模式):

把数据先临时存在数组中,待会再从数组中获取出来.

   1、字节内存流: ByteArrayInputStream/ByteArrayOutputStream

   2、字符内存流: CharArrayReader/CharArrayWriter

   3、字符串流:StringReader/StringWriter(把数据临时存储到字符串中)

Demo:

public class ByteArrayDemo {
 
public static void main(String[] args) {
String info = "wo shi haoren";
// 内存输入流
//将小写转换为大写
ByteArrayInputStream bais = null;
ByteArrayOutputStream baos = null;
try {
bais = new  ByteArrayInputStream(info.getBytes());
baos = new ByteArrayOutputStream();
int temp = 0;
while((temp=bais.read())!=-1){
char c = (char)temp;
char cc = Character.toUpperCase(c);
baos.write(cc);
}
System.out.println(baos.toString());
} catch (Exception e) {
// TODO: handle exception
}finally{
try {
bais.close();
baos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
 
}
 
}


 

七、转换流:

转换流:把字节流转成字符流:

   InputStreamReader:把字节输入流转成字符输入流.

   OutputStreamWriter:把字节输出流转成字符输出流.

为什么有字节转字符流,没有字符转字节流.

     字节流可以操作一切文件(纯文本文件/二进制文件).

     字符流是用来操作中文纯文本使用的,本身是对字节流的增强.

 

八、管道流:

定义:实现两个线程之间的数据交互.

PipedInputStream/PipedOutputStream/PipedReder/PipedWriter

Demo:

public class PipedDemo {
 
public static void main(String[] args) {
//管道流
OutPip op = new OutPip();
Receive rec = new Receive();
Thread th1 = new Thread(op);
Thread  th2 = new Thread(rec);
th1.start();
th2.start();
try {
op.getOut().connect(rec.getIn());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//op.getOut().connect(snk);
}
}
 
//接收线程
class Receive implements Runnable{
private PipedInputStream in;
public Receive() {
this.in = new PipedInputStream();
}
@Override
public void run() {
byte[] b = new byte[1024];
try {
this.in.read(b);
System.out.println(new String(b));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
try {
this.in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public PipedInputStream getIn() {
return in;
}
}
//发送线程
class OutPip implements Runnable{
private PipedOutputStream out;
 
public OutPip() {
this.out = new PipedOutputStream();
}
@Override
public void run() {
String info = "好人是我!";
try {
this.out.write(info.getBytes());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
try {
this.out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public PipedOutputStream getOut() {
return out;
}
}


九、打印流(只能是输出流):

1PrintStream: 字节打印流

2PrintWriter:  字符打印流

3、使用打印流作为输出流,此时的输出操作会特别简单,因为在打印流中:a):提供了print方法:打印不换行  b):提供了println方法:打印再换行

printprintln方法可以支持打印/输出各种数据类型的数据,记住void println(Object x) 即可

打印流中的格式化输出(prinf方法):

System.out.println();其实就相当于PrintStream ps = System.out;       ps.println()

Demo:

public class PrintStreamDemo {
 
public static void main(String[] args) {
String path = "d:"+File.separator+"test"+File.separator+"007.txt";
PrintStream ps = null;
try {
ps = new PrintStream(new FileOutputStream(path,true));
ps.println("好人!");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
PrintWriter pw = new PrintWriter(path);
pw.print("坏人");
pw.flush();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
 
}


4打印流的格式化输出(装饰设计模式)

Demo

File f = new File("d:"+File.separator+"text"+File.separator+"test6.text");
PrintStream ps = new PrintStream(new FileOutputStream(f));
PrintWriter pw  = new PrintWriter(new FileWriter(f));
String name = "张三";
int age = 20;
double score = 89.7;
char sex = 'F';
//字节打印流格式化输出
//	ps.printf("name:%s,age:%d,score:%f,sex:%c",name,age,score,sex);
//	ps.close();
//字符打印流格式化输出
pw.printf("name:%s,age:%d,score:%f,sex:%c",name,age,score,sex);
pw.close();


十、标准输入/输出流:

 1标准的输入: 通过键盘录入数据给程序.

 2标准的输出: 在屏幕上显示程序数据.

 3System类中有两个常量:

     1):InputStream in =   System.in;

     2):PrintStream out = System.out;

 4标准流的重定向操作:

 1):标准的输入:  通过键盘录入数据给程序.

     重新指定输入的源不再是键盘,而是一个文件.

     static void setIn(InputStream in)  重新分配“标准”输入流。    

     此后,System.in数据的来源就是通过setIn制定的源.

 2):标准的输出:  在屏幕上显示程序数据.

     重新指定输出的目标不再是屏幕,而是一个文件.

     static void setOut(PrintStream out)  重新分配“标准”输出流。

Demo1

public class OutDemo1 {
 
public static void main(String[] args) throws IOException {
OutputStream out  = System.out;//标准输出流
out.write("我是好人".getBytes());
Scanner sc = new Scanner(System.in);//标准的输入
OutputStream err = System.err;
err.write("错了!".getBytes());
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String temp = br.readLine();
System.out.println(temp);
}
}


Demo2

/**
 * 标准输入输出流的重定向
 * @author Administrator
 *
 * 本质是一个字节的输出入流,所以可以改变流的方向
 *
 */
 
public class OutInDemo {
 
public static void main(String[] args) {
//PrintStream out  = System.out;
//out.print("祖国万岁!");
System.out.println("祖国万岁!");
//重定向
String path = "d:"+File.separator+"test"+File.separator+"mylogs.txt";
PrintStream ps;
try {
ps = new PrintStream(new FileOutputStream(path,true));
System.setOut(ps);
//System.out.println("祖国万岁!");
int a = 3/0;
} catch (Exception e) {
//e.printStackTrace();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(sdf.format(new Date()));
System.out.println(e);
}
 
}
 
}


十一、扫描器类(Scanner:

Demo:

public class ScannerDemo {
/**
 * @param args
 * @throws FileNotFoundException
 */
public static void main(String[] args) throws FileNotFoundException {
//Scanner scan = new Scanner(System.in);//从键盘接收数据
Scanner scan = new Scanner(new FileInputStream("D:"+File.separator+"text"+File.separator+"text9.text"));//从文件输入
//改变以空格做为分隔符,如果不改就只能输出空格之前的
scan.useDelimiter("\n");
System.out.print("setin:");
String s = scan.next();
System.out.print(s);
}
}


 

十二、合并流:

SequenceInputStream:就是把多个输入流,合并成一个流对象

Demo:

public class SequenceInputStreamDemo {
/**
 * @param args
 * @throws IOException
 */
public static void main(String[] args) throws IOException {
/*String path1 = "D:"+File.separator+"soft"+File.separator+"test1.txt";
String path2 = "D:"+File.separator+"soft"+File.separator+"test2.txt";
String path3 = "D:"+File.separator+"soft"+File.separator+"test3.txt";
File f1 = new File(path1);
File f2 = new File(path2);
File f3 = new File(path3);
FileInputStream is1 = new FileInputStream(f1);
FileInputStream is2 = new FileInputStream(f2);
FileOutputStream is3 = new FileOutputStream(f3);
SequenceInputStream  s = new SequenceInputStream(is1, is2);
int temp=0;
while((temp=s.read())!=-1){
is3.write(temp);
}
s.close();
is1.close();
is2.close();
is3.close();
*/
String path1 = "D:"+File.separator+"soft"+File.separator+"test1.txt";
String path2 = "D:"+File.separator+"soft"+File.separator+"test2.txt";
String path3 = "D:"+File.separator+"soft"+File.separator+"test3.txt";
String path4 = "D:"+File.separator+"soft"+File.separator+"test4.txt";
File f1 = new File(path1);
File f2 = new File(path2);
File f3 = new File(path3);
File f4 = new File(path4);
FileInputStream is1 = new FileInputStream(f1);
FileInputStream is2 = new FileInputStream(f2);
FileInputStream is4 = new FileInputStream(f4);
FileOutputStream is3 = new FileOutputStream(f3);
ArrayList<FileInputStream> ar = new ArrayList<FileInputStream>();
ar.add(is1);
ar.add(is2);
ar.add(is4);
Enumeration<FileInputStream> et = Collections.enumeration(ar);
SequenceInputStream  s = new SequenceInputStream(et);
int temp=0;
while((temp=s.read())!=-1){
is3.write(temp);
}
s.close();
is1.close();
is2.close();
is3.close();
}
}


合并器/分割器:

Demo

public class SplitDemo {
 
public static void main(String[] args) {
String path = "d:"+File.separator+"test"+File.separator+"files";
try {
FileUtils.merge(path);
} catch (IOException e) {
e.printStackTrace();
}
}
 
}
 
class FileUtils{
//合并器
public static void merge(String path) throws IOException{
File f = new File(path);
File[] fs = f.listFiles();
/*for (int i = 0; i < fs.length; i++) {
System.out.println(fs[i].getName());
}*/
ArrayList<InputStream> list = new ArrayList<InputStream>();
for (File x : fs) {
//System.out.println(x);
InputStream in = new FileInputStream(x);
list.add(in);
//in.close();
}
Enumeration<InputStream> enm = Collections.enumeration(list);
SequenceInputStream sis = new SequenceInputStream(enm);
OutputStream out = new FileOutputStream(path+File.separator+"temp.jpg");
byte[] b = new byte[1024];
int len  = 0 ;
while((len=sis.read(b))!=-1){
out.write(b, 0, len);
}
out.close();
sis.close();
}
//分割器
public static void split(String path,int size) throws IOException{
InputStream in  = new FileInputStream(path);
String tempPath = "d:"+File.separator+"test"+File.separator+"files"+File.separator;
byte[] b = new byte[size];
int len = 0;
int count = 0;
while((len=in.read(b))!=-1){
OutputStream out  = new FileOutputStream(tempPath+(++count)+".me");
out.write(b, 0, len);
out.close();
}
in.close();
}
}


十三、Properties集合类配置文件:

public class PropertiesDemo {
 
public static void main(String[] args) throws IOException {
Properties prs = new Properties();  //Properties():创建一个空属性列表
prs.setProperty("os-name", "windows"); //etProperty():
prs.setProperty("os-version", "win10");
prs.setProperty("os-time","2017-10-23");
String path = "d:"+File.separator+"temptest"+File.separator+"5.txt";
File f = new File(path);
OutputStream ops = new FileOutputStream(f);
prs.store(ops, "key=values");//store:将properties表中的属性列表写入输出流
ops.close();
//读出并修改配置文件
String path1 = "d:"+File.separator+"temptest"+File.separator+"5.txt";
File f1 = new File(path1);
InputStream ips = new FileInputStream(f1);
Properties pros = new Properties();
pros.load(ips);//load:读取属性列表
pros.setProperty("os-version", "win7");
OutputStream ops1 = new FileOutputStream(f1);
pros.store(ops1,"sd");
//pros.list(System.out);//list:将属性列表输出到指定的输出流
//ips.close();
}
}


 

十四、压缩流:

public class ZipUtil {
public static void main(String[] args) {
String path = "D:"+File.separator+"test";
try {
ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream("D:"+File.separator+"tt.zip"));
new ZipUtil().zip(new File(path),"file",zipOut) ;
zipOut.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void zip(File inputFile,String str,ZipOutputStream zipFile) throws IOException{  
        //判断文件是否为文件夹  
        if(inputFile.isDirectory()){  
          File[] files = inputFile.listFiles();  
          zipFile.putNextEntry(new ZipEntry(str+"/"));  //使用指定名字创建压缩条目  
          str = str.length()==0 ? "":str+"/";  
          for (int i=0;i<files.length;i++) {  
              zip(files[i],str+files[i].getName(), zipFile); //递归调用压缩方法  
          }  
        }else{  
            InputStream in = new FileInputStream(inputFile);  
            //开始写入新的 ZIP 文件条目并将流定位到条目数据的开始处。  
            ZipEntry zipname = new ZipEntry(str);  
            zipFile.putNextEntry(zipname);    
            byte[] buff = new byte[1024];  
            int len = 0;  
            while((len = in.read(buff))!=-1){  
                zipFile.write(buff, 0, len);  
            }  
            in.close();  
        }  
    }  
//解压文件:
public void unzip(String zipFileName, String outputDirectory) {  
        System.out.println("正在解压···");  
        try {  
            ZipInputStream in = new ZipInputStream(new FileInputStream(zipFileName));  
            ZipEntry z = in.getNextEntry();  
            while (z != null) {  
                System.out.println("正在解压:" + z.getName());  
                //创建以zip包文件名为目录名的根目录  
                File f = new File(outputDirectory);  
                f.mkdirs();  
                if (z.isDirectory()) {  
                    String name = z.getName();  
                   // name = name.substring(0, name.length() - 1);  
                    f = new File(outputDirectory + File.separator + name);  
                    f.mkdirs();  
                } else {  
                    f = new File(outputDirectory + File.separator + z.getName());  
                    f.createNewFile();  
                    FileOutputStream out = new FileOutputStream(f);  
                    byte[] buff = new byte[1024];  
                    int len ;  
                    while ((len = in.read(buff)) != -1) {  
                        out.write(buff,0,len);  
                    }  
                    out.close();  
                }  
                z = in.getNextEntry();   //读取下一个ZipEntry  
            }  
            in.close();  
        } catch (FileNotFoundException e) {  
            e.printStackTrace();  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
    }  
 
 
}


十五、序列化与反序列化:

1序列化: 指把堆内存中的Java对象数据,通过某种方式把对象存储到磁盘文件中或者传递给其他网络的节点(在网络上传输),我们把这个过程称之为序列化.

2反序列化:把磁盘文件中的对象数据或者把网络节点上的对象数据,恢复成Java对象的过程.

3为什么要做序列化:

   1):在分布式系统中,需要共享的数据的JavaBean对象,都得做序列化,此时需要把对象再网络上传输,此时就得把对象数据转换为二进制形式.

以后存储在HttpSession中的对象,都应该实现序列化接口(只有实现序列化接口的类,才能做序列化操作).

   2):服务钝化:如果服务发现某些对象好久都没有活动了,此时服务器就会把这些内存中的对象,持久化在本地磁盘文件中(Java对象-->二进制文件).

如果某些对象需要活动的时候,现在内存中去寻找,找到就使用,找不到再去磁盘文件中,反序列化我们得对象数据,恢复成Java对象

4需要做序列化的对象的类,必须实现序列化接口:java.io.Serializable接口(标志接口[没有抽象方法]).

   底层会判断,如果当前对象是Serializable的实例,才允许做序列化.    boolean   ret = Java对象  instanceof  Serializable;

5使用对象流来完成序列化和反序列化操作:

     ObjectOutputStream:  通过writeObject方法做序列化操作的.

     ObjectInputStream:    通过readObject方法做反序列化操作的.

做反序列化操作必须存在对象的字节码对象.

6transient关键字(这个属性就不会在被序列化,序列化主要是对属性的序列化)

Eg: private transient String name = "haoren";

Demo

/**
 * 对象序列化:就是将对象作为一个整体,进行输入输出或传递。
 * @author Administrator
 *
 */
public class SerializableDemo1 {
 
public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
User user = new User(1,"好人","蛟龙港");
String path = "d:"+File.separator+"test"+File.separator+"object.txt";
//序列化:
ObjectOutputStream oops = new ObjectOutputStream(new FileOutputStream(path));
oops.writeObject(user);
oops.close();
//反序列化:
ObjectInputStream oips = new ObjectInputStream(new FileInputStream(path));
User userNew = (User) oips.readObject();
System.out.println(userNew.getName());
 
}
 
}


 

十六、数据流:

数据流,提供了可以读/写任意数据类型的方法:

DataOutputStream:  提供了 writeXxx(xxx value)方法.

DataInputStream:   提供了 readXxx()方法.

  【注】 writeXxxreadXxx必须要对应起来,  writeByte写出的数据,此时只能使用readByte读取回来.

Demo

/**
 * 读写基本数据类型的流
 
 * @author Administrator
 *
 */
public class DataOutputStreamDemo {
 
public static void main(String[] args) {
int number = 2;
double score = 3.1415;
String path = "d:"+File.separator+"test"+File.separator+"008.txt";
try {
DataInputStream dis = new DataInputStream(new FileInputStream(path));
int data1 = dis.readInt();
char data2 = dis.readChar();
double data3 = dis.readDouble();
System.out.println((data1+1)+","+data2+","+data3);
dis.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
 
}
 
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值