JAVA基础课程(第二十二天)

JAVA基础课程

第二十二天 I/O流

File类的使用

(1)说明

​ ①java.io.File 类:文件和文件目录路径的抽象表示形式,与平台无关

​ ②File能新建,删除,重命名文件和目录,但File不能访问文件内容本身

​ ③想要在Java程序中表示一个真实存在的文件或目录,那么必须有一个File对象,但是Java程序中的一个File对象,可能没有真实存在的文件或目录。

​ ④File可以作为参数传递给流的构造器

(2)File常用构造器

    public File(String pathname) {
    
    } //以pathname为路径创建File对象,可以是绝对路径或者是相对路径
    public File(String parent, String child) {
    
    } //以parent为父路径,child为子路径创建File对象
    public File(File parent, String child) {
    
    } //根据一个父File对象和子文件路径创建File对象

​ 注意:

​ ①路径分隔符,路径的每级目录都用一个路径分隔符隔开

​ window和dos默认使用 “\”表示

​ unix和url使用“/”表示

​ 为了安全隐患,File还提供了一个常量public static final char separatorChar。

​ ②相对路径:相较于某个路径下,指明的路径

​ 绝对路径:包含盘符在内的文件或文件目录的路径

​ (3)File常用构造器和方法说明

@Test
	public void test(){
		File file = new File("hello.txt");
		File file1 = new File("C:\\Users\\92588\\Documents\\test\\word.txt");

		System.out.println(file);
		System.out.println(file1);

		File file2 = new File("C:\\Users\\92588\\Documents", "test1");


		File file3 = new File(file2, "pp.txt");
		System.out.println(file2);
		System.out.println(file3);
		System.out.println("****************1.File类的创建功能**************");

		try {
			file.createNewFile();//创建文件,如果存在就不创建返回false
		} catch (IOException e) {
			e.printStackTrace();
		}
		file1.mkdir();//创建目录,如果文件目录不存在就不创建,如果没有父级目录,也不创建,返回false
		file2.mkdirs();//创建文件目录,如果上级目录不存在,一并创建
		System.out.println("****************2.File类的删除功能**************");

		file2.delete();//删除文件或者目录

		System.out.println("****************3.File类的获取功能**************");
		//File类的获取功能
		System.out.println(file1.getAbsolutePath());  //获取绝对路径
		System.out.println(file1.getPath());  //获取路径
		System.out.println(file1.getName());  //获取名称
		System.out.println(file1.getParent());  //获取上层目录路径
		System.out.println(file1.length()); //文件长度
		System.out.println(file1.lastModified());  //最后更新时间

		//获取目录下所有文件名称
		String[] list = file1.list();
		for (String s : list) {
			System.out.println(s);
		}
		File[] files = file1.listFiles();
		//获取目录下所有文件
		for (File file4 : files) {
			System.out.println(file4);
		}


		//File判断功能
		System.out.println("****************4.File判断功能**************");

		System.out.println(file.isDirectory());//是否是文件目录
		System.out.println(file.isFile());//是否是文件
		System.out.println(file.exists());//是否存在
		System.out.println(file.canRead());//是否可读
		System.out.println(file.canWrite());//是否可写
		System.out.println(file.isHidden());//是否隐藏
	}

​ (4)练习

IO流原理及流的分类

​ (1)Java IO原理

​ ①I/O是Input/OutPut,用于处理设备之间的数据传递。如读写文件,网络通讯等

​ ②Java中,对于数据的输入/输出以“流(stream)”的方式进行

​ ③输入:读取外部数据到内存中

​ ④输出:将内存中的数据输出到外部

​ ⑤输入输出都是以内存为中心。

​ (2)流的分类

​ 按照操作数据的不同,分为:字节流(8 bit),字符流(16bit)

​ 按照数据流的流向不同,分为:输入流,输出流

​ 按照流的角色不同,分为:节点流,处理流

字节流 字符流
输入流 InputStream Reader
输出流 OutputStream Writer

​ (3)IO流体系

分类 字节输入流 字节输出流 字符输入流 字符输出流
抽象基类 InputStream OutputStream Reader Writer
访问文件 FileInputStream FileOutputStream FileReader FileWriter
访问数组 ByteArrayInputStream ByteArrayOutputStream CharArrayReader CharArrayWriter
访问管道 PipeInputStream PipeOutputStream PipeReader PipeWriter
访问字符串 StringReader StringWriter
缓冲流 BufferendInputStream BufferendOutputStream BufferendReader BufferendWriter
转换流 InputStreamReader OutputStreamWriter
对象流 ObjectInputStream ObjectOutputStream
FillerInputStream FillerOutputStream FillerReader FillerWriter
打印流 PrintStream
推回输入流 PushbackInputStream PushbackReader
特殊流 DataInputStream DataOutputStream

节点流

	/***
	 * 节点流FileWriter和FileReader一块使用
	 * 对于文本文件,使用字符流处理
	 */
	@Test
	public void test5(){
		FileReader fileReader = null;
		FileWriter fileWriter = null;

		try {
			/***
			 * 读取word.txt文件
			 */
			fileReader = new FileReader(new File("word.txt"));
			/***
			 * 写到hello.txt
			 */
			fileWriter = new FileWriter(new File("hello.txt"));

			char[] chars = new char[10];
			int len;
			while ((len = fileReader.read(chars)) != -1){
				String s = new String(chars, 0, len);
				fileWriter.write(s);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if(fileReader != null){
					fileReader.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
			try {
				if(fileWriter != null) {
					fileWriter.close();

				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
/**
 * 节点流FileInputStream 和FileOutputStream的使用
 */
@Test
public void test() {
    
    
   FileInputStream fileInputStream = null;
   FileOutputStream fileOutputStream = null;
   try {
    
    
      fileInputStream = new FileInputStream(new File("C:\\Users\\92588\\Desktop\\相关文档\\学习\\ArrayList源码.md"));
      fileOutputStream = new FileOutputStream(new File("C:\\Users\\92588\\Desktop\\相关文档\\学习\\ArrayList源码1.md"));

      byte[] ch = new byte[1024];
      int len;
      while ((len = fileInputStream.read(ch)) != -1){
    
    
         fileOutputStream.write(ch,0,len);
      }
   } catch (IOException e) {
    
    
      e.printStackTrace();
   } finally {
    
    
      try {
    
    
         if(fileInputStream != null){
    
    
            fileInputStream.close();

         }
      } catch (IOException e) {
    
    
         e.printStackTrace();
      }
      try {
    
    
         if(fileOutputStream != null){
    
    
            fileOutputStream.close();
         }
      } catch (IOException e) {
    
    
         e.printStackTrace();
      }
   }
}

缓冲流

/***
	 * 缓冲流
	 * 提供流的读取和写入熟读,因为内部提供了一个缓冲区
	 * 处理流,也就是“嵌套”在自己的流的基础上。
	 */
	@Test
	public void test(){

		FileInputStream fis = null;
		FileOutputStream fos = null;
		BufferedInputStream bis = null;
		BufferedOutputStream bos = null;
		try {
			fis = new FileInputStream(new File("C:\\Users\\92588\\Desktop\\相关文档\\学习\\Java基础汇总.md"));
			fos = new FileOutputStream(new File("C:\\Users\\92588\\Desktop\\相关文档\\学习\\1.md"));
			bis = new BufferedInputStream(fis);
			bos = new BufferedOutputStream(fos);

			byte[] b = new byte[1024];
			int lem;
			while ((lem = bis.read(b)) != -1){
				bos.write(b,0,lem);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {

			//资源关闭,先关闭外层流的同时,内层流同时关闭
			try {
				fos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			try {
				fis.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
/*
			try {
				bos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			try {
				bis.close();
			} catch (IOException e) {
				e.printStackTrace();
			}*/

		}

	}

转换流

package com.test.course.filetest;

import org.junit.Test;

import java.io.*;

/**
 * 〈转换流〉 -- 属于字符流
 * InputStreamReader:将一个字节的输入流转换为字符的输入流
 * OutputStreamWriter:将会一个字符的输入流转换为字节的输出流
 * 字节流和字符流之间的转换
 *
 * @author PitterWang
 * @create 2020/5/12
 * @since 1.0.0
 */
public class FileTest3 {

	@Test
	public void test(){
		InputStreamReader isr = null;
		try {
			FileInputStream fis = new FileInputStream(new File("hello.txt"));
			isr = new InputStreamReader(fis,"UTF-8");
/*		FileOutputStream fos = new FileOutputStream(new File(""));
		OutputStreamWriter osw = new OutputStreamWriter(fos);*/

			char[] chars  = new char[1024];
			int len;
			while ((len = isr.read(chars)) != -1){
				String s = new String(chars, 0, len);
				System.out.println(s);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if(isr != null){
					isr.close();

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

		}
	}
}
字符编码

常见的编码表

ASCII:美国标准信息码表

IOS8859-1:拉丁码表

GB2312:中国编码表

GBK:中国编码表升级

Unicode:国际标准码

UTF-8:边长的编码方式,可用1-4个字节来表示一个字符

标准输入、输出流

​ (1)System.in和System.out分别代表了系统标准的输入(键盘输入)和输出设备(控制台输出)

​ (2)System.in的类型是InputStream,System.out类型是PrintStream,其实是OutputStream的子类

​ (3)重定向:通过System的setIn方法,setOut方法对默认设备进行改变

​ (4)使用

package com.test.course.filetest;

import org.junit.Test;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;

/**
 * 〈System练习〉
 *
 * @author PitterWang
 * @create 2020/5/13
 * @since 1.0.0
 */
public class SystemTest {
    
    

	//方法1:使用Scanner
	//方法2:使用System.in ->转换流 ->BufferedReader的readLine
	public static void main(String[] args){
    
    

		InputStreamReader isr = null;
		try {
    
    
			isr = new InputStreamReader(System.in);
			BufferedReader br = new BufferedReader(isr);
			while (true){
    
    
				String date = br.readLine();
				if("exit".equals(date)){
    
    
					break;
				}
				System.out.println(date.toUpperCase());
			}
		} catch (IOException e) {
    
    
			e.printStackTrace();
		} finally {
    
    
			if(isr!= null){
    
    
				try {
    
    
					isr.close();
				} catch (IOException e) {
    
    
					e.printStackTrace();
				}

			}
		}
	}
}

打印流

​ (1)实现将基本数据类型的数据格式转为字符串

​ (2)打印流:PrintStream和PrintWriter

​ ①提供了一系列的重载print()和println()方法

​ ②System.out返回的就是PrintStream的实例

package com.test.course.exceptiontest;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;

/**
 * 〈PrintTest〉
 *
 * @author PitterWang
 * @create 2020/5/13
 * @since 1.0.0
 */
public class PrintTest {

	public static void main(String[] args) {
		FileOutputStream fos = null;
		try {
			fos = new FileOutputStream("hello.txt");
		
			PrintStream printStream = new PrintStream(fos,true);

			if (printStream != null) {
				System.setOut(printStream); //修改输出位置到文件
			}

			for (int i = 0; i < 255; i++) {
				System.out.print((char)i);
				if(i%50 == 0){
					System.out.println();
				}
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} finally {
			if (fos == null) {
				try {
					fos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

数据流

​ (1)为了方便操作Java中的基本数据类型和String的类型,可以使用数据流

​ (2)数据流有两个类

​ DataInputStream和DataOutputStream

package com.test.course.filetest;

import org.junit.Test;

import java.io.*;

/**
 * 〈DataXXXStream〉
 *
 * @author PitterWang
 * @create 2020/5/13
 * @since 1.0.0
 */
public class DataStreamTest {
    
    

	public static void main(String[] args) throws FileNotFoundException {
    
    
		DataOutputStream dos = null;
		try {
    
    
			dos = new DataOutputStream(new FileOutputStream("hello.txt"));
			dos.writeUTF("哈哈哈");
			dos.flush();
			dos.write(12);
			dos.flush();
		} catch (IOException e) {
    
    
			e.printStackTrace();
		} finally {
    
    

			if (dos == null) {
    
    
				try {
    
    
					dos.close();
				} catch (IOException e) {
    
    
					e.printStackTrace();
				}
			}
		}
	}
	@Test
	public void test(){
    
    
		DataInputStream dis = null;
		try {
    
    
			dis = new DataInputStream(new FileInputStream("hello.txt"));

			String name = dis.readUTF();
			int age = dis.read();
			System.out.println(name);
			System.out.println(age);
		} catch (IOException e) {
    
    
			e.printStackTrace();
		} finally {
    
    
			if (dis == null) {
    
    
				try {
    
    
					dis.close();
				} catch (IOException e) {
    
    
					e.printStackTrace();
				}

			}
		}

	}
}

对象流

​ (1)ObjectInputStream和ObjectOutPutStream

​ (2)用于存储和读取基本数据类型数据或对象的处理流。他可以把Java中的对象写入数据源中,也可以把对象从数据源中还原回来。

​ (3)序列化:用ObjectOutputStream类保存基本数据类型或对象的机制

​ 反序列化:用ObjectInputStream类读取基本数据类型数据或对象机制

​ (4)ObjectInputStream和ObjectOutPutStream不能序列号static和transient修饰的成员变量

​ *(5)Java序列化机制,允许把内存中的Java对象转换成与平台无关的二进制流,从而允许把这种二进制流持久的保存在磁盘上,或通过网络进行传输。其他程序获得到这种二进制流,就可以恢复成原来的Java对象

package com.test.course.filetest;

import org.junit.Test;

import java.io.*;

/**
 * 〈ObjectXXXStreamTest〉
 *
 * @author PitterWang
 * @create 2020/5/13
 * @since 1.0.0
 */
public class ObjectStreamTest {
    
    

	/**
	 * 把实现Serializable的对象写入到object.dat中
	 */
	@Test
	public void test(){
    
    
		ObjectOutputStream oos = null;
		try {
    
    
			oos = new ObjectOutputStream(new FileOutputStream("object.dat"));
			oos.writeObject(new Person(1,"nidaye"));

			oos.flush();
		} catch (IOException e) {
    
    
			e.printStackTrace();
		} finally {
    
    
			if (oos == null) {
    
    
				try {
    
    
					oos.close();
				} catch (IOException e) {
    
    
					e.printStackTrace();
				}

			}
		}
	}

	/**
	 * 读取并转成对应对象
	 */
	@Test
	public void test2(){
    
    
		ObjectInputStream ois = null;
		try {
    
    
			ois = new ObjectInputStream(new FileInputStream("object.dat"));

			Object o = ois.readObject();
			Person s = (Person)o;
			System.out.println(s.toString());
			
		} catch (IOException e) {
    
    
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
    
    
			e.printStackTrace();
		} finally {
    
    
			try {
    
    
				if (ois == null) {
    
    
					ois.close();

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

/***
 * ①想要序列化,必须实现Serializable
 * ②提供一个serialVersionUID变量
 * ③内部属性是可序列化的
 */
class Person implements Serializable{
    
    
	private static final long serialVersionUID = -1L;

	private int id;
	private String name;

	public Person(int id, String name) {
    
    
		this.id = id;
		this.name = name;
	}

	public int getId() {
    
    
		return id;
	}

	public void setId(int id) {
    
    
		this.id = id;
	}

	public String getName() {
    
    
		return name;
	}

	public void setName(String name) {
    
    
		this.name = name;
	}

	@Override
	public String toString() {
    
    
		return "Person{" +
				"id=" + id +
				", name='" + name + '\'' +
				'}';
	}
}

随机存取文件流

​ (1)RadomAccessFile类 ,声明在io包下,但是直接继承Object类,并且实现DataInput,DataOutput这两个接口,意味着这个类即可读也可写

​ (2)RadomAccessFile类 支持随机访问方式,程序可以直接跳到文件的任意地方进行读,写文件

​ (3)RadomAccessFile包含一个记录指针,用以标示当前读写处位置

​ long getFilePointer:获取文件记录指针的当前位置

​ void seek(long pos):将文件记录指针定位到pos位置

​ (4)构造器

public RandomAccessFile(String name, String mode)
public RandomAccessFile(File file, String mode)
//mode指的是RandomAccessFile访问模式
r:只读
ew:打开以便读取和写入
rwd:打开以便读取和写入,同步文件内容的更新
rws:打开以便读取和写入,同步文件内容和元数据的更新

​ (5)如果RadomAccessFile作为输出流,写入到文件如果不存在,则执行过程自动创建,如果存在,就对原有文件内容进行覆盖(默认从头覆盖)

package com.test.course.filetest;

import org.junit.Test;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * 〈RadomAccessFileTest〉
 *
 * @author PitterWang
 * @create 2020/5/13
 * @since 1.0.0
 */
public class RadomAccessFileTest {
    
    

	@Test
	public void test(){
    
    
		RandomAccessFile r = null;
		RandomAccessFile r1 = null;
		try {
    
    
			r = new RandomAccessFile(new File("word.txt"), "rwd");
			r1 = new RandomAccessFile(new File("word1.txt"), "rwd");

			byte[] bytes = new byte[1024];
			int len;
			while ((len = r.read(bytes)) != -1){
    
    
				r1.write(bytes,0,len);
			}

			r1.seek(3);//从指针定位到3位置开始替换
			r1.write("sadfdsad".getBytes());
		} catch (IOException e) {
    
    

		} finally {
    
    

			if (r != null) {
    
    
				try {
    
    
					r.close();
				} catch (IOException e) {
    
    
					e.printStackTrace();
				}
			}
			if (r1 != null) {
    
    
				try {
    
    
					r1.close();
				} catch (IOException e) {
    
    
					e.printStackTrace();
				}
			}
		}



	}
}

猜你喜欢

转载自blog.csdn.net/weixin_35133235/article/details/106104325
今日推荐