File类:
该类的出现是对文件系统中的文件以及文件夹进行对象的封装。可以通过对象的思想来操作文件以及文件夹。
1. 构造函数:
File(String filename):将一个字符串路径(相对或者绝对)封装成File对象,该路径是可以存在的,也是可以不存在的。
File(Stringparent,String child);
File(Fileparent,String child);
2. 特别的字段:separator:跨平台的目录分隔符
eg.File file = newFile(“C:”+File.separator+”abc”+File.separator+”a.txt”);
3. 常见方法:
1) 创建:
boolean createNewFile() throwsIOException:创建文件,如果被创建的文件已经被创建,则不再创建。
boolean mkdir():创建文件夹。
boolean mkdirs():创建多级文件夹。
2) 删除:
boolean delete():可用于删除文件或者文件夹。
注意:对于文件夹只能删除不带内容的空文件夹;则对于带内容的文件夹,不可以直接删除,必须要从里往外依次删除。
void deleteOnExit():删除动作将在系统完成时触发。无论是否发生异常,系统在退出时执行删除动作。
3) 判断:
boolean canExecute():该文件是否能执行。
boolean canWrite():是否是可写文件
boolean canRead():是否是可读文件
boolean exists():判断文件或者文件夹是否存在。
boolean isFile():判断File对象中封装的是否是文件。
boolean isDirectory():判断File对象中封装的是文件夹。
boolean isHidden():判断文件或者文件夹是否隐藏,在获取硬盘文件或者文件夹时,对于系统目录中的文件,java是无法访 问的。所以遍历,可以避免遍历隐藏文件。
4) 获取:
String getName():获取文件或者文件夹的名称。
String getPath():File对象中封装的路径是什么,获取的就是什么。
String getAbsolutePath():无论File对象中封装的路径是什么,获取的都是绝对路径。
String getAbsoluteFile():也返回绝对路径,但是把绝对路径封装成了对象。
getParent():获取File对象封装文件或者文件夹的父目录。
注意:如果封装的相对路径,那么返回的是null;
long length():获取文件大小。
long lastModified():获取文件或者文件最后一次修改的时间
static File[] listRoots():获取的是被系统所用的有效盘符。
string[] list():获取指定目录下当前的文件以及文件夹名称。
string[] list(Filenamefilter): 可以根据指定的过滤器,过滤后的文件及文件夹名称。
File[] listFiles():获取指定目录下的文件以及文件夹对象。
5) 重命名:
renameTo(File):
File f1 = newFile("c:\\a.txt");
File f2 = newFile("c:\\b.txt");
f1.renameTo(f2);//将c盘下的a.txt文件改名为b.txt文件。
例子1:File类的基本方法的使用。
递归:
其实就是在使用一个功能过程中,又对该功能有需求。就出现了函数自身调用自身。
注意:
1,一定要限定条件,否则内存溢出。
2,使用递归时,调用次数不要过多,否则也会出现内存溢出。
例子2:想要列出指定目录下的文件以及文件夹中的文件(子文件)。
- package cn.itheima.day04;
- import java.io.File;
-
-
-
-
-
-
-
-
-
-
-
-
-
- public class FileDemo3 {
- public static void main(String[] args) {
- File dir = new File("F:\\Javajichu1\\JavaLianXi\\src\\cn\\itheima\\");
- showDir(dir,2);
-
-
-
- }
- public static String getLevel(int level){
- StringBuilder sb = new StringBuilder();
- sb.append("|--");
- for(int x = 0;x<level; x++){
-
- sb.insert(0, "| ");
-
- }
- return sb.toString();
- }
-
- public static void showDir(File dir,int level){
- sop(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{
- sop(getLevel(level)+files[x]);
- }
- }
- }
-
- public static void toBin(int num){
- if(num>0){
- toBin(num/2);
- sop(num%2);
-
- }
- }
-
- public static int getSum(int n){
- if(n==1)
- return 1;
- return n+getSum(n-1);
- }
- public static void sop(Object obj){
- System.out.println(obj);
- }
- }
例子3:删除一个带内容的目录。
- package cn.itheima.day04;
- import java.io.File;
-
-
-
-
-
-
- public class RemoveDir {
- public static void main(String[] args) {
- File file = new File("F:\\Javajichu1\\JavaLianXi\\src\\cn\\itheima\\day04\\aa");
- removeDir(file);
- }
-
- public static void removeDir(File dir) {
- File[] files = dir.listFiles();
- for (int x = 0; x < files.length; x++) {
- if(files[x].isDirectory())
- removeDir(files[x]);
- else
- System.out.println(files[x].toString()+":file:"+files[x].delete());
- }
- System.out.println(dir.toString()+":dir:"+dir.delete());
- }
- }
例子4:将一个指定目录下所有的java文件的绝对路径,存储到一个文本文件中,建立一个java文件的列表文件。
- package cn.itheima.day04;
- import java.io.BufferedWriter;
- import java.io.File;
- import java.io.FileWriter;
- import java.io.IOException;
- import java.util.ArrayList;
- import java.util.List;
-
-
-
-
-
-
-
-
-
-
-
- public class JavaFileList {
- public static void main(String[] args) throws IOException {
- File dir = new File("F:\\Javajichu1\\JavaLianXi\\src\\cn\\itheima\\");
- List<File> list = new ArrayList<File>();
- fileToList(dir,list);
- System.out.println(list.size());
- File file = new File("F:\\Javajichu1\\JavaLianXi\\src\\cn\\itheima\\day04\\","javaList.txt");
- writeToFile(list,file.toString());
- }
- public static void fileToList(File dir,List<File> list){
- File[] files = dir.listFiles();
- for (File file : files) {
- if(file.isDirectory()){
- fileToList(file, list);
- }else{
- if(file.getName().endsWith(".java")){
- list.add(file);
- }
- }
- }
- }
-
- public static void writeToFile(List<File> list,String javaListFile) throws IOException{
- BufferedWriter bufw=null;
-
- try {
- bufw = new BufferedWriter(new FileWriter(javaListFile));
- for (File f : list) {
- String path = f.getAbsolutePath();
- bufw.write(path);
- bufw.newLine();
- bufw.flush();
- }
- } catch (IOException e) {
- throw e;
- }finally{
- try {
- if(bufw!=null){
- bufw.close();
- }
- } catch (IOException e) {
- throw e;
- }
- }
- }
- }
例子5:利用Perperties类得到它里面存储的数据信息的值。
- package cn.itheima.day04;
- import java.util.Properties;
- import java.util.Set;
-
-
-
-
-
-
-
- public class PropertiesDemo {
-
- public static void main(String[] args) {
-
- setAndGet();
- }
-
- public static void setAndGet(){
- Properties properties = new Properties();
- properties.setProperty("zhangsan", "30");
- properties.setProperty("lisi", "39");
-
- String value = properties.getProperty("lisi");
-
- properties.setProperty("lisi", "89");
- Set<String> values = properties.stringPropertyNames();
- for (String s : values) {
- System.out.println(s+"::"+properties.getProperty(s));
- }
- }
- }
例子6:利用Properties类读取文件中的数据(数据格式为:键=值)存储到集合中,并读取到控制台上,并且可以修改文件中的数据。
例子7:用于记录应用程序运行的次数,如果使用次数已到,那么给出注册提示。
- package cn.itheima.day04;
- <pre>import java.io.File;
- import java.io.FileInputStream;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.util.Properties;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- public class RunCount {
- public static void main(String[] args) throws IOException {
- Properties properties = new Properties();
- FileInputStream fis=null;
- File file = new File("F:\\Javajichu1\\JavaLianXi\\src\\cn\\itheima\\day04\\count.txt");
- if(!file.exists())
- file.createNewFile();
- else
- fis = new FileInputStream(file);
- properties.load(fis);
- int count = 0;
- String value = properties.getProperty("time");
- if(value!=null){
- count = Integer.parseInt(value);
- if(count>=5){
- System.out.println("你好,你使用的次数已到,请注册后,使用。");
- }
- }
- count++;
- properties.setProperty("time", count+"");
- FileOutputStream fos = new FileOutputStream(file);
- properties.store(fos, "hello");
- fos.close();
- fis.close();
- }
IO包中常见的对象:
字节流:
FileInputStream
FileOutputStream
BufferedInputStream
BufferedOutputStream
字符流:
FilerReader
FileWriter
BufferedReader
BufferedWriter
转换流:
InputStreamReader
OutputStreamWriter
文件对象:
File
打印流:
PrintStream
PrintWriter
注意:所有的带File的流对象都可以直接操作File对象。
IO包中的其他对象:
1.打印流
PrintStream:是一个字节打印流,System.out对应的类型就是PrintStream.
它的构造函数可以接收三种数据类型。
1. 字符串路径。
2. File对象
3. OutputStream
PrintWriter:是一个字符打印流,构造函数可以接收四种类型的值。
1. 字符串路径。
2. File对象。
对于1.2类型的数据,还可以指定编码表。也就是字符集。
3. OutputStream
4. Writer
对于3.4类型的数据,可以指定自动刷新。
注意:该自动刷新的值为true时,只有三个方法可用:println,printf,format.
//如果想要既有自动刷新,又可执行编码。如何完成流对象的包装呢?
PrintWriter pw = new PrintWriter(newOutputStreamWriter(new FileOutputStream(“a.txt”)));
//如果想要提高效率,还要使用打印方法。
PrintWrterpw = newPrintWriter(new BufferdWriter(new OutputSteamWriter(new FileOutputStream("a.txt"),"utf-8")),true);
例子8:用打印流对象,用打印流接收用户在控制台输入的数据,然后用打印流输出到控制台上或者一个文件中
- package cn.itheima.day04;
- import java.io.BufferedReader;
- import java.io.BufferedWriter;
- import java.io.FileWriter;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.io.PrintWriter;
- public class PrintStreamDemo {
- public static void main(String[] args) throws IOException {
- BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
-
- PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("F:\\Javajichu1\\JavaLianXi\\src\\cn\\itheima\\day04\\a.txt")),true);
- String line=null;
- while((line=br.readLine())!=null){
- if("over".equals(line)){
- break;
- }
- out.println(line.toUpperCase());
-
- }
- out.close();
- br.close();
- }
- }
2.序列流,也成合并流。
SequenceInputStream:
特点:可以将多个读取流合并成一个流,这样操作起来很方便。
原理:其实就是将每一个读取流对象存储到一个集合中,最后一个流对象结尾作为这个流的结尾。
两个构造函数:
1. SequenceInputStream(InputStreamin1,InputStream in2):可以将两个读取流合并成一个流。
2. SequenceInputStream(Enumeration<?Extents InputStream> en):可以将枚举中的多个流合并成一个流。
例子9:将3个读取流文件合并成一个读取流文件。
- package cn.itheima.day04;
- import java.io.FileInputStream;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.SequenceInputStream;
- import java.util.Enumeration;
- import java.util.Vector;
- public class SequenceDemo {
-
- public static void main(String[] args) throws IOException {
- Vector<FileInputStream> v = new Vector<FileInputStream>();
- v.add(new FileInputStream("F:\\Javajichu1\\JavaLianXi\\src\\cn\\itheima\\day04\\1.txt"));
- v.add(new FileInputStream("F:\\Javajichu1\\JavaLianXi\\src\\cn\\itheima\\day04\\2.txt"));
- v.add(new FileInputStream("F:\\Javajichu1\\JavaLianXi\\src\\cn\\itheima\\day04\\3.txt"));
- Enumeration<FileInputStream> en = v.elements();
- SequenceInputStream sis = new SequenceInputStream(en);
- FileOutputStream fos = new FileOutputStream("F:\\Javajichu1\\JavaLianXi\\src\\cn\\itheima\\day04\\4.txt");
- byte[] buf = new byte[1024];
- int len = 0;
- while((len=sis.read(buf))!=-1){
- fos.write(buf,0,len);
- }
- fos.close();
- sis.close();
- }
- }
作用:可以用于多个数据的合并。
注意:因为Enumeration是Vector中特有的取出方式。而Vector被ArrayList取代。所以要使用ArrayList集合效率更高一些。
那么如何获取Enumeration呢?
- ArrayList<FileInputStream > al = new ArrayList<FileInputStream>();
- for(int x=1; x<4; x++)
- al.add(new FileInputStream(x+".txt"));
- Iterator<FileInputStream> it = al.iterator();
- Enumeration<FileInputStream> en = new Enumeration<FileInputStream>(){
- public boolean hasMoreElements(){
- return it.hasNext();
- }
- public FileInputStream nextElement(){
- return it.next();
- }
- };
-
- SequenceInputStream sis = new SequenceInputStream(en);
-
- FileOutputStream fos = new FileOutputStream("4.txt");
- byte[] buf = new byte[1024*4];
- int len = 0;
- while((len=sis.read(buf))!=-1){
- fos.write(buf,0,len);
- }
- fos.close();
- sis.close();
例子10.文件的切割和合并。
- package cn.itheima.day04;
- import java.io.FileInputStream;
- import java.io.FileNotFoundException;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.SequenceInputStream;
- import java.util.ArrayList;
- import java.util.Enumeration;
- public class SplitFile {
- public static void main(String[] args) throws IOException {
-
- merge();
- }
-
- public static void merge() throws IOException{
- ArrayList<FileInputStream> aList = new ArrayList<FileInputStream>();
- for(int x = 1;x<=4;x++){
- aList.add(new FileInputStream("F:\\Javajichu1\\JavaLianXi\\src\\cn\\itheima\\day04\\pic\\"+x+".part"));
- }
- final java.util.Iterator<FileInputStream> it = aList.iterator();
- Enumeration<FileInputStream> en = new Enumeration<FileInputStream>() {
- public boolean hasMoreElements() {
- return it.hasNext();
- }
- public FileInputStream nextElement() {
- return it.next();
- }
- };
- SequenceInputStream sis = new SequenceInputStream(en);
- FileOutputStream fos = new FileOutputStream("F:\\Javajichu1\\JavaLianXi\\src\\cn\\itheima\\day04\\pic\\0.png");
- byte[] buf = new byte[1024];
- int len=0;
- while((len=sis.read(buf))!=-1){
- fos.write(buf,0,len);
- }
- fos.close();
- sis.close();
- }
-
- public static void splitFile() throws IOException{
- FileInputStream fis = new FileInputStream("F:\\Javajichu1\\JavaLianXi\\src\\cn\\itheima\\day04\\1.png");
- FileOutputStream fos = null;
- byte[] buf = new byte[1024*1024];
- int len =0;
- int count =1;
- while((len=fis.read(buf))!=-1){
- fos = new FileOutputStream("F:\\Javajichu1\\JavaLianXi\\src\\cn\\itheima\\day04\\pic\\"+(count++)+".part");
- fos.write(buf,0,len);
- fos.close();
- }
- if(fos!=null){
- fos.close();
- }
- fis.close();
- }
- }
操作对象的流:
ObjectInputStream
ObjectOutputStream
可以通过这两个流对象直接操作已有的对象,并将对象进行本地持久化存储。存储后的对象可以进行网络传输。
两个对象的特有方法:
ObjectInputStream
Object readObject():该方法抛出异常:ClassNotFountException
ObjectOutputStream
void writeObject(Object):被写入的对象必须实现一个接口:Serializable,否则会抛出异常:NotSerializableException
Serializable:该接口其实就是一个没有方法的标记接口。
用于给类指定一个UID。该UID是通过类中的可序列化成员的数字签名运出来的一个long型的值。只要是这些成员没有变化,那么该值每次运算都一样。该值用于判断被序列化的对象和类文件是否兼容。如果被序列化的对象需要被不同的类版本所兼容。可以在类中自定义UID。
定义方式:static final long serialVersionUID = 42L;
注意:对应静态的成员变量,不会被序列化。
对应非静态也不想被序列化的成员而言,可以通过transient关键字修饰。
例子11.利用ObjectInputStream和ObjectOutputStream,写入和读取文件中的数据
- package cn.itheima.day05;
- import java.io.Serializable;
- public class Person implements Serializable{
- private static final long serialVersionUID = 42L;
- private String name;
- transient int age;
- static String country="cn";
- public Person() {
- super();
- }
- public Person(String name, int age,String country) {
- super();
- this.name = name;
- this.age = age;
- this.country=country;
- }
- public static String getCountry() {
- return country;
- }
- public static void setCountry(String country) {
- Person.country = country;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- @Override
- public String toString() {
- return "Person [name=" + name + ", age=" + age + ",country=" + country + "]";
- }
- }
-
-
- package cn.itheima.day05;
- import java.io.FileInputStream;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.ObjectInputStream;
- import java.io.ObjectOutputStream;
- public class ObjectStreamDemo {
- public static void main(String[] args) throws IOException, ClassNotFoundException {
-
- readObj();
- }
-
- public static void readObj() throws IOException, ClassNotFoundException{
- ObjectInputStream ois = new ObjectInputStream(new FileInputStream("F:\\Javajichu1\\JavaLianXi\\src\\cn\\itheima\\day05\\obj.txt"));
- Person person = (Person)ois.readObject();
- System.out.println(person);
- ois.close();
- }
-
- public static void writeObj() throws IOException{
- ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("F:\\Javajichu1\\JavaLianXi\\src\\cn\\itheima\\day05\\obj.txt"));
- oos.writeObject(new Person("lisi0",39,"china"));
- oos.close();
- }
- }
管道流:
PipedInputStream
PipedOutputStream
特点:
读取管道流和写入管道流可以进行连接。
连接的方式:
1. 通过两个流对象的构造函数。
2. 通过两个对象的connect方法。
通常两个流在使用时,需要加入多线程技术,也就是让读写同时运行。
注意:对于read方法。该方法是阻塞式的,也就是没有数据的情况,该方法会等
例子12.管道流的应用,用到多线程的知识。
- package cn.itheima.day05;
- import java.io.IOException;
- import java.io.PipedInputStream;
- import java.io.PipedOutputStream;
- class Read implements Runnable {
- private PipedInputStream in;
- Read(PipedInputStream in){
- this.in = in;
- }
- public void run() {
- try {
- byte[] buf = new byte[1024];
- int len = 0;
- System.out.println("读取前没有数据,阻塞");
- len = in.read(buf);
- System.out.println("读取到数据,阻塞结束");
- String s = new String(buf,0,len);
- System.out.println(s);
- in.close();
- } catch (IOException e) {
- throw new RuntimeException("管道读取流失败");
- }
- }
- }
- class Writer implements Runnable {
- private PipedOutputStream out;
- public Writer(PipedOutputStream out) {
- this.out = out;
- }
- public void run() {
- try {
- System.out.println("开始写入数据等待6秒后");
- Thread.sleep(6000);
- out.write("管道 来啦".getBytes());
- out.close();
- } catch (IOException e) {
- throw new RuntimeException("管道输出流失败");
- } catch (InterruptedException e) {
-
- e.printStackTrace();
- }
- }
- }
- public class PipedStream {
- public static void main(String[] args) throws IOException {
- PipedInputStream in = new PipedInputStream();
- PipedOutputStream out = new PipedOutputStream();
- in.connect(out);
- Read r = new Read(in);
- Writer w= new Writer(out);
- new Thread(r).start();
- new Thread(w).start();
- }
- }
RandomAccessFile类:
该类特点:该类不算IO体系中的子类,而是直接继承Object,但是它是IO包中的成员,因为它具备读和写功能,因为它内部封装了一个数组,而且通过指针对数组的元素进行操作。可以通过,getFilePointer获取指针位置,同时可以通过seek改变指针的位置。
其实完成读写的原理:内部封装了字节输入流和字节输出流。
通过构造函数,可以看出,该类只能操作文件,有局限性。
而且操作文件还有模式(4种):r(只读) rw(可读可写) rws rwd
而且该对象的构造函数要操作的文件不存在,会自动的创建,如果存在则不会覆盖。
如果模式是r: 则不会创建文件,会去读取一个已存在的文件,如果该文件不存在,则会出现异常。
如果模式是rw:操作的文件不存在,会自动创建,如果存在则不会原来的数据。
例子13:利用RandomAccessFile的seek()方法实现随机的读写和访问。
- package cn.itheima.day05;
- import java.io.FileNotFoundException;
- import java.io.IOException;
- import java.io.RandomAccessFile;
- public class RandomAccessFileDemo {
- public static void main(String[] args) throws IOException {
-
-
- readFile();
-
- }
-
- public static void readFile() throws IOException{
-
- RandomAccessFile raf=new RandomAccessFile("F:\\Javajichu1\\JavaLianXi\\src\\cn\\itheima\\day05\\ran.txt", "r");
-
-
-
-
-
- raf.skipBytes(8*3);
- byte[] buf = new byte[4];
- raf.read(buf);
- String name = new String(buf);
- System.out.println("name="+name);
- int age = raf.readInt();
- System.out.println("age="+age);
- raf.close();
- }
- public static void writerFile_2(){
- try {
- RandomAccessFile raf = new RandomAccessFile("F:\\Javajichu1\\JavaLianXi\\src\\cn\\itheima\\day05\\ran.txt", "rw");
-
- raf.seek(8*3);
- raf.write("周期".getBytes());
- raf.writeInt(103);
- raf.close();
-
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- public static void writeFile(){
- try {
- RandomAccessFile raf = new RandomAccessFile("F:\\Javajichu1\\JavaLianXi\\src\\cn\\itheima\\day05\\ran.txt", "rw");
- raf.write("张三".getBytes());
- raf.writeInt(97);
- raf.write("王五".getBytes());
- raf.writeInt(23);
- raf.close();
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
操作基本数据类型的流对象:DataInputStream.
DataInputStream:
DatsInputStream(InputStream);
它操作的基本数据类型的方法:
Int readInt():一次读取四个字节,并将其转换成int值。
booleanreadBoolean():一次读取一个字节。
short readShort():
longreadLong();
String readUTF():按照utf-8修改版读取字符。注意,它只能读取writeUTF()写入的字符数据。
DataOutputStream:
DataOutputStream(OutputStream):
操作基本数据类型的方法:
writeInt(int):一次写入四个字节。
注意和write(int)不同。write(int)只将该整数的最低一个8位写入。剩余三个8位丢弃。
writeBoolean(boolean);
writeShort(short);
writeLong(long);
writeUTF(String):按照utf-8修改版将字符数据进行存储。只能通过readUTF读取。通常只要操作基本数据类型的数据。就需要通过DataStram进行包装。通常成对使用。
例子14:利用DataInputStream和DataOutputStream操作基本数据类型进行读写操作。
- package cn.itheima.day05;
- import java.io.DataInputStream;
- import java.io.DataOutputStream;
- import java.io.FileInputStream;
- import java.io.FileNotFoundException;
- import java.io.FileOutputStream;
- import java.io.IOException;
-
-
-
-
- public class DataStreamDemo {
- public static void main(String[] args) {
-
-
-
- readUtfDemo();
- }
-
- public static void readUtfDemo(){
- try {
- DataInputStream dis = new DataInputStream(new FileInputStream("F:\\Javajichu1\\JavaLianXi\\src\\cn\\itheima\\day05\\utfdata.txt"));
- String value = dis.readUTF();
- System.out.println(value);
- dis.close();
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- public static void WriteUtfDemo(){
- try {
- DataOutputStream dos = new DataOutputStream(new FileOutputStream("F:\\Javajichu1\\JavaLianXi\\src\\cn\\itheima\\day05\\utfdata.txt"));
- dos.writeUTF("小明");
- dos.close();
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- public static void readData(){
- try {
- DataInputStream dis = new DataInputStream(new FileInputStream("F:\\Javajichu1\\JavaLianXi\\src\\cn\\itheima\\day05\\data.txt"));
- int num = dis.readInt();
- boolean b = dis.readBoolean();
- double d = dis.readDouble();
- System.out.println("num="+num);
- System.out.println("b="+b);
- System.out.println("d="+d);
- dis.close();
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- public static void writeData(){
- try {
- DataOutputStream dos = new DataOutputStream(new FileOutputStream("F:\\Javajichu1\\JavaLianXi\\src\\cn\\itheima\\day05\\data.txt"));
- dos.writeInt(234);
- dos.writeBoolean(true);
- dos.writeDouble(98.03);
- dos.close();
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
操作数组的流对象:
1,操作字节数组
ByteArrayInputStream:特点:在构造时需要接收数据源,而且数据源是一个字节数组,
ByteArrayOutputStream 特点:在构造的时候,不用定义数组目的。因为该对象中已经内部封装了一个可变长度的字节数组。
toByteArray();
toString();
writeTo(OutputStream):输入内容到一个文件中。
因为这两个流对象都操作的是数组,并没有使用系统资源,所以,没有不用进行流的关闭。(即使流对象关闭,还是可以使用的。
在流---规律讲解时:
源设备:
键盘 System.in 硬盘FileStream 内存ArrayStream
目的:
控制台System.out 硬盘FileStream 内存ArrayStream
用流的读写思想去操作数据。
例子15:ByteArrayInputStream和ByteArrayOutputStream来读写数据。
- package cn.itheima.day05;
- import java.io.ByteArrayInputStream;
- import java.io.ByteArrayOutputStream;
- import java.io.FileNotFoundException;
- import java.io.FileOutputStream;
- import java.io.IOException;
- public class ByteArrayStream {
- public static void main(String[] args) throws FileNotFoundException, IOException {
-
- ByteArrayInputStream bis = new ByteArrayInputStream("abcdefg".getBytes());
-
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- System.out.println(bos.size());
- int by = 0;
- while ((by = bis.read())!=-1) {
- bos.write(by);
- }
- System.out.println(bos.size());
- System.out.println(bos.toString());
- bos.writeTo(new FileOutputStream("F:\\Javajichu1\\JavaLianXi\\src\\cn\\itheima\\day05\\a.txt"));
- }
- }
2,操作字符数组。
CharArrayReader
CharArrayWriter
对于这些流,源是内存。目的也是内存。而且这些流并未调用系统资源。使用的就是内存中的数组。
所以这些在使用的时候不需要close。
操作数组的读取流在构造时,必须要明确一个数据源。所以要传入相对应的数组。
对于操作数组的写入流,在构造函数可以使用空参数。因为它内置了一个可变长度数组作为缓冲区。
编码转换:
在io中涉及到编码转换的流是转换流和打印流。但是打印流只有输出。在转换流中是可以指定编码表的。
默认情况下,都是本机默认的码表。GBK. 这个编码表怎么来的?System.getProperty("file.encoding");
常见码表:
ASCII:美国标准信息交换码。使用的是1个字节的7位来表示该表中的字符。
ISO8859-1:拉丁码表。使用1个字节来表示。
GB2312:简体中文码表。
GBK:简体中文码表,比GB2312融入更多的中文文件和符号。
unicode:国际标准码表。都用两个字节表示一个字符。
UTF-8:对unicode进行优化,每一个字节都加入了标识头。
编码转换:
(String--àbyte[])
字符串-->字节数组:编码。
通过str.getBytes(charset);
(byte[]--àString)
字节数组-->字符串:解码。
通过String类的构造函数完成。new String(byte[],charset);
如果编错了,没救!
如果编对了,解错了,有可能还有救!
String s = "你好";
//编码。
byte[] b =s.getBytes("GBK");
//解码。
String s1 = newString(b,"iso8859-1");
System.out.println(s1);
//想要还原。
/*
对s1先进行一次解码码表的编码。获取原字节数据。
然后在对原字节数据进行指定编码表的解码。
*/
byte[] b1 = s1.getBytes("iso8859-1");
String s2 = newString(b1,"gbk");
System.out.println(s2);//你好。
这种情况在tomcat服务器会出现。因为tomcat服务器默认是iso8859-1的编码表。所以客户端通过浏览器向服务端通过get提交方式提交中文数据时,服务端获取到会使用ISO8859-1进行中文数据的解码。会出现乱码。这时就必须要对获取的数据进行iso8859-1编码。然后在按照页面指定的编码表进行解码即可而对于post提交,这种方法也通用。但是post有更好的解决方式。
request.setCharacterEncoding("utf-8");即可。
所以建立客户端提交使用post提交方式。
例子16:写入和读出UTF-8编码和GBK编码的文件。
- package cn.itheima.day05;
- import java.io.FileInputStream;
- import java.io.FileNotFoundException;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.io.OutputStreamWriter;
- public class EncodeStream {
- public static void main(String[] args) {
-
- readText();
- }
- public static void readText(){
- try {
- InputStreamReader isr = new InputStreamReader(new FileInputStream("F:\\Javajichu1\\JavaLianXi\\src\\cn\\itheima\\day05\\gbk.txt"),"UTF-8");
- int len = 0;
- char[] buf = new char[10];
- len = isr.read(buf);
- String str = new String(buf,0,len);
- System.out.println("str="+str);
- isr.close();
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- public static void writeText(){
- try {
- OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("F:\\Javajichu1\\JavaLianXi\\src\\cn\\itheima\\day05\\gbk.txt"),"UTF-8");
- osw.write("你好");
- osw.close();
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
例子17:中文乱码的解决方案。
- package cn.itheima.day05;
- import java.io.UnsupportedEncodingException;
- import java.util.Arrays;
- public class EncodeDemo {
- public static void main(String[] args) throws UnsupportedEncodingException {
- String str = "你好";
- byte[] b1 = str.getBytes("GBK");
-
- String s1 = new String(b1,"ISO8859-1");
-
- byte[] b2 = s1.getBytes("ISO8859-1");
- System.out.println(Arrays.toString(b2));
-
- String s2 = new String(b2,"GBK");
-
- System.out.println(s2);
- }
- }
例子18:记事本敲“联通”,再次打开出现乱码的问题。查看“联通”的二进制数是符合GBK的编码,还是符合UTF-8的编码。
- package cn.itheima.day05;
- import java.io.UnsupportedEncodingException;
- public class EncodeDemo2 {
- public static void main(String[] args) throws UnsupportedEncodingException {
- String s = "联通";
- byte[] by = s.getBytes("GBK");
- for (byte b : by) {
- System.out.println(Integer.toBinaryString(b&255));
- }
- }
- }
例子19:有五名学生,每个学生有3门课的成绩,从键盘上输入以上数据,(包括姓名,和三门课的成绩,输出格式为:zhangsan,30,40,60,并且计算出总成绩,并把学生信息和计算出的总分数,按从高到低的顺序存放到硬盘的文件上”studentScore.txt”)
分析:1.描述学生对象。
2.定义一个可操作学生对象的工具类。
思想:1.通过获得键盘上录入的一行数据,并将该行中的信息,取出封装成学生对象
2.因为学生对象有很多,就需要使用集合,因为学生的总分要排序,所以可以使用TreeSet
3.将集合中的信息写入到一个文件中。
- package cn.itheima.day05;
- import java.io.BufferedReader;
- import java.io.BufferedWriter;
- import java.io.FileWriter;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.util.Collections;
- import java.util.Comparator;
- import java.util.Set;
- import java.util.TreeSet;
- class Student implements Comparable<Student>{
- private String name;
- private int ma,cn,en;
- private int sum;
-
- public String getName() {
- return name;
- }
- public int getSum() {
- return sum;
- }
- public int hashCode(){
- return name.hashCode()+sum*78;
- }
- public boolean equals(Object obj){
- if(!(obj instanceof Student))
- throw new ClassCastException("类型不匹配");
- Student s = (Student)obj;
- return this.name.equals(s.name) && this.sum==s.sum;
- }
- @Override
- public String toString() {
- return "Student [name=" + name + ", ma=" + ma + ", cn=" + cn + ", en="
- + en + ", sum=" + sum + "]";
- }
- public Student(String name, int ma, int cn, int en) {
- super();
- this.name = name;
- this.ma = ma;
- this.cn = cn;
- this.en = en;
- sum = ma+cn+en;
- }
- @Override
- public int compareTo(Student s) {
- int num = new Integer(this.sum).compareTo(new Integer(s.sum));
- if(num==0)
- return this.name.compareTo(s.name);
- return num;
- }
- }
- class StudentInfoTool{
- public static Set<Student> getStudents() throws IOException{
- return getStudents(null);
- }
- public static Set<Student> getStudents(Comparator<Student> cmp) throws NumberFormatException, IOException{
- BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
- String line = null;
- Set<Student> stus = null;
- if(cmp==null){
- stus=new TreeSet<Student>();
- }else {
- stus=new TreeSet<Student>(cmp);
- }
- while((line=bufr.readLine())!=null){
- if("over".equals(line))
- break;
- String[] info= line.split(",");
- Student stu = new Student(info[0], Integer.parseInt(info[1]), Integer.parseInt(info[2]), Integer.parseInt(info[3]));
- stus.add(stu);
- }
- bufr.close();
- return stus;
-
- public static void writeFile(Set<Student> stus) throws IOException{
- BufferedWriter bufw = new BufferedWriter(new FileWriter("F:\\Javajichu1\\JavaLianXi\\src\\cn\\itheima\\day05\\studentinfo.txt"));
- for (Student stu : stus) {
- bufw.write(stu.toString()+"\t");
- bufw.write(stu.getSum()+"");
- bufw.newLine();
- bufw.flush();
- }
- bufw.close();
- }
- }
- public class StudentInfoTest {
- public static void main(String[] args) throws NumberFormatException, IOException {
- Comparator<Student> cmp = Collections.reverseOrder();
- Set<Student> students = StudentInfoTool.getStudents(cmp);
- StudentInfoTool.writeFile(students);
- }
- }