十七.复制一个图片 虽然简单,但是考试会考
思路:
1.用字节读取流对象和图片关联。
2.用字节写入流对象创建一个图片文件。用于存储获取到的图片数据。
3.通过循环读写,完成数据的读取。
4.关闭资源。
import java.io.*;
class IoTextDemo
{
public static void main(String[] args) throws IOException
{
FileOutputStream fos = null;
FileInputStream fis = null;
try
{
fis = new FileInputStream("E:\\3.png");
fos = new FileOutputStream("F:\\2.png");
byte[] buf = new byte[1024];
int len = 0;
while((len = fis.read(buf)) != -1)
{
fos.write(buf,0,len);
}
}
catch (IOException e)
{
throw new RuntimeException("复制文件失败");
}
finally
{
try
{
if(fis != null)
fis.close();
}
catch (IOException e)
{
throw new RuntimeException("读取关闭失败");
}
try
{
if(fos != null)
fos.close();
}
catch (IOException e)
{
throw new RuntimeException("写入关闭失败");
}
}
}
}
十八.通过缓冲区复制mp3 很重要!!!会考!!!
bufferedOutStream
BufferedInputStream
(1)用系统的缓冲区
import java.io.*;
class IoTextDemo
{
public static void main(String[] args)throws IOException
{
long start = System.currentTimeMillis();
copyMethod_1();
long end = System.currentTimeMillis();
}
//通过字节流的缓冲区
public static void copyMethod_1() throws IOException
{
FileInputStream fis = new FileInputStream("E:\\123.mp3");
FileOutputStream fos = new FileOutputStream("F:\\ert.mp3");
BufferedInputStream bis = new BufferedInputStream(fis);
BufferedOutputStream bos = new BufferedOutputStream(fos);
//byte[] buf= new byte[1024]; //可不可以用这个??????看看字符流的缓冲写法
int len = 0;
while((len = bis.read()) != -1) //返回 0 到 255 范围内的 int 字节值
{
//write(int b) // 将指定的字节写入此输出流//只写最后一个字节!!!!!
bos.write(len); //这里可以接受int型吗????跟字符类型进行对比!!!!!!
}
bis.close();
bos.close();
}
}
(2)用自定义的缓冲区 很重要 多写写!!!!!
import java.io.*;
class IoTextDemo
{
public static void main(String args[]) throws IOException
{
long start = System.currentTimeMillis();
copyMethod_2();
long end = System.currentTimeMillis();
System.out.println(end-start+"毫秒");
}
public static void copyMethod_2() throws IOException
{
FileInputStream fis = new FileInputStream("E:\\123.mp3");
FileOutputStream fos = new FileOutputStream("F:\\ws.mp3");
MyBufferedInputStream mbis = new MyBufferedInputStream(fis);
BufferedOutputStream bos = new BufferedOutputStream(fos);
int len = 0;
while((len = mbis.myRead() ) != -1) //myRead返回的是字符
{
bos.write(len);
}
mbis.myClose();
bos.close();
}
}
class MyBufferedInputStream
{
private InputStream in ;
private int count = 0;
private int pos = 0;
private byte[] buf = new byte[1024];
MyBufferedInputStream(InputStream in)
{
this.in = in;
}
public int myRead() throws IOException
{
//比如第一次count=0,然后去取数据,count= 1024,然后在if(count = 0)读到第一个字节的数据并返回
//然后主函数的while没有读到-1,继续循环myRead
//此时count = 1023,在if(count >0)又读取一个数据并返回,然后同上不断循环,直到count =0;
//再次进入if(count = 0),如果in.read(buf)还有数据,那么继续重复上面的步骤,如果in.read(buf)没有读到数据
//count = -1;那么return -1,循环结束。进入到while内部进行写操作!!!
if(count == 0) //取数据
{
count = in.read(buf);
if(count < 0)
{
return -1; //读到结尾,返回-1
}
pos = 0;//指针指向的位置//新的读取从头开始!!!!!!!要不然会报数组越界这个Exception
count--;
byte b = buf[pos];
pos++;
//MP3是二进制数据 1111 1111 换成十进制 是 -1,所以可能没读到文件末尾就停止了
//b这里是byte类型,(00000000 00000000 00000000 11111111)被int接收,是被提升了,
//提升成(11111111 11111111 11111111 11111111 ),但是这样读出来还是-1
//11111111 11111111 11111111 11111111
//&
//00000000 00000000 00000000 11111111
//所以把前面全部补零,这样读出来就不会是-1.
return b&0xff;
}
else
if(count >0)
{
byte b = buf[pos];
count--;
pos++;
return b&0xff;
}
return -1;
}
public void myClose()throws IOException
{
in.close();
}
}
十九.Io流读取键盘录入
//读取键盘录入
//System.out:对应的是标准的输出设备,控制台
//System.in:对应的是标准的输入设备:键盘(java lang)。
需求:通过键盘输入数据。当录入一行数据后,就将该行数据进行打印。如果录入的数据是over,那么停止录入。
import java.io.*;
class IoTextDemo
{
public static void main(String[] args) throws IOException
{
InputStream in = System.in;
StringBuilder sb = new StringBuilder();
while(true)
{
int ch = in.read();
if(ch == '\r')
{
System.out.println("-r-");
continue;
}
else
if(ch == '\n')
{
System.out.println("-n-");
String s = sb.toString();
System.out.println("inlcude---"+s);
if("over".equals(s))
{
System.out.println("1");
break;
}
System.out.println(s.toUpperCase());
sb.delete(0,sb.length());
}
else //如果不加输入over也停不下来
{
System.out.println(ch);
System.out.println("add");
sb.append((char)ch);
}
}
}
}
//没有else
//as
//97
//add
//115
//add
//-r-
//-n-
//inlcude---as
//AS
//10 //换行符也被添加进了StringBuilder,所以"over".equals(s)不成立
//add //因为输入over后,s中实际是"\r\nover"
//over
//111
//add
//118
//add
//101
//add
//114
//add
//-r-
//-n-
//inlcude--- //注意这里有个换行符
// over
// OVER
// 10
// add
二十.IO流转换流
字符流:
FileReader
FileWriter
BufferedReader
BufferedWriter
字节流:
FileInputStream
FileOutputStream
BufferedInputStream
BufferedOutputStream
通过刚才的键盘录入一行数据并打印其大写,发现其实就是读一行数据的原理。
也就是readLine方法。
能不能直接使用readLine方法来完成键盘录入的一行数据的读取呢?
readLine方法是字符流BufferedReader类中的方法。
而键盘录入的read方法是字节流InputStream的方法。
那么能不能将字节流转成字符流,然后在使用字符流缓冲区的readLine方法呢?
(1)读取转换流
//需求
//用readline来读取键盘输入的数据
import java.io.*;
class IoTextDemo
{
public static void main(String[] args) throws IOException
{
InputStream in = System.in;
//InputStreamReader通过后缀名可以看出是属于字符流,
//但是前面的功能是操作字节流,是字节流通向字符流的桥梁!!!!!
//将字节流对象转成字符流对象,使用转换流。InputStreamReader
InputStreamReader isr = new InputStreamReader(in);
//为了提高效率,将字符串进行缓冲区技术高效操作。使用BufferedReader
BufferedReader bufr = new BufferedReader(isr);
String line = null;
while((line = bufr.readLine()) != null)
{
if("over".equals(line))
{
break;
}
System.out.println(line.toUpperCase());
}
bufr.close();
}
}
(2)写入转换流
import java.io.*;
class IoTextDemo
{
public static void main(String[] args) throws IOException
{
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
//OutputStreamWriter 是字符流通向字节流的桥梁!!!!
//字符输出流内部有缓冲区,所以要刷新OutputStreamWriter
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));
String line = null;
while((line = bufr.readLine()) != null)
{
if("over".equals(line))
{
break;
}
bufw.write(line.toUpperCase());
bufw.newLine();//newline属于BufferedWriter readLine是属于BufferedReader
bufw.flush();
}
bufr.close();
bufw.close();
}
}
二十一.IO流操作规律
(1)三种基本需求
1.需求:键盘录入,控制台输出
源:键盘录入。
目的:控制台。
BufferedReader bufr = new BufferedReader ( new InputStreamReader(System.in));
BufferedWriter bufw = new BufferedWriter ( new OuyputStreamWriter(System.out));
2.需求:想把键盘录入的数据存储到一个文件中。
源:键盘。
目的:文件
BufferedReader bufr = new BufferedReader ( new InputStreamReader(System.in));
BufferedWriter bufw = new BufferedWriter ( new OuyputStreamWriter(new FileOutputStream(“out.txt”))); //FileOutputStream字节输出流能操作文件的对象
3.需求:想要将一个文件的数据打印在控制台上。
源:文件。
目的:控制台。
BufferedReader bufr = new BufferedReader ( new InputStreamReader(new FileInputStream(“CopyPic.java”)));
BufferedWriter bufw = new BufferedWriter ( new OuyputStreamWriter(System.out));
(2)流操作的基本规律:
最痛苦的就是流对象有很多,不知道该用哪一个。
通过两个明确来完成。
1.明确源和目的。
源:输入流。InputStream Reader
目的:输出流。OutputStream Writer.
2.操作的数据是否是纯文本。
是:字符流。
不是:字节流。
3.当体系明确后,在明确用哪个具体的对象。
通过设备来进行区分:
源设备:内存,硬盘,键盘
目的设备:内存,硬盘,控制台
(3)例子
例一:将一个文本文件中的数据存储到另一个文件中。复制文件。
将一个文本文件中的数据存储到另一个文件中。复制文件。
step1:源:因为是源,所以使用读取流。InputStream Reader
是不是操作文本文件。是!这时就可以选择Reader,这样体系就明确了
step2:接下来明确要使用该体系中的哪个对象
明确设备:硬盘。上一个文件
Reader体系中可以操作文件的对象是FileReader
step3:是否需要提高效率:是!
加入Reader体系中缓冲区 BufferedReader.
FileReader fr = new FileReader(“a.txt”);
BufferedReader bufr = new BufferedReader(fr);
step4:目的:OutputStream Writer
是否是纯文本。是!Writer.
设备:硬盘,一个文件
Writer体系中可以操作文件的对象是FileWriter.
是否需要提高效率:是! 加入Writer体系中缓冲区 BufferedWriter
FileWriter fw = new FileWriter(“b.txt”);
BufferedWriter bufw = new BufferedWriter(fw);
例二:想把键盘录入的数据存储到一个文件中
想把键盘录入的数据存储到一个文件中
step1:设备:键盘。对应的对象是System.in:不是选择Reader吗?System.in对应的不是字节流吗?
为了操作键盘的文本数据方便。转成字符流按照字符串是最方便的,因为可以读一行再打印,使用readLine
所以既然明确了Reader,那么就将System.iin转换成Reader
用到了Reader体系中转换流,InputStreamReader
InputStreamReader isr = new InputStreamReader(System.in);
需要提高效率吗?需要!bufferedReader
BufferedReader bufr = new BufferedReader(isr);
step2:目的:OutputStream Writer
是否是纯文本?是! Writer
设备:硬盘。一个文件。使用FileWriter.
FileWriter fw = new FileWriter(“c.txt”);
需要提高效率吗?需要
BufferedWriter bufw = new BufferedWriter(fw);
*****************************************************
扩展一下,想要把录入的数据按照指定的编码表(UTF-8,一般默认使用的是默认字符编码(gbk)),将数据存到文件中
目的:OutputStream Writer
是否是纯文本?是! Writer
设备:硬盘。一个文件。使用FileWriter.
但是FileWriter是使用的默认编码表。GBK
但是存储时,需要加入指定编码表utf-8,而指定的编码表只有转换流可以指定(!!!!!!!!!!!!!)。
所以要使用的对象是OutPutStreamWriter.
而该转换流对象要接收一个字节输出流。而且还可以操作的文件的字节输出流FileOutputStream。//很特别!!!,容易写错
OutputStreamWRiter osw = new OutputStreamWriter(new FileOutputStream(“d.txt”),”UTF-8”);
需要高效吗?需要。
BufferedWriter bufw = new BufferedWriter(osw);
所以,记住,转换流什么时候使用。字符和字节之间的桥梁。通常,涉及到字符编码转换时,需要用到转换流。
如果用了其他编码,读取的时候就不能用fileWriter(默认使用GBK),要用输入转换流
********************************************************************
import java.io.*;
class IoTextDemo
{
public static void main(String[] args) throws IOException
{
//
// 通过两个明确来完成。
// 1.明确源和目的。
// 源:输入流。InputStream Reader
// 目的:输出流。OutputStream Writer.
// 2.操作的数据是否是纯文本。
// 是:字符流。
// 不是:字节流。
// 3.当体系明确后,在明确用哪个具体的对象。
// 通过设备来进行区分:
// 源设备:内存,硬盘,键盘
// 目的设备:内存,硬盘,控制台
//step1:源:输入流,
// 目的:输出流
//
//step2:操作的数据是否是纯文本:是
//step3:源设备:键盘
// 目的设备:硬盘
//输入推断:
//可以推断出,源本来应该使用System.in,但是因为输入的是纯文本,用字符流,整行读取效率比较搞,所以用reader
//但是键盘输入是字节流操作,所以要用 字节流到字符流的桥梁 inputStreamReader
//考虑到需要用缓冲区,所以按下面这么写
//BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
//输出推断:
//对于输出流是写入硬盘中的文件,而且是纯文本,所以用的肯定是字符流Writer,写到文件中去,FileWriter,
//为什么要用字节流写到文件中??????
//因为用的转换流是OutputStreamWriter,里面的对象应该是字节流!!!!!
//但是 FileWriter 默认使用GBK,但是要控制具体使用的编码表,就只能用转换流且可操作文件,所以用 FileOutputStream
//控制编码表,所以用 OutputStreamWriter,考虑到缓冲区的使用。
//BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter (new FileOutputStream("hc.txt") , "UTF-8"))
//所以,记住,转换流什么时候使用。字符和字节之间的桥梁。通常,涉及到字符编码转换时,需要用到转换流。
//如果用了其他编码,读取的时候就不能用fileWriter(默认使用GBK),要用输入转换流
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter (new FileOutputStream("hc2.txt") , "UTF-8"));
//GBK 6字节
//UTF-8 8字节
String line = null;
while((line = bufr.readLine()) != null)
{
if("over".equals(line))
{
break;
}
bufw.write(line.toUpperCase());
bufw.newLine();
bufw.flush();
}
bufw.close();
}
}
二十二.IO流改变标准输入输出设备
class IoTextDemo
{
public static void main(String[] args) throws IOException
{
//System.setIn(new FileInputStream(“PersonDemo.java”));//然后这就变成一个源了,不再是键盘输入
//System.setOut(new PrintStream(“zz.txt”));//打印成一个文件,这两个一般都不常见
//键盘的最常见写法
BufferedReader bufr = new BufferedReader ( new InputStreamReader(System.in));
BufferedWriter bufw = new BufferedWriter ( new OuyputStreamWriter(System.out));
String line = null ;
while((line = bufr.readLine() ) != null)
{
if(“over ”.equals(line))
break;
bufw.write(line.toUpperCase());
bufw.newLine();
bufw.flush();
}
bufr.close();
}
}
二十三.IO流异常的日志信息
import java.io.*;
import java.util.*;
import java.text.*;
//System.setout(new PrintStream(“exeception.log”));
//e.printStackTrace(System.out)
//上面两行等效于e.printStackTrace(new PrintStream(“a.txt”));
class IoTextDemo
{
public static void main(String[] args)
{
try
{
char[] ch = new char[2];
System.out.println(ch[3]);
}
catch (Exception e)
{
try
{ //时间的写法!!!!
Date d = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String s = sdf.format(d);
System.out.println(s);
PrintStream ps = new PrintStream("Exception_log.txt");
ps.print(s);
System.setOut(ps);
}
catch (IOException ex)
{
throw new RuntimeException("日志文件创建失败");
}
e.printStackTrace(System.out);
}
}
}
二十四.IO流系统信息
import java.io.*;
import java.util.*;
class IoTextDemo
{
public static void main(String[] args) throws Exception
{
//Properties util包中
Properties prop = System.getProperties();
//System.out.println(prop);//打印到操作台上
//list(PrintStream out)将属性列表输出到指定的输出流
prop.list(new PrintStream("SYSTEM_INFO.txt"));//写到一个文件中
}
}
二十五.File类概述
1.用来将文件或者文件夹封装成对象
2.方便对文件与文件夹的属性进行操作
3.File对象可以作为参数传递给流的构造函数
4。了解File类中的常用方法
5.弥补了流对象的不足,流对象也能操作文件,但是不能操作文件夹和文件属性信息(可读还是可写),流只能操作数据,
想要操作数据封装成的文件信息必须得用File类。
import java.io.*;
class IoTextDemo
{
public static void sop(Object obj)
{
System.out.println(obj);
}
public static void main(String[] args)
{
//下面四个都不会新创建文件夹和文件!!!
//将1.txt封装成File对象。可以将已有的和未出现的文件或者文件夹封装成对象
File f1 = new File("E:\\Java_Text\\1.txt");
//跟上面效果一样,但是下面是把路径,跟文件分成两个参数进行传递
File f2 = new File("E:\\Java_Text","2.txt");
//跟上面效果一样,分开写而已
File d = new File("E\\Java_Text");
File f3 = new File(d,"3.txt");
//跟上面效果一样,只是这种鞋可以跨平台,separator跨平台使用的目录分割符!!!!
File f4 = new File("E:"+File.separator+"Java_Text"+File.separator+"4.txt");
sop("f1:"+f1); //
sop("f2:"+f2);
sop("f3:"+f3);
sop("f4:"+f4);
}
}
二十六.File对象功能:创建 和 删除,判断。
File类常见方法:
1.创建
boolean creatNewFile(); 在指定位置创建文件,如果该文件已经存在,则不创建,返回false,和输出流不一样,输出流对象一建立创建文件。而且文件已经存在,会覆盖
boolean mkdir():创建文件夹(只能单级的)
boolean mkdirs():创建多级文件夹
2.删除。
boolean delete():删除失败返回false
void deleteonExit();在程序退出时删除指定文件://如果程序异常,跳转了,避免产生垃圾文件,如果放在finally,可能删不掉,因为可能正在被应用
3.判断
boolean exists():文件是否存
isFile();//是否是文件
isDirectory();//是否是目录
isHidden();//是否隐藏
isAbsolute();//是否绝对
4.获取信息
getName();
getPath();
getParent();
getAbsolutepath()//获取绝对路径
lastModified();
length();
import java.io.*;
class IoTextDemo
{
public static void sop(Object obj)
{
System.out.println(obj);
}
public static void main(String[] args)
{
method_4();
}
public static void method_1()
{
try
{
File f = new File("E:\\tq.txt");
sop("create:"+f.createNewFile()); // 只能用来创建文件,不能创建文件夹
}
catch (Throwable e)
{
throw new RuntimeException("出错");
}
}
public static void method_2()
{
//File f = new File("justtest.txt"); //只是封装对象,不会创建
//sop("Execute:"+f.canExecute()); //false
//判断文件或者目录存不存在都可以
//sop("exists:"+f.exists());//存在返回true,不存在返回false,这里返回false
//创建单级目录
//File dir = new File("E:\\JAVA_TEXT");
//sop("mkdir:"+dir.mkdir());//创建成功,返回TRUE,不成功返回false
//但是mkdir只能创建 单级目录!!!
//这里创建成功了
//创建多级目录
File dir = new File("E:\\JAVA_TEXT1\\DaXiongText\\add");
sop("mkdirs:"+dir.mkdirs());
}
//判断是不是目录
public static void method_3()
{
File f = new File("E:\\JAVA_TEXT2.txt");
//记住在判断文件对象是否是文件或者目的时,必须先判断文件封装对象是否存在
//通过exists判断
if(!f.exists())
{
f.mkdir();//就创造出一个JAVA_TEXT2.txt文件夹!!!!所以不要认为有后缀名就是一个文件
}
sop("是目录"+f.isDirectory());
sop("是文件"+f.isFile());
}
public static void method_4()
{
File f = new File("c:\\a.txt");
sop("path:"+f.getPath()); //打印:c;\a.txt
//如果写的是 FIle f = new File(“file.txt”); (这个文件是否存在无所谓!!!!)
//打印 path:file.txt
sop("abspath:"+f.getAbsolutePath());///打印:c;\a.txt
//如果写的是 FIle f = new File(“file.txt”); 打印abspath:D:\java1223\day20\file.txt
sop("parent:"+f.getParent());//该方法返回的是绝对路径中的父目录。
//如果没有,返回null(获取的是相对路径,但是如果相对路径中有上一层目录,
//那么该目录就是返回结果,如果没写上一层目录就没有,比如这么写就有
//FIle f = new File("abc\\file.txt");
}
public static void method_5()
{
File f1 = new File("c:\\Test.java");
File f2 = new File("d:\\haha.java");
sop("rename:"+f1.renameTo(f2)); //把文件换名字存放,rename成功 会把自己文件删掉
}
}
二十七.file对象功能-文件列表
String[] list() 只能获取名称
Files[] listFiles() 获取对象,可以通过getname getpath获取相关信息,一般开发中这个比较常用
import java.io.*;
class IoTextDemo
{
public static void main(String[] args)
{
list_demo2();
}
//用的是list
public static void list_demo()
{
File dir = new File("E:\\JAVA_TEXT");
String[] s = dir.list(new FilenameFilter() //这里我写错了
{
public boolean accept(File dir ,String name)
{
return name.endsWith("java"); //注意字母的拼写
}
});
System.out.println("文件个数:"+s.length);
for(String name:s)
{
System.out.println(name);
}
}
//用下listfile 和上面的比对一下
//Files[] listFiles() 获取对象,可以通过getname getpath获取相关信息
//一般开发中这个比较常用
public static void list_demo2()
{
File file= new File("E:\\JAVA_TEXT");
File[] s= file.listFiles( new FilenameFilter()
{
public boolean accept(File dir , String name)
{
return name.endsWith("java");
}
}
);
System.out.println(s.length);
for(File fi :s)
{
System.out.println("名字:"+fi.getName()+"长度:"+fi.length());
}
}
public static void listDemo()
{
File f = new File("c:\\"); 再看看!!!!!!!!!!!!!!?????????
//如果此抽象路径名不表示一个目录,那么此方法将返回 null。
//否则返回一个字符串数组,每个数组元素对应目录中的每个文件或目录。
//表示目录本身及其父目录的名称不包括在结果中。每个字符串是一个文件名,
//而不是一条完整路径。
String[] names = f.list(); //调用list方法的file对象必须是封装了一个目录。该目录还必须存在。
for(String name : names)
{
System.out.println(name);//把C盘中所有文件名字打印出来(包含隐藏文件)
}
}
}