黑马程序员_JavaIO输入与输出下

来源:互联网 发布:中国网络教育大学排名 编辑:程序博客网 时间:2024/06/07 01:16

----------- android培训java培训java学习型技术博客、期待与您交流! ------------

 

       File概述

File类:用来将文件或者文件夹封装成对象。方便对文件与文件夹的属性信息进行操作。File对象可以作为参数传递给流的构造函数。

示例:

import java.io.*;
class FileDemo
{
 public static void main(String[] args)
 {
  consMethod();
 }
 public static void consMethod()
 {
  //创建File对象,将a.txt封装成File对象。可以将已有的和不存在的文件或文件夹封装成File对象。
  File f1=new File("a.txt");
  File f2=new File("d:\\abc","b.txt");
  File d=new File("d:\\abc");
  File f3=new File(d,"c.txt");
  File f4=new File("d:"+File.separator+"abc"+File.separator+"zzz"+File.separator+"z.txt");
  sop("f1:"+f1);
  sop("f2:"+f2);
  sop("f3:"+f3);
  sop("f4:"+f4);
 }
 public static void sop(Object obj)
 {
  System.out.println(obj);
 }
}

 

File类中常见方法:

1.创建:

boolean createNewFile():在指定位置创建文件。如果该文件已经存在,则不创建,返回false。

boolean mkdir():创建一级文件夹。

boolean mkdirs():创建多级文件夹。

2.删除:

boolean delete():删除失败返回false。如果文件正在被使用,则删除失败返回false。

void deleteOnExit():在程序退出时删除指定文件。

示例1:

import java.io.*;
class FileDemo1
{
 public static void main(String[] args)throws IOException
 {
  File f=new File("file.txt");
  sop("create:"+f.createNewFile());
  //sop("delete:"+f.delete());
  f.deleteOnExit();
 }
 public static void sop(Object obj)
 {
  System.out.println(obj);
 }
}

3.判断:

boolean exists():文件是否存在。

isFile():是否是文件。

isDirectory():是否是文件夹。

isHidden():是否是隐藏文件。

isAbsolute():是否是绝对路径。

canExecute():是否是可执行文件。

示例2:

import java.io.*;
class FileDemo2
{
 public static void main(String[] args)throws IOException
 {
  method_2();
  method_3();
 }
 public static void sop(Object obj)
 {
  System.out.println(obj);
 }
 public static void method_2()
 {
  File f=new File("file.txt");
  //File f=new File("FileDemo.java");
  sop("execute:"+f.canExecute());
  sop("exists:"+f.exists());
  //创建文件夹。
  File dir=new File("wanglin");
  sop("mkdir:"+dir.mkdir());
  File dir1=new File("wanglin\\tangwei\\abc\\fdree\\java.txt");
  sop("mkdirs:"+dir1.mkdirs());
 }
 public static void method_3()throws IOException
 {
  File f1=new File("file.txt");
  //在判断文件对象是否是文件或者文件夹目录时,必须要先判断该文件对象封装的内容是否存在。通过exists方法判断。
  f1.mkdir();
  sop("dir:"+f1.isDirectory());
  sop("file:"+f1.isFile());
  sop(f1.isAbsolute());
  File f2=new File("d:\\java01\\day20\\file.txt");
  sop(f2.isAbsolute());

 }
}

4.获取:

getName();

getPath():只获取文件对象封装的路径目录。

getParent():获取父目录。

getAbsolutePath():获取绝对路径。

long lastModified():获取文件最后一次修改时间。

long length():获取文件大小。

示例3:

import java.io.*;
class FileDemo3
{
 public static void main(String[] args)throws IOException
 {
  method_4();
  method_5();
 }
 public static void sop(Object obj)
 {
  System.out.println(obj);
 }
 public static void method_4()
 {
  File f=new File("file.txt");
  sop("path:"+f.getPath());
  sop("absolute:"+f.getAbsolutePath());
  //sop("parent:"+f.getParent());
  File f3=new File("wanglin\\file.txt");
  sop("parent:"+f3.getParent());
 }
 public static void method_5()
 {
  File f1=new File("f:\\java01\\day20\\FileDemo.java");
  File f2=new File("d:\\wanglin.txt");
  sop("rename:"+f1.renameTo(f2));
 }
}

 

5.列出文件列表:

list():列出指定目录下所有文件和文件夹名称,包括隐藏文件和文件夹。

示例:

import java.io.*;
class FileDemo4
{
 public static void main(String[] args)
 {
  listRootsDemo();
  listDemo();
 }
 public static void listRootsDemo()
 {
  File[] files=File.listRoots();
  for(File f:files)
  {
   System.out.println(f);
  }
 }
 public static void listDemo()
 {
  File f1=new File("e:\\");
  String[] names=f1.list();
  for(String name:names)
  {
   System.out.println(name);
  }
 }
}

FilenameFilter接口:获取指定目录下的指定名称的文件名。

示例:

import java.io.*;
class FileDemo5
{
 public static void main(String[] args)
 {
  File dir=new File("d:\\");
  File[] files=dir.listFiles();
  for(File f:files)
  {
   System.out.println(f.getName()+"::::"+f.length());
  }
  listDemo_2();
 }
 public static void listDemo_2()
 {
  File dir1=new File("f:\\java01\\day19");
  String[] arr=dir1.list(new FilenameFilter()
  {
   public boolean accept(File dir,String name)
   {
    return name.endsWith(".txt");//获取指定目录下的.txt文件。
   }
  });
  System.out.println("len:"+arr.length);
  for(String name:arr)
  {
   System.out.println(name);
  }
 }
}

 

怎样列出指定目录下的所有内容,包括子内容?

因为目录中还有目录,只要使用同一个列出目录功能的函数完成即可。在列出过程中出现的还有目录的话,还可以再次调用本功能。也就是函数自身调用自身,这种表现形式或者编程手法,称为递归。

递归要注意:

1.限定条件。

2.要注意递归的次数。次数太多,内存会溢出。

递归示例:

import java.io.*;
class FileDemo6
{
 public static void main(String[] args)
 {
  File dir=new File("f:\\java01");
  showDir(dir);
  toBin(74);
  int n=getSum(142);
  System.out.println("n="+n);
 }
 public static int getSum(int n)
 {
  if(n==1)
   return 1;
  return n+getSum(n-1);
 }
 public static void toBin(int num)
 {
  if(num>0)
  {
   toBin(num/2);
   System.out.println(num%2);
  }
 }
 public static void showDir(File dir)
 {
  System.out.println(dir);
  File[] files=dir.listFiles();
  for(File file:files)
  {
   if(file.isDirectory())
    showDir(file);
   else
    System.out.println(file);
  }
 }
}

删除带内容的目录:

删除原理:先删除完里面的内容,再删外面的内容,最后删除指定的文件夹。这时就需要用到递归。

删除文件夹示例:

import java.io.*;
class FileDemo8
{
 public static void main(String[] args)
 {
  File dir=new File("f:\\myclass");
  removeDir(dir);
 }
 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+"::dir::"+dir.delete());
 }
}

 

Properties简述

Properties是Hashtable的子类。也就是说它具备Map集合的特点。而且它里面存储的键值对都是字符串。它是集合中和IO技术相结合的集合容器。

Properties对象的特点:可以用于键值对形式的配置文件。那么在加载数据时,需要数据有固定格式:键=值

Properties存取元素:

示例:

import java.io.*;
import java.util.*;
class PropertiesDemo
{
 public static void main(String[] args)
 {
  setAndGet();
 }
 public static void setAndGet()
 {
  Properties prop=new Properties();
  prop.setProperty("wanglin01","23");
  prop.setProperty("wanglin02","25");
  prop.setProperty("wanglin03","27");
  System.out.println(prop);
  String value=prop.getProperty("wanglin02");
  System.out.println(value);
  prop.setProperty("wanglin03",20+"");
  Set<String> names=prop.stringPropertyNames();
  for(String s:names)
  {
   System.out.println(s+"::"+prop.getProperty(s));
  }
 }
}

Properties存取配置文件:

示例:

import java.io.*;
import java.util.*;
class PropertiesDemo2
{
 public static void main(String[] args)throws IOException
 {
  //method_1();
  loadDemo();
 }
 public static void loadDemo()throws IOException
 {
  Properties prop=new Properties();
  FileInputStream fis=new FileInputStream("info.txt");
  prop.load(fis);
  System.out.println(prop);
  prop.setProperty("wanglin03",30+"");
  FileOutputStream fos=new FileOutputStream("info.txt");
  prop.store(fos,"tangwei");
  prop.list(System.out);
  fos.close();
  fis.close();
 }
 public static void method_1()throws IOException
 {
  BufferedReader bufr=new BufferedReader(new FileReader("info.txt"));
  String line=null;
  Properties prop=new Properties();
  while((line=bufr.readLine())!=null)
  {
   String[] arr=line.split("=");
   System.out.println(arr[0]+":::"+arr[1]);
   prop.setProperty(arr[0],arr[1]);
  }
  bufr.close();
  System.out.println(prop);
 }
}

 

IO包中的其他类:

1.打印流:PrintWriter与PrintStream    可以直接操作输入流和文件。该流提供了打印方法,可以将各种数据类型的数据都原样打印。

字节打印流:PrintStream

构造函数可以接收的参数类型:File对象 file;字符串路径 String;字节输出流 OutputStream

字符打印流:PrintWriter

构造函数可以接收的参数类型:File对象 file;字符串路径 String;字节输出流 OutputStream;字符输出流 Writer

打印流示例:

import java.io.*;
class PrintStreamDemo
{
 public static void main(String[] args)throws IOException
 {
  BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));
  //PrintWriter out=new PrintWriter(new FileWriter("a.txt"),true);
  //PrintWriter out=new PrintWriter(System.out);
  PrintWriter out=new PrintWriter(new BufferedWriter(new FileWriter("a.txt")),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.序列流:SequenceInputStream   将多个文件的输入流合并为一个输入流。

示例:

import java.io.*;
import java.util.*;
class SequenceDemo
{
 public static void main(String[] args)throws IOException
 {
  Vector<FileInputStream> v=new Vector<FileInputStream>();
  v.add(new FileInputStream("d:\\1.txt"));
  v.add(new FileInputStream("d:\\2.txt"));
  v.add(new FileInputStream("d:\\3.txt"));
  Enumeration<FileInputStream> en=v.elements();
  SequenceInputStream sis=new SequenceInputStream(en);
  FileOutputStream fos=new FileOutputStream("d:\\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();
 }
}

切割指定文件,再将切割后的文件碎片合并。

操作示例:

import java.io.*;
import java.util.*;
class SplitFile
{
 public static void main(String[] args)throws IOException
 {
  splitFile();
  //merge();
 }
 public static void merge()throws IOException
 {
  ArrayList<FileInputStream> al=new ArrayList<FileInputStream>();
  for(int x=1;x<=4;x++)
  {
   al.add(new FileInputStream("f:\\splitfiles\\"+x+".part"));
  }
  final 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("f:\\splitfiles\\0.mp3");
  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:\\1.mp3");
  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:\\splitfiles\\"+(count++)+".part");
   fos.write(buf,0,len);
   fos.close();
  }
  fis.close();
 }
}

 

3.操作对象:ObjectInputStream与ObjectOutputStream   被操作的对象需要实现Serializable接口(标记接口)。

对象的序列化:将堆内存中的对象数据保存到硬盘上的一个文件中,从而将对象永久保存,这就叫做对象序列化,也叫对象持久化。

对象序列化示例:

Person对象:

import java.io.*;
class Person implements Serializable
{
 public static final long serialVersionUID=48L;
 private String name;
 transient int age;
 static String country="cn";
 Person(String name,int age,String country)
 {
  this.name=name;
  this.age=age;
  this.country=country;
 }
 public String toString()
 {
  return name+"::"+age+"::"+country;
 }
}
将Person对象序列化:

import java.io.*;
class ObjectStreamDemo
{
 public static void main(String[] args)throws Exception
 {
  writeObj();
  //readObj();
 }
 public static void readObj()throws Exception
 {
  ObjectInputStream ois=new ObjectInputStream(new FileInputStream("obj.txt"));
  Person p=(Person)ois.readObject();
  System.out.println(p);
  ois.close();
 }
 public static void writeObj()throws IOException
 {
  ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("obj.txt"));
  oos.writeObject(new Person("wanglin01",22,"jp"));
  oos.close();
 }
}

 

4.RandomAccessFile:随机访问文件,自身具备读写的方法。该类不算是IO体系中的子类,而是直接继承自Object类。但是它是IO包中成员,因为它具备读写功能。该类内部封装了一个字节数组,可以通过指针对数组的元素进行操作。可以通过getFilePointer获取指针的位置,再通过seek方法或skipBytes方法改变指针的位置。从而达到随机访问。其实该类完成读写的原理就是内部封装了字节输入流和输出流。通过构造函数可以看出,该类只能操作文件。而且操作的文件有两种模式:r(只读),rw(读写)。

示例:

import java.io.*;
class RandomAccessFileDemo
{
 public static void main(String[] args)throws IOException
 {
  //writeFile();
  writeFile_2();
  readFile();
  RandomAccessFile raf=new RandomAccessFile("ran1.txt","rw");
  //RandomAccessFile raf=new RandomAccessFile("ran1.txt","r");
  raf.write("tang".getBytes());
 }
 public static void readFile()throws IOException
 {
  RandomAccessFile raf=new RandomAccessFile("ran.txt","r");
  raf.seek(8*1);//将指针调整到脚标8位置。
  //raf.skipBytes(8);//跳过8个字节。
  byte[] buf=new byte[4];
  raf.read(buf);
  String name=new String(buf);
  int age=raf.readInt();
  System.out.println("name="+name);
  System.out.println("age="+age);
  raf.close();
 }
 public static void writeFile_2()throws IOException
 {
  RandomAccessFile raf=new RandomAccessFile("ran.txt","rw");
  raf.seek(8*0);
  //raf.seek(8*3);
  raf.write("丽丽".getBytes());
  raf.writeInt(201);
  raf.close();
 }
 public static void writeFile()throws IOException
 {
  RandomAccessFile raf=new RandomAccessFile("ran.txt","rw");
  raf.write("宝宝".getBytes());
  raf.writeInt(97);
  raf.write("贝贝".getBytes());
  raf.writeInt(99);
  raf.close();
 }
}

5.管道流:PipedInputStream和PipedOutputStream   输入输出可以直接进行连接,通过结合线程使用。涉及到多线程技术的IO流对象。

示例:

import java.io.*;
class Read implements Runnable
{
 private PipedInputStream in;
 Read(PipedInputStream in)
 {
  this.in=in;
 }
 public void run()
 {
  try
  {
   byte[] buf=new byte[1024];
   System.out.println("读取前。。。没有数据阻塞");
   int 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 Write implements Runnable
{
 private PipedOutputStream out;
 Write(PipedOutputStream out)
 {
  this.out=out;
 }
 public void run()
 {
  try
  {
   System.out.println("开始写入数据,等待6秒后");
   Thread.sleep(6000);
   out.write("piped lai la".getBytes());
   out.close();
  }
  catch (Exception e)
  {
   throw new RuntimeException("管道输出流失败");
  }
 }
}
class PipedStreamDemo
{
 public static void main(String[] args)throws IOException
 {
  PipedInputStream in=new PipedInputStream();
  PipedOutputStream out=new PipedOutputStream();
  in.connect(out);
  Read r=new Read(in);
  Write w=new Write(out);
  new Thread(r).start();
  new Thread(w).start();
 }
}

6.操作基本数据类型的数据的流对象:DataInputStream和DataOutputStream

示例:

import java.io.*;
class DataStreamDemo
{
 public static void main(String[] args)throws IOException
 {
  writeData();
  readData();
 }
 public static void writeData()throws IOException
 {
  DataOutputStream dos=new DataOutputStream(new FileOutputStream("data.txt"));
  dos.writeInt(346);
  dos.writeBoolean(false);
  dos.writeDouble(45893.9823);
  dos.close();
 }
 public static void readData()throws IOException
 {
  DataInputStream dis=new DataInputStream(new FileInputStream("data.txt"));
  int num=dis.readInt();
  boolean b=dis.readBoolean();
  double d=dis.readDouble();
  sop("num="+num);
  sop("b="+b);
  sop("d="+d);
 }
 public static void sop(Object obj)
 {
  System.out.println(obj);
 }
}

 

7.操作字节数组的流对象:

ByteArrayInputStream:在构造的时候,需要接收数据源,而且数据源是一个字节数组。

ByteArrayOutputStream:在构造的时候,不用定义数据目的。因为该对象中已经封装了可变长度的字节数组,这就是数据目的地。

示例:

import java.io.*;
class ByteArrayStream
{
 public static void main(String[] args)
 {
  ByteArrayInputStream bis=new ByteArrayInputStream("wanglin01".getBytes());
  ByteArrayOutputStream bos=new ByteArrayOutputStream();
  int by=0;
  while((by=bis.read())!=-1)
  {
   bos.write(by);
  }
  System.out.println(bos.size());
  System.out.println(bos.toString());
 }
}

转换流的字符编码:

字符流的出现为了方便操作字符。更重要的是加入了编码转换。通过子类转换流来完成:InputStreamReader和OutputStreamWriter。这两个流对象进行构造的时候可以加入字符集。

编码表的由来:

计算机只能识别二进制数据。为了方便应用计算机,让它可以识别各个国家的文字,就将各个国家的文字用数字来表示,并一一对应,形成一张表。这就是编码表。

常见的编码表:

ASCII:美国标准信息交换码。用一个字节的7位可以表示。

ISO8859-1:欧洲码表。用一个字节的8位表示。

GB2312:中国的中文编码表。

GBK:GB2312的升级版。融合了更多的中文文字符号。

Unicode:国际标准码,融合了多种文字。所有文字都用两个字节表示。Java语言使用的就是Unicode。

UTF-8:国际标准码改进版,最多用三个字节来表示一个字符。

 

转化流的编码应用:

1.可以将字符以指定编码格式存储。

2.可以对文本数据以指定编码格式来读取。

3.指定编码表的动作由构造函数完成。

应用示例:

import java.io.*;
class EncodeStream
{
 public static void main(String[] args)throws IOException
 {
  //writeText();
  readText();
 }
 public static void readText()throws IOException
 {
  //InputStreamReader isr=new InputStreamReader(new FileInputStream("gbk.txt"),"GBK");
  InputStreamReader isr=new InputStreamReader(new FileInputStream("utf.txt"),"GBK");
  char[] buf=new char[10];
  int len=isr.read(buf);
  String str=new String(buf,0,len);
  System.out.println(str);
  isr.close();
 }
 public static void writeText()throws IOException
 {
  //OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("gbk.txt"),"GBK");
  OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("utf.txt"),"UTF-8");
  osw.write("你好");
  osw.close();
 }
}

 

字符编码:字符串变成字节数组。通过getBytes(指定的编码表);

字符解码:字节数组变成字符串。通过new String(byte[],指定的编码表);

编码与解码示例:

import java.util.*;
class EncodeDemo
{
 public static void main(String[] args)throws Exception
 {
  String s="你好";
  byte[] b1=s.getBytes("gbk");
  //byte[] b1=s.getBytes("utf-8");
  System.out.println(Arrays.toString(b1));
  //String s1=new String(b1,"GBK");
  //String s1=new String(b1,"UTF-8");
  String s1=new String(b1,"iso8859-1");
  System.out.println("s1="+s1);
  
  byte[] b2=s1.getBytes("ISO8859-1");
  System.out.println(Arrays.toString(b2));
  String s2=new String(b2,"gbk");
  //String s2=new String(b2,"utf-8");
  System.out.println("s2="+s2);
 }
}

 

字符编码中的特殊现象:在记事本程序中写入“联通”两个字,保存后再打开记事本,这两个字变成乱码。原因是:“联通”这两个字的GBK编码的二进制形式正好符合UTF-8的二进制编码规则,记事本程序自动用UTF-8编码表进行解码,所以变成乱码。

 

----------- android培训java培训java学习型技术博客、期待与您交流! ------------


 

 

 

               

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 买高跟鞋一只脚合适一只脚挤怎么办 脚瘦穿高跟鞋撑不起来怎么办 银川市阅海幼儿园进不去怎么办 考编专业不对口怎么办 北京55中国际部怎么办 初中数学没学好高中怎么办 靴子大了一码怎么办 靴子买大了一码怎么办 马丁靴大了一码怎么办 社保掌上通登录密码忘记怎么办 录微课时忘词怎么办 微课掌上通看不到信息怎么办 五年级学生上课很吵新老师怎么办 跟财务老师吵起来怎么办 qq把微信冻结了怎么办 微信给封号了怎么办 微信久了没登录冻结了怎么办 换手机号了微店怎么办 ai文件置入后都是字怎么办 excel加载项被禁用了怎么办 被期刊网骗了怎么办 发表的文章不想被收录怎么办? 农村长说的眼睛害了怎么办 普通党员不认同领导的决定怎么办 大学读不下去了怎么办 教师因病长期不能上班怎么办 长按win键黑屏了怎么办 巡视组巡视出问题后续怎么办 货运资格证两次没继续教育怎么办 电子注册备案表学信网查不到怎么办 学信网学籍档案没照片怎么办 信访局不给答复怎么办 发票跳了一个号怎么办 报税用的ca证书怎么办 报税u盘丢了怎么办 地税ca证书丢了怎么办 深圳ca证书丢了怎么办 武汉国税报税证书过期怎么办 江苏大学专业选修课挂了怎么办 电信翼企享福卡怎么办 教育部学籍在线验证报告过期怎么办