一、回顾
字符流
Reader
Writer
字符缓冲流
BufferedReader
BufferedWriter
字节流:可以操作任何类型的数据
InputStream:字节输入流
-----FileInoutStream:int read() 一次读一个字节 int read(byte[] arr)
OutputStream:字节输出流,不需要刷新
-----FileOutputStream:write(byte[] b);
下面来看看字节流
二、字节流
下面列出的是下面代码示例要用的几个方法
得到文件中字节的总数,也就是文件的大小(直接使用这个方法可能会造成数组内存溢出,因此适合于小文件)
(1)使用FileInputStream实现从文件中读取数据-----read()和read(byte[] arr)两种方式
使用FileOutputStream向文件中写入数据-----write()
import java.io.*;
class Demo1
{
public static void main(String[] args)throws IOException
{
//write();
//read();
//read2();
fun();
}
//获取文件的大小
public static void fun()throws IOException
{
FileInputStream fis = new FileInputStream("tmp.txt");
//int num = fis.available();//得到的是文件中字节的总数,也就是文件的大小
byte[] arr=new byte[fis.available()];
int num = fis.read(arr);
sop(new String(arr,0,num));
}
//从文件中读取数据
public static void read2()throws IOException
{
FileInputStream fis = new FileInputStream("tmp.txt");
byte[] arr=new byte[1024];
int num=0;
while((num = fis.read(arr))!=-1)
{
System.out.print(new String(arr,0,num));
}
fis.close();
/*
int num = fis.read(arr);//返回的是读取的字节的个数
System.out.print(new String(arr,0,num));
num = fis.read(arr);//返回的是读取的字节的个数
System.out.print(new String(arr,0,num));
num = fis.read(arr);//返回的是读取的字节的个数
System.out.print(num);//-1
*/
}
//从文件中读取数据
public static void read()throws IOException
{
FileInputStream fis = new FileInputStream("tmp.txt");//文件需要事先存在
//int read() 一次读一个字节
int num =0;
while((num=fis.read())!=-1)
{
//System.out.println(Integer.toBinaryString(num));
System.out.print((char)num);
}
fis.close();
/*
int num = fis.read();
System.out.print((char)num);
num = fis.read();
System.out.print((char)num);
num = fis.read();
System.out.print((char)num);
num = fis.read();
System.out.print(num); -1
*/
}
//向文件中写入数据--字节流
public static void write()throws IOException
{
//创建字节输出流对象和文件相关联
FileOutputStream fos=new FileOutputStream("tmp.txt");
//void write(byte[] b)
fos.write("abc".getBytes());//编码 直接写入文件
fos.close();
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
总结:字节流和字符流的区别:直接写入文件,不需要刷新
(2)字节流实现复制一个文件
import java.io.*;
class Demo2
{
public static void main(String[] args)throws IOException
{
//字节流实现复制一个文件
FileInputStream fis = new FileInputStream("Home2.java");
FileOutputStream fos = new FileOutputStream("Home2_copy.java");
int num=0;
while((num=fis.read())!=-1)
{
fos.write(num);
}
fis.close();
fos.close();
}
}
(3)字节流复制一张图片
class Demo3
{
public static void main(String[] args)
{
//复制一个图片 --只能用字节流
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try
{
bis=new BufferedInputStream(new FileInputStream("33.jpg"));
bos=new BufferedOutputStream(new FileOutputStream("33_copy.jpg"));
byte[] arr=new byte[1024];
int num=0;
while((num=bis.read(arr))!=-1)
{
bos.write(arr,0,num);
}
}
catch (IOException e)
{
e.printStackTrace();
}finally{
if(bis!=null)
try
{
bis.close();
}
catch (IOException e)
{
throw new RuntimeException("字节缓冲读取流关闭失败");
}
if(bos!=null)
try
{
bos.close();
}
catch (IOException ee)
{
throw new RuntimeException("字节缓冲输出流关闭失败");
}
}
}
}
字节缓冲流
BufferedInputStream对比BufferedReader:
BufferedReader----String readLine()
BufferedInputStream----没有自己特有的方法
BufferedOutputStream对比BufferedWriter:
BufferedWriter----newLine()
BufferedOutputStream----没有自己的特有的方法
三、转换流InputStreamReader、OutputStreamWriter
InputStream子类对象in
(1)下面先用in实现循环读取键盘输入的小写字母,够一行时,输出其大写形式
import java.io.*;
class Demo4
{
public static void main(String[] args)throws IOException
{
//FileInputStream fis = new FileInputStream("tmp.txt");
//InputStream stream = System.in;//in是一个InputStream的子类对象,是一个已经和键盘绑定好的输入流对象
//int num = stream.read();//阻塞式方法
//System.out.println((char)num);
//循环读取键盘输入的小写字母,够一行时,输出其大写形式
int num=0;
StringBuilder sb = new StringBuilder();
while(true)
{
num = System.in.read();
if(num=='\r')
continue;
else if(num=='\n'){
if("over".equals(sb.toString()))
break;
System.out.println(sb.toString().toUpperCase());
sb.delete(0,sb.length());
}else
sb.append((char)num);
}
}
}
(2)上面的in属于InputStream,是字节流。下面将字节流转换为字符流——转换流
字节输入流转成字符输入流:InputStreamReader-----从字节输入流到字符输入流的桥
字节输出流转成字符输出流:OutputStreamWriter-----从字符输出流转成字符输出流的桥
class Demo5
{
public static void main(String[] args) throws IOException
{
//1.定义标准的键盘输入流
InputStream in = System.in;
//2.把字节输入流转成字符输入流
InputStreamReader isr=new InputStreamReader(in);//转换流
//3.把字符输入流对象传给BufferedReader的构造方法
BufferedReader br=new BufferedReader(isr);
//4.定义标准的输出流(输出到控制台)
PrintStream ps=System.out;//已经和控制台绑定的字节输出流对象
//5.把字节输出流转成字符输出流
OutputStreamWriter osw=new OutputStreamWriter(ps);
//6.把字符输出流对象传给BufferedWriter的构造方法
BufferedWriter bw=new BufferedWriter(osw);
String line=null;
while((line=br.readLine())!=null)
{
//当输入over的时候结束输入
if("over".equals(line))
break;
bw.write(line);
bw.newLine(); //每次要加换行
bw.flush(); //每次要刷新
//System.out.println(line);
}
br.close();
bw.close();
}
}
(3)经过上面的知识点学习,下来总结一下
字符流
Reader int read() int read(char[] arr)
FileReaer
Writer write(String str) flush()
FileWriter
字节流
InputStream int read() int read(byte[] arr)
FileInputStream
OutputStream write(byte[] arr)写入多个字节 write(int a)一次写入一个字节
FileOutputStream
缓冲流:提高效率,不具备读写功能的
字符缓冲流
BufferedReader(Reader r) 父类是Reader,自己特有的功能:String readLine()
BufferedWriter(Writer w) 父类是Writer,自己特有的功能: void newLine()
字节缓冲流
BufferedInputStream(InputStream in) 父类是InputStream,没有自己特有的功能
BufferedOutputStream(OutputStream out) 父类是OutputStream,没有自己特有的功能
标准输入流:System.in in是InputStream的子类对象
标准输出流:System.out out 是PrintStream类型的对象
转换流
InputStreamReader(InputStream i)
new BufferedReader(new InputStreamReader(System.in));
OutputStreamWriter(OutputStream s)
new BufferedWriter(new OutputStreamWriter(System.out))
1.
确定从哪儿读
确定往哪儿写
2.确定字符流还是字节流
3.确定设备
读取键盘数据,写入到控制台
(4)练习
分别从键盘读或从文件读,写入到控制台或写入到文件,
import java.io.*;
class Demo6
{
public static void main(String[] args) throws IOException
{
//键盘读
//BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
//从文件读
BufferedReader br=new BufferedReader(new InputStreamReader(new FileInputStream("tt.txt")));
//控制台写
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(System.out));
//写入到文件
//BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("tt.txt")));
String line=null;
while((line=br.readLine())!=null)
{
if("over".equals(line))
break;
bw.write(line);
bw.newLine();
bw.flush();
}
br.close();
bw.close();
}
}
四、File
把文件和文件夹面向对象
(1)构造函数和常用方法
File(String pathname)
import java.io.*;
import java.util.*;
import java.text.*;
class Demo7
{
public static void main(String[] args)throws IOException
{
//File:把文件和文件夹面向对象
//File(String pathname)
File f1=new File("F:\\bg2002\\day18\\Demo1.java");//绝对路径
File f11=new File("Demo1.java");//相对路径
//File(String parent, String child)
File f2=new File("F:\\bg2002\\day18","Demo1.java");
//File(File parent, String child)
File f3=new File("F:\\bg2002\\day18");
File f4=new File(f3,"Demo1.java");
//System.out.println("Hello World!");
//fun1();
fun2();
}
public static void fun2()throws IOException
{
File file=new File("Home2_copy.java");
if(!file.exists())
file.createNewFile();
System.out.println(file.getName());
System.out.println(file.getPath());//如果是相对路径,显示相对路径
System.out.println(file.getParent());//如果是相对路径,显示null
System.out.println(file.getAbsolutePath());
String riqi = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(file.lastModified()));
System.out.println(riqi);
System.out.println(file.delete());
}
public static void fun1()throws IOException
{
File file=new File("bg2002.txt");
if(!file.exists())
file.createNewFile();//创建文件
//file.mkdirs();//创建文件夹
System.out.println(file.isFile());//判断是不是文件
System.out.println(file.isDirectory());//判断是不是文件夹
System.out.println(file.isHidden());//判断是不是隐藏的
}
}
(2)listRoots()、list()、listFiles()
package day17;
import java.io.*;
class Demo6 {
public static void main(String[] args)
{
File[] roots = File.listRoots();
for(File file:roots)
System.out.println("listRoots():\t"+file);
//String[] list()
File dir=new File("F:\\QMDownload");
String[] arr = dir.list();//只得到目录下所有的文件和文件夹
for(String ss:arr)
{
System.out.println("dir.list():\t"+ss);
}
//File[] listFiles() 得到目录下所有的文件和文件夹,包括完整的路径
File[] array = dir.listFiles();
for(File f:array)
{
System.out.println("listFiles():\t"+f.getAbsolutePath());
}
}
}
(3)File[] listFiles(FileFilter filter) 方法-----lambda表达式
import java.io.*;
class Demo9
{
public static void main(String[] args) throws IOException
{
//File[] listFiles(FilenameFilter filter)
File dir=new File("f:\\bg2002\\day18");
//File[] files = dir.listFiles(new MyFilter());
/*
File[] files=dir.listFiles(new FilenameFilter(){
public boolean accept(File dir,String name)
{
if(name.endsWith(".mp4"))
return true;
else
return false;
}
});
*/
File[] files=dir.listFiles((dirs,name) ->name.endsWith(".txt"));
for(File ff:files)
System.out.println(ff);
}
}
class MyFilter implements FilenameFilter
{
public boolean accept(File dir,String name)
{
if(name.endsWith(".java"))
return true;
else
return false;
}
}
(4)练习
删除指定目录下的所有的内容,包括子文件夹下的所有内容
import java.io.*;
class Demo11
{
public static void main(String[] args) throws IOException
{
//删除指定目录下的所有的内容,包括子文件夹下的所有内容
File dir=new File("f:\\bg2002\\day17");
del(dir);
}
public static void del(File dir)throws IOException
{
File[] files = dir.listFiles();
for(File file:files)
{
if(file.isDirectory())
del(file);
else
System.out.println(file+"..."+file.delete());
}
System.out.println(dir+"..."+dir.delete());
}
}
五、打印流
PrintStream:字节输出流,继承了OutputStream,具备了字节输出流的基本功能,特有的功能是打印功能,有如下方法:
PrintStream(File file)
PrintStream(String file)
PrintStream(OutputStream stream)
具体用法如下:
import java.io.*;
class Demo12
{
public static void main(String[] args)throws IOException
{
PrintStream ps=new PrintStream(new FileOutputStream("t.txt"));
//ps.write(353); // write(int a) 00000000 00000000 00000001 01100001-->款掉前三个字节01100001
//ps.write("abc".getBytes());
//ps.println(353);//按照数据的原样显示
ps.write(String.valueOf(353).getBytes());// "353".getBytes()
ps.close();
}
}
PrintWriter :继承了Writer,具备了Writer的基本功能,自己特有的功能是打印功能
PrintWriter(String file)
PrintWriter(File file)
PrintWriter(OutputStream out)
PrintWriter(Writer write)
下面用PrintWriter实现从控制台边输入边打印
import java.io.*;
class Demo13
{
public static void main(String[] args) throws IOException
{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out)); //这是用BufferedWrite实现边输入边打印
PrintWriter pw = new PrintWriter(System.out,true);//指定第二个参数,可以自动刷新
String line=null;
while((line=br.readLine())!=null)
{
if("end".equals(line))
break;
pw.println(line);
//bw.write(line);
//bw.newLine();
//bw.flush();
}
br.close();
pw.close();
}
}
六:序列流-----SequenceInputStream (了解)
import java.io.*;
import java.util.*;
class Demo14
{
public static void main(String[] args) throws IOException
{
/*
FileInputStream f1=new FileInputStream("Demo1.java");
FileInputStream f2=new FileInputStream("Demo2.java");
FileInputStream f3=new FileInputStream("Demo3.java");
Vector<FileInputStream> v=new Vector<>();
v.add(f1);
v.add(f2);
v.add(f3);
Enumeration<FileInputStream> en = v.elements();
*/
FileInputStream f1=new FileInputStream("Demo1.java");
FileInputStream f2=new FileInputStream("Demo2.java");
FileInputStream f3=new FileInputStream("Demo3.java");
List<FileInputStream> list=new ArrayList<>();
list.add(f1);
list.add(f2);
list.add(f3);
Enumeration<FileInputStream> en = Collections.enumeration(list);
SequenceInputStream se=new SequenceInputStream(en);
FileOutputStream fos = new FileOutputStream("hebing.java");
byte[] arr=new byte[1024];
int num=0;
while((num=se.read(arr))!=-1){
fos.write(arr,0,num);
}
se.close();
fos.close();
}
}
练习:下面使用序列流把一个文件拆分成多个文件,再把多个文件合并成一个文件
import java.io.*;
import java.util.*;
class Demo15
{
public static void main(String[] args)throws IOException
{
//把一个文件拆成多个文件
File file=new File("ok.jpg");
splits(file);
}
//把一个文件拆成多个文件
public static void splits(File file)throws IOException
{
if(!file.isFile())
return;
//把拆出来的文件放到同一个文件夹下
String name=file.getName().substring(0,file.getName().indexOf("."));
File dir=new File(name);
if(!dir.exists())
dir.mkdir();
FileInputStream fis=new FileInputStream(file);
FileOutputStream fos = null;
byte[] arr=new byte[1024*1024*2];
int num=0;
int n=1;
while((num=fis.read(arr))!=-1){
fos=new FileOutputStream(new File(dir,(n++)+".jpg"));
fos.write(arr,0,num);
}
//附加一个说明信息
Properties pro=new Properties();
pro.setProperty("fileType",file.getName());
pro.setProperty("fileNumber",Integer.toString(--n));
//把map集合中的信息写入到文件
fos=new FileOutputStream(new File(dir,"readme.txt"));
pro.store(fos,"haha");
fis.close();
fos.close();
}
}