--------------------- android培训、java培训、期待与您交流! ----------------------
一丶IO介绍
/*
1.用来处理设备之间的数据传输,java对数据的操作是通过流的方式
2.流按操作数据分为:字节流和字符流
|--按照流向分为:输入流和输出流
3.字节流的抽象基类:inputStream,OutputStream
|--字符流的抽象基类:Reader,Writer
*/
4、FileReader
package study_note_18;
import java.io.*;
/*
*1.第一种方式
*/
public class FileReaderDemo
{
public static void main(String[] args) throws IOException
{
// 创建一个文件读取流对象,和指定名称的文件相关联
// 要保证该文件是已经存在的,如果不存在,会发生FileNotFoundException
FileReader fr = new FileReader("demo.txt");
// 调用读取流对象的read方法,read方法一次读一个字符,而且会自动往下读
// 读到末尾会返回-1
// int ch=fr.read();
//
// System.out.println("ch:"+(char)ch);
//
// int ch1=fr.read();
//
// System.out.println("ch1:"+(char)ch1);
// while(true)
// {
// int ch=fr.read();
// if(ch==-1)
// break;
// System.out.println("ch="+(char)ch);
// }
int ch = 0;
while ((ch = fr.read()) != -1)
{
System.out.println("ch=" + (char) ch);
}
fr.close();
}
}
5、FileWriter
package study_note_18;
import java.io.*;
/*
*1.字符流
*/
public class FileWriteDemo
{
public static void main(String[] args) throws Exception
{
// 创建一个FileWriter对象,该对象被初始化的同时必须要明确被操作的文件
// 而且该文件会被创建到指定目录下,如果该目录下已有同名文件,将被覆盖
FileWriter fw = new FileWriter("demo.txt");
// 调用write方法,将字符串写入到流中
fw.write("abcde");
// 刷新流对象中的缓冲中的数据,将数据刷到目的地中
fw.flush();
// 关闭流资源,但是关闭之前会刷新一次内部的缓冲的数据,将数据刷到目的地中
// 和flush的区别 ,流可以继续使用,close刷新后,会将流关闭
fw.close();
fw.write("haha");
}
}
二丶流操作的基本规律
/*
1、明确源和目的
|--源:输入流--InputStream Reader
|--目的:输出流--OutputStream Writer
2、操作的数据是否是文本
|--是:字符流
|--不是:字节流
3、当体系明确后,再明确要使用哪个具体的对象
|--通过设备进行区分
|--源设备:内存,硬盘,键盘
|--目的设备:内存,硬盘,控制台
4、示例1
|--将一个文本文件数据存储到另一个文件中--复制文件
|--源,因为是源,所以使用读取流--InputStream Reader
|--因为是文本文件,所以使用Reader
|--明确设备:硬盘上的一个文件
|--则Reader体系中可以操作文件的对象时FileReader
|--是否需要提高效率:是--Reader体系中缓冲区:BufferedReader
FileReader fr=nwe FileReader("a.txt");
BufferedReader bufr=new BufferedReader(fr);
|--目的:--OutputStream Writer
|--因为是文本所以使用Writer
|--明确设备:硬盘上的一个文件
|--则Writer体系中可以操作文件的对象时FileWriter
|--是否需要提高效率:是--Reader体系中缓冲区:BufferedWriter
FileWriter fw=nwe FileWriter("b.txt");
BufferedWriter bufw=new BufferedWriter(fw);
5、示例2
|--将键盘录入的数据保存到一个文件中
|--源:--InputStream Reader
|--因为是文本文件,所以使用Reader
|--设备:键盘--System.in
|--System.in字节流,为了键盘文本数据操作方便,则将System.in转成Reader
|--使用Reader体系中的InputStreamReader
InputStreamReader isr=new InputStreamReader(System.in);
|--是否需要提高效率:是--Reader体系中缓冲区:BufferedReader
BufferedReader bufr=new BufferedReader(isr);
|--目的:--OutputStream Writer
|--因为是文本所以使用Writer
|--明确设备:硬盘上的一个文件
|--则Writer体系中可以操作文件的对象时FileWriter
FileWriter fw=nwe FileWriter(cb.txt");
|--是否需要提高效率:是--Reader体系中缓冲区:BufferedWriter
BufferedWriter bufw=new BufferedWriter(fw);
6、扩展
|--把录入的数据按照指定的编码表(utf-8)存到文件中
|--源:--InputStream Reader
|--因为是文本文件,所以使用Reader
|--设备:键盘--System.in
|--System.in字节流,为了键盘文本数据操作方便,则将System.in转成Reader
|--使用Reader体系中的InputStreamReader
InputStreamReader isr=new InputStreamReader(System.in);
|--是否需要提高效率:是--Reader体系中缓冲区:BufferedReader
BufferedReader bufr=new BufferedReader(isr);
|--目的:--OutputStream Writer
|--因为是文本所以使用Writer
|--明确设备:硬盘上的一个文件
|--则Writer体系中可以操作文件的对象时FileWriter
|--FileWriter是使用默认编码表GBK,现需要加入指定编码表utf-8,指定编码表只有转换流可以
|--所以要使用OutputStreamWriter
OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("d.txt"),"UTF-8");
|--是否需要提高效率:是--Reader体系中缓冲区:BufferedWriter
BufferedWriter bufw=new BufferedWriter(osw);
7、转换流:字符和字节之间的桥梁,通常涉及到字符编码转换时使
*/
8、BufferedReader
package study_note_19;
import java.io.*;
/*
*1.readLine()方法一次读取一行,方便对于文本数据的获取,当返回空 时,说明已经读到末尾
* |--返回回车符之前的内容,不包括回车符
*/
public class BufferedReaderDemo
{
public static void main(String[] args) throws IOException
{
// 创建一个读取流对象和文件相关联
FileReader fr = new FileReader("buf.txt");
// 为了提高效率,加入缓冲技术,将字符读取流对象作为参数传递给缓冲对象的构造函数
BufferedReader bufr = new BufferedReader(fr);
String line = null;
while ((line = bufr.readLine()) != null)
{
System.out.println(line);
}
// String s1=bufr.readLine();
//
// System.out.println("s1:"+s1);
bufr.close();
}
}
9、BufferedWriter
package study_note_19;
import java.io.*;
/*
*1.缓冲区的出现是为了提高流的操作效率,所以在创建缓冲区之前,必须要先有流对象
*2.newLine()方法可以跨平台,起到换行的作用
*/
public class BufferedWriterDemo
{
public static void main(String[] args) throws IOException
{
// 创建一个字符写入流对象
FileWriter fw = new FileWriter("buf.txt");
// 为了提高字符写入流的效率,加入了缓冲技术
// 只要将需要被提高效率的流对象作为参数传递给缓冲的构造函数即可
BufferedWriter bufw = new BufferedWriter(fw);
for (int x = 1; x < 5; x++)
{
bufw.write("abcde" + x);
bufw.newLine();// 换行,可以跨平台
// 只要用到缓冲区,就要记得刷新
bufw.flush();
}
// 关闭缓冲区就是在关闭缓冲区中的流对象
bufw.close();
}
}
10、字节流
package study_note_19;
import java.io.*;
/*
*1.字符流
* |--FileReader
* |--FileWriter
* |--BufferedReader
* |--BufferedWtriter
*2.字节流
* |--InputStream:读
* |--OutputSteam:写
* |--BufferedInputStream
* |--BufferedOutputStream
*
*
*
*需求:想要操作图片数据,这时就要用到字节流
*
*/
public class FileStream
{
public static void main(String[] args) throws IOException
{
writeFile();
readFile_1();
readFile_2();
readFile_3();
}
public static void writeFile() throws IOException
{
FileOutputStream fos = new FileOutputStream("fos.txt");
fos.write("abcde".getBytes());// 只能写字符或者字符数组,所以需要转换
fos.close();
}
// 一次读一个字符
public static void readFile_1() throws IOException
{
FileInputStream fis = new FileInputStream("fos.txt");
int ch = 0;
while ((ch = fis.read()) != -1)
{
System.out.println((char) ch);
}
fis.close();
}
public static void readFile_2() throws IOException
{
FileInputStream fis = new FileInputStream("fos.txt");
byte[] buf = new byte[1024];
int len = 0;
while ((len = fis.read(buf)) != -1)
{
System.out.println(new String(buf, 0, len));
}
fis.close();
}
/*
* 数据不是太大可以用这种方法,如果超过内存就会发生内存溢出
*/
public static void readFile_3() throws IOException
{
FileInputStream fis = new FileInputStream("fos.txt");
// int num=fis.available();//如果有第二行则打印出来会含有\r和\n两个字符
byte[] buf = new byte[fis.available()];// 定义一个刚刚好的缓冲区,不用再循环了
fis.read(buf);
// System.out.println("num="+num);
System.out.println(new String(buf));
fis.close();
}
}
11、自定义缓冲区
package study_note_19;
import java.io.*;
/*
*自定义缓冲区
*1.定义数组
*2.定义指针
*3.定义计数器
*/
public class MyBufferedInputStream
{
private InputStream in;
private byte[] buf = new byte[1024];
private int pos = 0, count = 0;// 定义指针和计数器
MyBufferedInputStream(InputStream in)
{
this.in = in;
}
// 一次读取一个字节,从缓冲区(字节数组)读
public int myRead() throws IOException
{
// 通过in对象读取硬盘上数据,并存储在buf中
if (count == 0)
{
count = in.read(buf);// 记录个数
if (count < 0)
return -1;
pos = 0;// 重新写入数据时,需要从o开始取出
byte b = buf[pos];// 根据指针获取元素
count--;// 取出一个数量自减
pos++;// 一次往下取,指针自增
/*
* 第一个字节打印会出现-1,因为会出现11111111转成int类型之后还是-1,会导致程序停止
* 则&255会让byte转成int时高位补0,就会避免出现-1的情况
*/
return b & 255;
}
else if (count > 0)
{
byte b = buf[pos];
count--;
pos++;
return b & 255;
}
return -1;
}
public void myClose() throws IOException
{
in.close();
}
}
三丶装饰设计模式
/*
1、装饰模式比继承要灵活,避免了继承体系的臃肿,而且降低了类与类之间的关系
2、装饰类因为增强已有对象,具备的功能和已有的是相同的,只不过提供了更强的功能
|--所以装饰类和被装饰类通常都是属于一个体系中的
*/
3、示例
package study_note_19;
/*
*1.装饰设计模式 :
* |--当想要对已有的对象进行功能增强时,可以定义类,将已有对象传入,基于已有的功能
* |--并提供加强功能,那么自定义的该类就成为装饰类
*2.装饰类通常会通过构造方法接受被装饰的对象,并基于被装饰的对象的功能,提供更强的功能
*/
class Person
{
public void chifan()
{
System.out.println("吃饭");
}
}
// 基于原来的功能提供增强功能
class SuperPerson
{
private Person p;
SuperPerson(Person p)
{
this.p = p;
}
public void superChifan()
{
System.out.println("开胃酒");
p.chifan();// System.out.println("吃饭");
System.out.println("甜点");
System.out.println("来一根");
}
}
public class PersonDemo
{
public static void main(String[] args)
{
Person p = new Person();
// p.chifan();
SuperPerson sp = new SuperPerson(p);
sp.superChifan();
}
}
四丶File的常见操作方法
package study_note_20;
import java.io.*;
/*
*类常见方法
* |--创建:boolean createNewFile()
* |--在指定位置创建文件,如果该文件已经存在,则不创建,返回false
* |--与输出流不一样,输出流对象一建立创建文件,如果文件已存在,会覆盖
* |--boolean mkdir();创建文件夹,只能创建一级目录
* |--boolean mkdirs();创建文件夹,创建多级目录
* |--删除:
* |--boolean delete();删除失败返回false
* |--void deleteOnExit();程序退出时删除
* |--判断:
* |--canExecute();
* |--boolean exists();文件是否存在
* |--isFile();判断是否是文件
* |--isDirectory();判断是否是文件夹
* |--isHidden();判断文件是否是隐藏的
* |--获取:
* |--getName();
* |--getPath();获取路径
* |--getParent();返回绝对路径中的文件父目录,如果获取的是相对路径,返回null
* |--如果相对路径中有上一层目录,那么该目录就是返回结果
* |--getAbsolutePath();获取绝对路径
* |--long lastModified();文件最后一次被修改的时间
* |--long length();
*
*/
public class FileDemo
{
public static void main(String[] args) throws IOException
{
// consMethod();
// method_2();
// method_3();
method_4();
}
public static void method_4() throws IOException
{
File f = new File("c:\\a.txt");
sop("path:" + f.getPath());
sop("absPath:" + f.getAbsolutePath());
sop("parent:" + f.getParent());
}
public static void method_3() throws IOException
{
File f = new File("file.txt");
// f.createNewFile();
f.mkdirs();
// 在判断文件对象是否是文件或者目录时,必须先判断该文件对象封装的内容是否存在
// 通过exists判断
sop("dir:" + f.isDirectory());
sop("dir:" + f.isFile());
}
public static void method_2() throws IOException
{
File f = new File("file.txt");
sop("exists:" + f.exists());
// ("execute:" + f.canExecute());
// 川建文件夹
File dir = new File("abc");
sop("mkdir:" + dir.mkdir());
}
public static void method_1() throws IOException
{
File f = new File("file.txt");
sop("create:" + f.createNewFile());
}
// 创建File对象
public static void consMethod()
{
// 将文件封装成对象,将已有的和未出现的文件或者文件夹封装成对象
File f1 = new File("c:\\abc\\a.txt");
File f2 = new File("c:\\abc", "b.txt");
File d = new File("c:\\abc");
File f3 = new File(d, "c.txt");
File f4 = new File("c:" + File.separator + "abc\\a.txt");// File.separator可以根据系统的不同获取该系统的分隔符,这里相当于“\\”
sop("f1:" + f1);
sop("f2:" + f2);
sop("f3:" + f3);
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
1、打印流
package study_note_20;
import java.io.*;
/*
*打印流:
* |--打印流提供了打印法,可以将各种数据类型的数据原样打印
*字节打印流:PrintStream
* |--构造函数可以接收的参数类型
* |--file对象--File
* |--字符串路径--String
* |--字节输出流--OutputStream
*
*字符打印流:PrintWriter
*|--构造函数可以接收的参数类型
* |--file对象--File
* |--字符串路径--String
* |--字节输出流--OutputStream
* |--字符输出流--Writer
*/
public class PrintStreamDemo
{
public static void main(String[] args)throws IOException
{
BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));
PrintWriter out=new PrintWriter(System.out,true);
String line=null;
while((line=bufr.readLine())!=null)
{
if("over".equals(line))
break;
out.println(line.toUpperCase());
//out.flush();
}
out.close();
bufr.close();
}
}
2、递归
package study_note_20;
import java.io.*;
/*
*列出指定目录下文件或者文件夹,包含子目录中的内容,也就是列出指定目录下所有内容
*
*因为目录中还有目录,只要使用同一个列出目录功能的函数完成即可,在列出过程中出现的
*还是目录的话,还可以再次调用本功能,也就是函数自身调用自身
*这种表现形式,或者编程手法,称为递归
*
*递归注意事项
*1、限定条件
*
*2、注意递归次数,尽量避免内存溢出
*/
public class FileDemo3
{
public static void main(String[] args)
{
File dir = new File("d:\\Linux");
showDir(dir, 0);
int n = getSum(10);// 数值不能过大,运算过程中不断开辟内存空间,过大会导致内存溢出
System.out.println("n=" + n);
}
public static String getLevel(int level)
{
StringBuilder sb = new StringBuilder();
sb.append("|--");
for (int x = 0; x < level; x++)
{
// sb.append("|--");
sb.insert(0, " ");
}
return sb.toString();
}
// 递归求和
public static int getSum(int n)
{
if (n == 1)
return 1;
else
return n + getSum(n - 1);
}
public static void showDir(File dir, int level)
{
System.out.println(getLevel(level) + dir.getName());
level++;
File[] files = dir.listFiles();
for (int x = 0; x < files.length; x++)
{
if (files[x].isDirectory())
showDir(files[x], level);
else
System.out.println(getLevel(level) + files[x]);
}
}
}
五丶编码表
/*
1、ASCII:美国标准信息交换吗--用一个字节的7为可以表示
2、ISO8859-1:拉丁码表,欧洲码表--用一个字节的8为表示
3、GB2132:中国的中文编码表
4、GBK:中国的中文编码表升级,融合了更多的中文字字符号1111
5、Unicode:国际标准码,融合了多种文字--所有文字都用两个字节表示,java就是使用的这种编码
6、UTF-8:最多用三个字节表示一个字符
*/
--------------------- android培训、java培训、期待与您交流! ----------------------