黑马程序员-【IO流】

时间:2023-02-18 08:11:18

                                         ------- android培训java培训、期待与您交流! ----------

 

IO流用来处理设备之间的数据传输

 Java对数据的操作是通过流的方式 

 Java用于操作流的对象都在IO包中

 

file类

 

    与文件本身有关的操作类,用来将文件或者文件夹封装成对象

 

    可以进行创建、删除文件等操作

 

    File对象可以作为参数传递给流的构造函数

 

file类的常见方法

 

    1、创建

 

     boolean creatNewFile();当且仅当不存在,该方法创建一个该File对象所指定的新文件,创建成功返回true。

   

     在指定位置创建文件,如果该文件已经存在,则不创建,返回false

   

     和输出流不一样,输出流对象一建立就会创建文件,如果该文件已经存在会对原文件进行覆盖

 

import java.io.*;

class FileDemo {
public static void main(String[] args) throws IOException {
method_1();
// System.out.println("Hello World!");
}

public static void method_1() throws IOException {
File f = new File("file.txt");
System.out.println("creat:" + f.createNewFile());
}
}


   boolean mkdir():创建文件夹 只能创建一级目录 如果文件夹已存在则创建失败,返回false 而且

  boolean mkdirs():创建多级文件夹

 

import java.io.*;

class FileDemo {
public static void main(String[] args) throws IOException {
method_2();
}

public static void method_2() {
File f = new File("file.txt");
File dir = new File("abc//cba");// 如果没有文件夹abc 则创建失败,返回false 只能创建一级文件夹
System.out.println("mkdir:" + dir.mkdir());
}
}


 

2、删除

 

  boolean delete():删除File对象所对应的文件或路径;

 

  void deleteOnExit() 在程序退出时删除指定文件

 

3、判断

 

boolean exists():判断对象对应的文件或目录是否存在;


boolean canWrite():判断对象对应文件或目录是否可写;


boolean canRead():判断对象对应文件或目录是否可读;


boolean isFile():判断对象是文件,不是目录;


boolean isDirectory()  判断对象的文件是否是一个目录;


boolean isAbsolute() 判断对象对应文件或目录是否为绝对路径名;

 

4、返回信息

 

String getName():返回文件名或路径名(若是路径,返回最后一级子路径名)


String getPath():返回对象对应的路径名


File  getAbsoluteFile():返回绝对路径


String getAbsolutePath():返回对象对应的绝对路径


String getParent():返回文件目录的上一级目录名


boolean renameTo(File newName):重命名此File对象对应的文件或目录,若重命名成功返回true;


实例:

 

import java.io.*;

class FileDemo {
public static void main(String[] args) {
// consMethod();
method_1();// 第二次运行出现false
}

public static void method_1() {
File f = new File("file.txt");
sop("creat:" + f.creatNewFile());// 创建指定文件
}

public static void method_3()
{
File f = new File("file.txt")
//记住在判断文件对象是否是文件或者目录时,必须要先判断该文件对象封装的内容是否存在
//通过exists判断
sop(f.isFile());//打印为false 文件不存在
sop(f.isDirectory());//打印为false
}

public static void consMethod() {
// 将a.txt封装成file对象。可以将已有的和未出现的文件或者文件夹封装成对象
File f1 = new File("c:\\abc\\a.txt");
File f0 = new File("a.txt");

File f2 = new File("c:\\abc", "b.txt");

File d = new File("c:\\abc");

File f3 = new File(d, "c.txt");
sop("f1:" + f1);// 打印 f1:c:\\abc\\a.txt
sop("f0:" + f1);// 打印 f1:a.txt
sop("f2:" + f2);// 打印 f2:c:\\abc\\b.txt
sop("f3:" + f3);// 打印 f3:c:\\abc\\c.txt
// 由于目录分隔符\\在不同系统中定义不同 因此可以用File.separator完成跨平台操作
File f4 = new File("c:" + File.separator + "abc" + File.separator + "zsc" + File.separator + "b.txt");

}

public static void sop(Object obj) {
System.out.println(obj);
}

}

 

Flie对象功能--返回文件列表

 

import java.io.*;

class FileDemo2 {
public static void main(String[] args) {
listRootsDemo();
listDemo();
}

public static void listRootsDemo() {
File[] files = File.listRoots();
for (File f : files) {
System.out.println(f);// 输出结果C:\ D:\ ...
}
}

public static void listDemo()
{
File f = new File("C:\\");
String[] names = f.list();\\调用list方法的file对象必须是封装了一个目录 该目录还必须存在, 否则报错空指针异常
for(String name :names)
{
System.out.println(name);//输出结果为C盘目录下的所有文件名 包含隐藏文件
}
}
}

 

list(FilenameFilter filter)


返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中满足指定过滤器的文件和目录。


FilenameFilter(文件过滤器)该接口里包含accept(File dir,String name)方法,该方法依次对指定File的所有子目录,子文件夹进行迭代。


dir - 被找到的文件所在的目录。


name - 文件的名称。


当且仅当该名称应该包含在文件列表中时返回 true;否则返回 false

class List1 {
public static void main(String[] args)
{
File dir = new File("E:\过滤器练习");
String[] arr = dir.list(new FilenameFilter()
{
public boolean accept(File dir,String name)
//System.out.println(dir+"---"+name);//测试dir(目录)和name(目录内文件名)是什么
//if(name.endWith(".java"))
// return true;
//else
//return false;
return name.endWith(".java");
})
}

 

listFiles()


返回一个抽象路径名数组,这些路径名表示此抽象路径名表示的目录中的文件。

 

class ListFiles
{
public static void main(String[] args)
{
File dir = new File("E:\\");
File[] files = dir.listFiles();
for(File f : files)
{
System.out.println(f.getName()+"---"+f.length());//文件夹大写无法获取
}
}
}

 

递归及其应用

现在要求输出一个给定目录中的全部文件的路径。


本程序肯定只能依靠递归的操作完成,因为在一个给定的路径下有可能还是文件夹,那么如果是文件夹的话则肯定要继续列出,重复判断。


递归就是在方法里调用自身;


在使用递归时,必须有一个明确的递归结束条件,称为递归出口。


练习:列出文件夹下所有文件(包含子文件夹内)

 

public class Demo2 {
public static void main(String[] args) {
File f = new File("D:/V5");

mylist(f);
}

public static void mylist(File f) {
System.out.println(f);// 先输出一下,因为不能确定接受来的文件是否是文件夹!
if (f.isDirectory()) {
File[] file = f.listFiles();
for (File file2 : file) {
mylist(file2);
}
}
}
}

 

删除一个目录(注意:要删除目录必须删除目录下的文件和子目录)

 

import java.io.File;

public class Demo11 {
public static void main(String[] args) {

File f = new File("D:/V5");
deleter(f);

System.out.println("删除成功 !");
}

public static void deleter(File f){//程序简陋,就没有判断空引用!
if(f.isFile()){
f.delete();
}else if(f.isDirectory()){
File []file = f.listFiles();
for (File file2 : file) {
deleter(file2);//调用自身,递归!
file2.delete();//删除子文件夹(内部没有文件的时候可以删除),如果这里写上f.delete();那么V5这个文件夹也没有了
}
}
}
}


Properties 是hashtable的子类

也就是说它具备map集合的特点,而且它里面存储的键值对都是字符串

是集合中和IO技术相结合的集合容器

该对象的特点可以用于键值对形式的配置文件

在加载数据时,需要数据有固定格式:键=值

import java.io.*;
import java.util.*;

class PropertiesDemo {
public static void main(String[] args) throws IOException {
setAndGet();
method_1();
loadDemo();
}

public static void loadDemo() throws IOException {
Properties prop = new Properties();
FileInputStream fis = new FileInputStream("info.txt");
// 将流中数据加载进集合
prop.load(fis);
// System.out.println(prop);
FileOutputStream fos = new FileOutputStream("info.txt");
prop.store(fos, "haha");
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) {
String[] arr = line.split("=");
prop.setProperty(arr[0], arr[1]);

}
bufr.close();
System.out.println(prop);
}

// 设置和获取元素
public static void setAndGet() {
Properties prop = new Properties();
prop.setProperty("zhangsan", "30");
prop.setProperty("lisi", "40");

// System.out.println(prop);
String value = prop.getProperty("lisi");
System.out.println(value);

prop.setProperty("lisi", 89 + "");

Set<String> names = prop.stringPropertyName();
for (String s : names) {
System.out.println(s + ":" + prop.getProperty(s));
}
}
}

   数据流是一串连续不断的数据的集合,就像水管里的水流,在水管的一端一点一点地供水,而在水管的另一端看到的是一股连续不断的水流.


   数据写入程序可以使一段一段地向数据流管道中写入数据,这些数据段会按先后顺序形成一个长的数据流.


   在程序中所有的数据都是以流的方法进行传输和保存的

 

   Java把所有传统的流类型(类或抽象类)都放在java.io包中,用以实现输入输出功能。


流的操作步骤

     一、使用File类找到一个文件对象,得到IO操作的源或目标


     二、通过字节流或字符流的子类创建对象,(得到IO操作的通道)


     三、进行读或写的操作,(IO操作)


     四、关闭输入/输出,(打完收工,注意节约资源,关掉)


        由于流的操作属于资源操作,所以在操作的最后一定要关闭以释放资源。


字节流和字符流

 

   一般来说处理字符或字符串时使用字符流,处理字节或二进制对象时应使用字节流

 

字节流


         字节流主要是操作byte(字节)的类型数据:


         字节输出流:OutputStream


        字节输入流:InputStream

字符流


Java中的字符是Unicode编码,是双字节的,1个字符 等于 2个字节;


使用字节来处理字符文本就不太方便了,此时可以考虑使用字符流;


字符流主要是操作char的类型数据:


字符输出流:Writer


字符输入流:Reader


字节流和字符流的区别

字节流和字符流在使用上的代码结构都是非常类似的,但是其内部本身也是有区别的,因为在进行字符流操作的时候会使用到缓冲区(内存中),而字节流操作的时候是不会使

用到缓冲区的。

输入流和输出流相对于内存设备而言.

将外设中的数据读取到内存中:输入

将内存的数写入到外围中:输出


字符流的由来:


其实就是:字节流读取文字字节数据后,不直接操作而是先查指定的编码表.获取对应的文字

在对这个文字进行操作.简单说:字节流+编码表

 

字节流的两个顶层父类:
1、InputStream


2、OutputStream


字符流的两个顶层父类:
1、Reader


2、Writer


这些体系的子类都以父类名作为后缀


而且子类名的前缀就是该对象的功能

从熟悉的文字开始字符流


//需求:将一些文字存储到硬盘一个文件中。


记住:如果要操作文字数据,建议优先考虑字符流


而且要将数据从内存写到硬盘上,要使用字符流中的输出流。Writer


硬盘的数据基本上体现是文件,希望找到一个可以操作文件的Writer找到了FileWriter


文件的复制:

 

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class Demo8 {
public static void main(String[] args) throws IOException {

File src = new File("E:/heima.doc");
File tar = new File("E:/heima1.doc");

copy(src, tar);
System.out.println("Well done !");
}

public static void copy(File src, File tar) throws IOException {
try (InputStream is = new FileInputStream(src);
OutputStream os = new FileOutputStream(tar);) {
byte[] b = new byte[1024];
int len;
while ((len = is.read(b)) != -1) {
os.write(b);
}

} catch (IOException e) {
e.printStackTrace();
}
}
}

 

图片的复制

 

public class Demo {
public static void main(String[] args) throws Exception {
File src = new File("D:/chuanzhiboke.jpg");

File tar = new File("D:/黑马.jpg");

copy(src,tar);
System.out.println("复制完成!");
}
public static void copy(File src,File tar) throws Exception{
/*Reader r = new FileReader(src);
Writer w = new FileWriter(tar);*/
/*if(!src.exists()){
throw new Exception("对不起,源文件不存在!");
}*/
InputStream in = new FileInputStream(src);
OutputStream os = new FileOutputStream(tar);

byte []c = new byte[1024];
int len;
while((len = in.read(c)) != -1){
os.write(c);
}

/*w.close();
r.close();*/
}
}