一、流是什么及流关系图
流(Stream)是什么-----流就是一系列的数据
当不同介质之间有数据交互的时候,JAVA就使用流来实现。
数据源可以是文件,还可以是数据库,网络甚至是其他的程序
比如:
InputStream是字节输入流---从文件读取数据到程序中
OutputStream是字节输出流---从程序中写数据到文件中
用于以字节的形式读取和写入数据
?
?二、文件对象
文件常用办法1
File f = new File("d:/LOLFolder/LOL.exe");
System.out.println("当前文件是:" +f);
//文件是否存在
System.out.println("判断是否存在:"+f.exists());
//是否是文件夹
System.out.println("判断是否是文件夹:"+f.isDirectory());
//是否是文件(非文件夹)
System.out.println("判断是否是文件:"+f.isFile());
//文件长度
System.out.println("获取文件的长度:"+f.length());
//文件最后修改时间
long time = f.lastModified();
Date d = new Date(time);
System.out.println("获取文件的最后修改时间:"+d);
//设置文件修改时间为1970.1.1 08:00:00
f.setLastModified(0);
//文件重命名
File f2 =new File("d:/LOLFolder/DOTA.exe");
f.renameTo(f2);
System.out.println("把LOL.exe改名成了DOTA.exe");
注意: 需要在D:\\LOLFolder确实存在一个LOL.exe,\r\n才可以看到对应的文件长度、修改时间等信息
?文件常用办法2
File f = new File("d:/LOLFolder/skin/garen.ski");
// 以字符串数组的形式,返回当前文件夹下的所有文件(不包含子文件及子文件夹)
f.list();
// 以文件数组的形式,返回当前文件夹下的所有文件(不包含子文件及子文件夹)
File[]fs= f.listFiles();
// 以字符串形式返回获取所在文件夹
f.getParent();
// 以文件形式返回获取所在文件夹
f.getParentFile();
// 创建文件夹,如果父文件夹skin不存在,创建就无效
f.mkdir();
// 创建文件夹,如果父文件夹skin不存在,就会创建父文件夹
f.mkdirs();
// 创建一个空文件,如果父文件夹skin不存在,就会抛出异常
f.createNewFile();
// 所以创建一个空文件之前,通常都会创建父目录
f.getParentFile().mkdirs();
// 列出所有的盘符c: d: e: 等等
f.listRoots();
// 刪除文件
f.delete();
// JVM结束的时候,刪除文件,常用于临时文件的删除
f.deleteOnExit();
三、字节流
字节输入流: InputStream,同时也是抽象类,只提供方法声明,不提供方法的具体实现 字节输出流:OutputStream,同时也是抽象类,只提供方法声明,不提供方法的具体实现
ASCII码----所有数据存放在计算机中都是以数字的形式存放的,所以字母就需要转化为数字才能够存放
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.I0Exception;
public class LxStream{
public static void main(String[] args){
//输入输出流必须先有文件
try{//这里文件内容是AB,对应得ASCII分别的65、66
File a=new File("d:/wx.txt");
//创建基于文件的输入流,通过这个输入流,就可以把数据从硬盘读取到Java的虚拟机中,也就是读取到内存中
FileInputStream b=new FileInputStream(a);
//创建字节数组,长度就是文件长度
byte[] all=new byte[(int)a.length()];
//以字节流的形式读取文件所有内容
b.read(all);
for(byte c:all){
打印出来是65 66
System.out.println(c);
}
//每次使用完流,都应该进行关闭
b.close();}catch(IOException e){
e.printStackTrace();
}
try{// 准备文件zxx.txt其中的内容是空的
File m=new File("d:/zxx.txt");
FileOutputStream n=new FileOutputStream(m);
// 准备长度是2的字节数组,用88,89初始化,其对应的字符分别是X,Y
byte []date=new byte{88,89};
//把数据写入到输出流
n.write(date);
n.close();} catch(IOException e){
e.printStackTrace;
}
}
}
? ? ? ? ? 字节流又分为对象流和数据流
1、对象流----意思是可以直接把一个对象以流的形式传输给其他的介质,比如硬盘
? ? ? ? ? ? 一个对象以流的形式进行传输,叫做序列化。该对象所对应的类必须是Serializable接口
? ? ? ? ? ? Serializable接口的作用理解
? ? ? ? ? ? ? 这是一个接口,当一个类实现这个接口后,这个类就变成了一个可序列化的类,它就可以被写入流,保存起来,然后也可以用流读取,反序列化。
一般情况下,一个对象会随着程序的执行完成而消失,而有时我们需要保存下来一个对象的状态,这个时候就可以把它序列化
第一个
package charactor;
import java.io.Serializable;
//要把Hero对象直接保存在文件上,务必让Hero类实现Serializable接口
public class hero implements Serializable{
private static final long serialVersionUID=1L; //表示这个类当前的版本,如果有了变化,比如新设计了属性,就应该修改这个版本号
public String name;
public float hp;
}
//第二个
package liu;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import charactor.hero;
public class hero1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
hero h=new hero();
h.name="garen";
h.hp=464;
File a=new File("d:/wx.txt");//准备文件用于保存对象
try(//创建对象输入流
FileInputStream b=new FileInputStream(a);
ObjectInputStream c=new ObjectInputStream(b);
//创建对象输出流
FileOutputStream m=new FileOutputStream(a);
ObjectOutputStream n=new ObjectOutputStream(m);){
n.writeObject(h);
hero h2=(hero)c.readObject();
System.out.println(h2.name+h2.hp);
}catch(IOException e){
e.printStackTrace();
}catch(ClassNotFoundException e){
e.printStackTrace();
}
}
}
2、数据流
DataInputStream(数据输入流)
DataOutputStream(数据输出流)
使用数据流的writeUTF()和readUTF() 可以进行数据的格式化顺序读写
下面的代码展现的是用DateOutputStream写出以及用DateInputStream读入
package liu;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class ShuJu {
private static void write(){
File f=new File("d:/wx.txt");
try(FileOutputStream a=new FileOutputStream(f);
DataOutputStream b=new DataOutputStream(a);){
b.writeBoolean(true);
b.writeInt(400);
b.writeUTF("4644 woaini");
}catch(IOException e){
e.printStackTrace();
}
}
private static void read(){
File f=new File("d:/wx.txt");
try(
FileInputStream m=new FileInputStream(f);
DataInputStream n=new DataInputStream(m);){
boolean sj1=n.readBoolean();
int sj2=n.readInt();
String sj3=n.readUTF();
System.out.println("布尔值是:"+sj1);
System.out.println("整数是:"+sj2);
System.out.println("字符串是:"+sj3);
} catch(IOException e){
e.printStackTrace();
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
write();
read();
}
}
?总结:对象流是以对象进行数据传输;而数据流是以数据来传输
四、关闭流的方式----三种办法
所有的流,无论是输入流还是输出流,使用完毕之后,都应该关闭。 如果不关闭,会产生对资源占用的浪费。 当量比较大的时候,会影响到业务的正常开展。
1、在try的作用域里关闭流(有隐患),前面代码就是用的这种方式。但是这样有弊端,如果发生异常,就不会执行关闭流代码,造成资源浪费。
2、在finally中关闭(标准的关闭流方式),
? ? ? 1. 首先把流的引用声明在try的外面,如果声明在try里面,其作用域无法抵达finally. ? ? ? 2. 在finally关闭之前,要先判断该引用是否为空 ? ? ? 3. 关闭的时候,需要再一次进行try catch处理
public static void main(String[] args) {
File a = new File("d:/wx.txt");
InputStream b=null;
try{b=new InputStream(a);
byte []all=new byte[(int)a.length()];
b.read(all);
for(byte c:all){
System.out println(c);}
catch(IOException e){
e.printStackTrace();
}finally{
if(null!=null)try{
b.close();
}catch(IOException e){
e.printStackTrace();
}
}
}
3、使用try()的方式---把流定义在try()里,try,catch或者finally结束的时候,会自动关闭
public static void main(String[] args) {
File a = new File("d:/wx.txt");
try(InputStream b=new InputStream(a)){
byte[] all=new byte[(int)a.length()];
b.read(all);
for(byte m:all){
System.out println(m);
}
}catch(IOException e){
e.ptintStackTrace();
}
}
? ? ?五、字符流
? ? ? ? ? Reader字符输入流 ? ? ? ? ? Writer字符输出流 ? ? ? ? ? 专门用于字符的形式读取和写入数据
以下代码练习写入和读取
package liu;
import java.io.File;
import java.io.FileWriter;
import java.io.FileReader;
import java.io.IOException;
public class zfl {
public static void main(String[] args) {
// TODO Auto-generated method stub
write();
read();
}
private static void read(){
File f=new File("d:/wx.txt");
try(FileWriter a=new FileWriter(f);){
String shuju="woaini";
char []cs=shuju.toCharArray();
a.write(cs);
}catch(IOException e){
e.printStackTrace();
}
}
private static void write(){
File f=new File("d:/wx.txt");
try(FileReader m=new FileReader(f);){
char[]ch=new char[(int)f.length()];
m.read(ch);
for(char n:ch){
System.out.print(n);
}}catch(IOException e){
e.printStackTrace();
}
}
}
? ? 缓冲流-----可以减少IO操作
? ? ? ? ? ? ? 缓存流在读取的时候,会一次性读较多的数据到缓存中,以后每一次的读取,都是在缓存中访问,直到缓存中的数据读取完毕,再到硬盘中读取。缓存字符输入流 BufferedReader 可以一次读取一行数据
? ? ? ? ? ? ? 缓存流在写入数据的时候,会先把数据写入到缓存区,直到缓存区达到一定的量,才把这些数据,一起写入到硬盘中去。PrintWriter 缓存字符输出流, 可以一次写出一行数据
? ? ? ? ? ? ??有的时候,需要立即把数据写入到硬盘,而不是等缓存满了才写出去。 这时候就需要用到flush
代码比较复制代码
见如下代码
package liu;
import java.io.File;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.io.FileReader;
import java.io.BufferedReader;
import java.io.IOException;
public class hcl {
private static void write(){
File f=new File("d:/wx.txt");
try(FileReader a=new FileReader(f);//创建文件字符流
PrintWriter b=new PrintWriter(a);/*缓冲流必须建立在一个存在的流基础上*/){
b.println("woaini");
b.flush(); //强制把缓存中的数据写入硬盘,无论缓存是否已满
b.println("dashabi");
b.println("aiqinhai");
}catch(IOException e){
e.printStackTrace();
}
}
private static void read(){
File f=new File("d:/wx.txt");
try(FileReader m=new FileReader(f);//创建文件字符流
BufferedReader n=new BufferedReader(m);/*缓存流必须建立在一个存在的流的基础上*/){
while(true){
String line=n.readLine();
if(null==line)
break;
System.out.println(line);
}
}catch(IOException e){
e.printStackTrace();
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
write();
read();
}
}
六、中文问题
? 1、编码概念
计算机存放数据只能存放数字,所有的字符都会被转换为不同的数字。 就像一个棋盘一样,不同的字,处于不同的位置,而不同的位置,有不同的数字编号。 有的棋盘很小,只能放数字和英文 有的大一点,还能放中文 有的“足够”大,能够放下世界人民所使用的所有文字和符号

?
经常接触的编码方式有如下几种: ISO-8859-1 ASCII?数字和西欧字母 GBK GB2312 BIG5?中文 UNICODE?(统一码,万国码)
其中 ISO-8859-1 包含 ASCII GB2312 是简体中文,BIG5是繁体中文,GBK同时包含简体和繁体以及日文。 UNICODE 包括了所有的文字,无论中文,英文,藏文,法文,世界所有的文字都包含其中,而UTF是简化版的UNICODE
?
七、System.in-------可以从控制台输入数据
例一直使用的Scanner
|