OI流
1. File类
概念:文件名或者目录名的一种抽象表示形式,简单来说就是表示目录或者文件名的
构造方法
public File (String pathname):直接指定当前路径,创建一个File对象
File file = new File ("F:\\test\\a.txt");
public File (String parent ,String child):指定一个父目录,child文件或者文件夹,创建一个File对象
File file1 = new File ("F\\demo","\\a.txt");
public File(File parent,String child):创建一个File对象
参数一:File文件对象,描述某个父目录
参数二:子目录或者子文件夹
创建功能
public boolean createNewFile() throws IOException:创建一个文件,如果存在,不会创建
public boolean mkdir(): 创建一个目录,如果存在,目录不会创建,返回false,如果不存在,创建,返回true
注意事项:一次只能创建单个目录,如果要创建多级目录,必须父目录存在,否则false
public boolean mkdirs():创建目录,一次创建多个目录,如果当前目录不存在,就会自动创建
如果没有指定路径,默认在当前路径下创建文件以及文件夹
删除功能
public boolean delete () 删除此抽象路径名表示的文件或者目录,如果此路径名表示一个目录,则该目录必须为空才能删除
重命名功能
public boolean renameTo (File dest);
参数:指定的文件路径
1.如果两次表达dest路径一致的话,仅仅是改名字
2.如果两次表单路径不一致的话,改名并剪切到指定路径 如果是多级目录,父目录必须存在;
File f1 = new File("杨桃.jpg") ;
File f2 = new File("e:\\高圆圆.jpg") ;
System.out.println("renamteTo():"+f1.renameTo(f2));
判断功能
public boolean isDirectory() :判断是否是文件夹
public boolean isFile() :判断是否是文件
public boolean exists() :判断是否存在
public boolean canRead() :判断是否可读 只能读取内容
public boolean canWrite() :判断是否是可写 可写 可以修改和删除里面内容
public boolean isHidden() :是否是隐藏的文件或者文件夹
获取功能
public String getAbsolutePath() :绝对路径
public String getPath() :相对路径
public String getName() :获取File对象的名称
public long length() :获取长度(此抽象路径名表示的文件的长度,以字节为单位)
public long lastModified():最后一次操作当前文件或者目录的时间戳 返回值是一个时间毫秒值
File f =new File ("bean.txt");
System.out.println(f.getAbsolutePath()); //D:\wangchao\com.wangchao.oi\bean.txt
System.out.println(f.getPath()); //bean.txt
System.out.println(f.getName()); //bean.txt
File f =new File ("E:\\bean.txt"); (nihao吗?)
System.out.println(f.getAbsolutePath()); //E:\bean.txt
System.out.println(f.getPath()); // E:\bean.txt
System.out.println(f.length()); // 8 返回当前文件中内容的字符长度
File的高级获取功能
public File[] listRoots():列出可用的文件系统根 即列出计算机磁盘的盘符;
public String [] list();返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中的文件和目录
列出文件名
public File[] listFiles():返回的是一个File数组,这些路径名表示此抽象路径名表示的目录中的文件
列出文件的绝对路径 返回的是一个File类的引用 它具有类的所有属性和方法
2. io流
流的分类:按照数据类型划分
字节流
字节输入流 inputStream 读取数据
字节输出流 outputStream 写出数据
字符流
字符输入流 Reader
字节输出流 Writer
按照流向划分 :
输入流:都是将数据读取出来(控制体输出/读取到服务器端)输入流是指从外围设备流向主机(包括CPU和内存)的数据流。
输出流:将数据写出到指定位置(将服务器读取到的数据写到客户端)
2.1 节点流
2.1.1 字节流
1 .字节输入流
/**
* @Author
* @Date
* FileInputStream的基本测试
*/
public class InPutStreamTest01 {
public static void main ( String[] args ) {
try {
File file = new File("hello.txt");
FileInputStream fileInputStream = new FileInputStream(file);
// 一次读取一个字节
int by;
while ((by = fileInputStream.read())!=-1){
System.out.print((char)by);
}
// 一次读取一个字节数组
byte [] bytes = new byte[1024];
int len;
while ((len=fileInputStream.read(bytes))!=-1){
System.out.print(new String(bytes,0,len));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
2.字节输出流
/**
* @Author
* @Date
*FileOutputStream的基本测试
*/
public class OutputStreamTest {
public static void main ( String[] args ) throws Exception {
// 目标文件
File srcFile = new File("hello.txt");
// 写入流写入的文件
File desFile = new File("world.txt");
// 获取输入 输出流
FileInputStream inputStream = new FileInputStream(srcFile);
FileOutputStream outputStream = new FileOutputStream(desFile);
// 一次写入一个字节数组
byte [] bytes = new byte[1024];
int len;
while ((len=inputStream.read(bytes))!=-1){
outputStream.write(bytes,0,len);
}
outputStream.close();
inputStream.close();
}
}
2.2.2字符流
1. 字符输入流
/**
* @Author xiaoqi
* @Date
* FileReader的一个基本测试
*/
public class ReaderTest001 {
public static void main ( String[] args ) throws IOException {
File file = new File("hello.txt");
FileReader reader = new FileReader(file);
// 这里有一次读取一个字符和一个字符数组,与字节输入流类似,这里以一次读取一个字符数组为例
char [] chars = new char[1024];
int len;
while ((len=reader.read(chars))!=-1){
System.out.print(new String(chars,0,len));
}
}
}
2.字符输出流
/**
* @Author xiaoqi
* @Date
* FileWriter类的一个基本测试
*/
public class FileWriterTest001 {
public static void main ( String[] args ) throws Exception {
File srcFile = new File("hello.txt");
File desFile = new File ("java.txt");
FileReader reader = new FileReader(srcFile);
FileWriter writer = new FileWriter(desFile);
char [] chars = new char[1024];
int len;
while((len=reader.read(chars))!=-1){
writer.write(chars,0,len);
writer.flush();
}
writer.close();
reader.close();
}
}
2.2 缓冲流
BufferedOutputStream:字节缓冲输出流
public BufferedOutputStream(OutputStream out):创建缓冲输出流对象,缓冲区默认的(使用居多,缓冲大小足够大!)
public BufferedOutputStream(OutputStream out,int size):创建缓冲输出流对象并且指定缓冲大小
BufferedInPutStream:字节缓冲输入流
public BufferedInPutStream(InputStream in);创建缓冲输入流对象,缓冲区默认无限大
public BufferedInPutStream(InPutStream in , int size)创建缓冲输入流对象,并且指定大小
BufferedReader:字符缓冲输入流
BufferedReader(Reader in) 创建一个使用默认大小输入缓冲区的缓冲字符输入流。
BufferedReader(Reader in, int sz) 创建一个指定缓冲大小
读取的特有功能:public String readLine() :一次读取一行内容
BufferedWriter:字符缓冲输出流
public BufferedWriter(Writer out):提供默认缓冲区大小的字符缓冲输出流,默认缓冲区足够大
public BufferedWriter(Writer out,int size):指定缓冲大小的
BufferedWriter的特有功能 :public void newLine():写入一个新的行分隔符
处理流的作用: 提高流的读取,写入速度,原因:内部提供了一个缓冲区
2.2.1 字节缓冲流的使用
/**
* @Author xiaoqi
* @Date
* 字节流的图片复制 的使用
*/
public class BufferedTest001 {
BufferedInputStream bs;
BufferedOutputStream bo;
@Test
public void copyPhoto() {
try {
// 声明字节缓冲流
bs = new BufferedInputStream(new FileInputStream("D:\\360downloads\\298277.jpg"));
bo = new BufferedOutputStream(new FileOutputStream("F:\\123.jpg"));
// 创建字节数组
byte [] bytes = new byte[1024];
int len;
// 进行复制操作
while((len = bs.read(bytes)) != -1){
bo.write(bytes,0,len);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭资源,先创建的后关闭
if (bo!= null){
try {
bo.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bs!= null){
try {
bs.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
2.2.2字符缓冲流的使用
/**
* @Author xiaoqi
* @Date
* 字符缓冲流的复制操作,使用缓冲流的特有API
*/
public class BufferedTest002 {
BufferedReader bd;
BufferedWriter bw;
@Test
public void copyTxtByBuffered(){
try {
// 获取字符缓冲流
bd = new BufferedReader(new FileReader("hello.txt"));
bw = new BufferedWriter(new FileWriter("hello1.txt"));
// 利用字符缓冲流提供的特有方法来进行复制操作
String str;
// bd.readLine() 一次读取一行数据
while ((str = bd.readLine())!= null){
bw.write(str);
bw.newLine(); //换行
}
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
if (bw != null){
bw.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (bd != null){
bd.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
2.3 转换流
OutputStreamWriter:字符转换输出流
构造方法
public OutputStreamWriter(OutputStream out):使用默认的编码格式创建字符流对象
public OutputStreamWriter(OutputStream out,Charset cs):指定编码格式创建字符流对象
InputStreamReader:字符转换输入流
构造方法
InputStreamReader(InputStream in) 创建一个使用默认字符集的 InputStreamReader。对象
InputStreamReader(InputStream in, Charset cs) :创建指定字符集的字符流对象
使用当前字符转换流:
输出和读取数据,要保证编码格式一致!
转换流: 其实就是字符流与字节流之间的一个桥梁
/**
* @Author xiaoqi
* @Date
* 需求:将UTF-8编码的文件复制时变成GBK编码的文件
*/
public class ConvertTest {
InputStreamReader isr;
OutputStreamWriter osw;
@Test
public void copyOfConvert(){
try {
// 获取字符转换流,并指定相应的编码
isr = new InputStreamReader(new FileInputStream("hello.txt"),"utf-8");
osw = new OutputStreamWriter(new FileOutputStream("123.txt"),"GBK");
// 进行复制操作,与字符流的复制操作相同
char [] chars = new char[1024];
int len;
while((len = isr.read(chars))!= -1){
osw.write(chars,0,len);
osw.flush();
}
} catch (Exception e) {
e.printStackTrace();
}finally {
// 关闭资源
try {
if (osw != null){
osw.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (isr != null){
isr.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
2.4 标准的输入输出流
/**
* @Author xiaoqi
* @Date
* 标准的输入输出流的测试
* System.in :标准的输入流,默认从键盘输入
* System.out :标准的输出流,默认从控制台输出
*/
/**
* 需求:键盘录入数据,如果是exit则退出
*/
public class StandardFlow {
public static void main ( String[] args ) throws IOException {
// 键盘录入
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
while (true) {
System.out.println("请输入字符串");
// 一次读取一行数据
String str = br.readLine();
// 忽略大小写比较
if (str.equalsIgnoreCase("exit")) {
System.out.println("结束");
break;
}
// 将输入的字符串大写输出
String string = str.toUpperCase();
System.out.println(string);
}
}
}
2.5 打印流
/* 打印流:
* PrintStream PrintWriter
System.out的返回值就是PrintSream
*/
public class PrintTest {
public static void main ( String[] args ) throws FileNotFoundException {
PrintStream out = System.out;
out.print("nihaoa");
}
}
2.6 数据流
// DataInputStream 针对基本类型数据操作和String类型的
// DataOutputStream
/**
* @Author xiaoqi
* @Date
* 数据流的操作:
* 注意;在读取的时候,要按照顺序进行,不然会出现以下异常
* EOFException: 输入流的读取过程 中,程序意外的读取到末尾
*/
public class DataTest001 {
// 将数据写入文件
@Test
public void writeTest() throws Exception {
DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.txt"));
dos.writeUTF("wangzi");
dos.write(20);
dos.writeDouble(120000.89);
dos.writeBoolean(true);
}
// 从文件中读取数据,按照顺序进行读取
@Test
public void readTest() throws Exception {
DataInputStream dis = new DataInputStream(new FileInputStream("data.txt"));
String s = dis.readUTF();
int i = dis.read();
double d = dis.readDouble();
boolean b1 = dis.readBoolean();
System.out.println(s);
System.out.println(i);
System.out.println(d);
System.out.println(b1);
}
}
2.7 对象流(序列化流)
实体类
@Data //get/set方法 (使用这三个注解需要导入lombok包)
@AllArgsConstructor //全参构造
@NoArgsConstructor //无参构造
public class User implements Serializable{
// 这个常量是java运行时环境根据类的内部细节自动生成的,如果类的实例变量做了修改,这个常量也会发生改变,因此一般建议显示声明
// 这个常量就是一个序列化版本的标识符,在进行反序列化的时候,要把流中的版本标识符与相应的实体类的版本标识符进行比较,相同则反序列化,如果不同,则抛出异常
private static final long serialVersionUID = 6739406330338108087L;
private int id;
private String name;
private String pass;
}
对象流的测试类
/**
* @Author xiaoqi
* @Date
*ObjectOutputStream序列化:将Java对象以流数据的方式在(网络,设备..)数据的传输
* ObjectInputStream反序列化:(还原) 需要将流数据以java对象的方式保存
* 如果一个类要进行序列化实现,那么该类必须实现序列化接口,否则出现序列化异常!
*/
public class ObjectflowTest {
// 将java对象保存在user.txt文件中
@Test
public void writeTest() throws Exception {
// 1.获取序列化流
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("user.txt"));
// 写入
oos.writeObject(new User(1,"wangzi","123"));
// 刷新
oos.flush();
oos.close();
}
/**
* 这个方法是反序列化的方法,即将流数据读取出来
*/
@Test
public void readTest() throws Exception{
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("user.txt"));
User user = (User) ois.readObject();
System.out.println(user);
}
}
2.8 随机访问流
/**
* @Author xiaoqi
* @Date
* RandomAccessFile 随机访问流,他继承自Object类
* 既可以作为一个输入流,也可以作为一个输出流
*/
/**
* 现在有这样一个需求,程序运行3次以后就不能再运行了
* 解决方案:使用随即流,创建一个文件,在文件里面写入运行的次数,因为随机流写入时会覆盖
* 原来文件,每运行一次,重新写入还能运行的次数
*/
public class RandomTest001 {
RandomAccessFile raf;
@Test
public void randomTest(){
// 获取一个随机访问流, “rw”表示可读可写
try {
raf = new RandomAccessFile("a.txt", "rw");
// 读取文件中的数据
String s = raf.readLine();
// -1 是程序已经运行一次,后面需要将这个数据写入a.txt文件
int i = Integer.parseInt(s) - 1;
if (i > 0){
System.out.println("还有"+i+"次机会");
// 在文件中写入剩余次数
raf.seek(0); //指针重新指向开头
// 这里要用字节写入
raf.write((i+"").getBytes());
}else {
System.out.println("你已经没有机会了");
}
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
if (raf != null){
raf.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
2.9 合并流
/**
* @Author xiaoqi
* @Date
* 合并流
*/
public class SequenceDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
FileOutputStream fos = null;
SequenceInputStream scs = null;
//创建InputStream 对象
try {
FileInputStream fis1 = new FileInputStream("a.txt");
FileInputStream fis2 = new FileInputStream("Aa.txt");
//创建合并流读取对象
scs = new SequenceInputStream(fis1,fis2);
//创建合写出对象
fos = new FileOutputStream("h.txt");
byte [] bytes = new byte [1024];
int len = 0;
while ((len = scs.read(bytes))!= -1) {
fos.write(bytes,0,len);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (scs != null) {
try {
scs.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
2.10 内存操作流
/**
* @Author xiaoqi
* @Date
* 内存操作流
主要内存中的一些数组(临时变量)进行操作
在Socket编程中(使用套接字流的一种),可以使用内存操作输入流给服务器端发送文件(针对小文件发送)
*/
public class BytearrayTest {
@Test
public void byteTest() throws IOException {
// 获取输出流,然后将数据写入流中
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bos.write("我是内存操作流".getBytes());
byte[] byteArray = bos.toByteArray();
// 获取输入流,将流中数据读取出来
ByteArrayInputStream bis = new ByteArrayInputStream(byteArray);
byte [] bytes = new byte[1024];
int len ;
while ((len = bis.read(bytes))!= -1){
System.out.println(new String(bytes,0,len));
}
}
}