黑马程序员_关于io的学习

时间:2022-04-29 00:30:56

---------------------- android培训java培训、期待与您交流! ----------------------

通过几天的学习,io终于学完了第一遍,但是学了后,忘记的很快,所以只有在以后需要用的时候在去看那API文档,那么必须学会看API文档,下面是我在观看传智播客的毕老师的视频和在网上找的一些质料:

 流操作的基本规律

    1通过2个明确来来完成。

       源:输入流 Inputstream   Reader

                            目的:输出流 Otputstream   Writer

                 2  操作数据还是不是纯文本。

                           是: 字符流

                           否: 字节流

        体系的明确后在确定要用那个具体的对象,通过设备来进行区分

                                原设备      内纯  硬盘  键盘

                              目的设备       内存     硬盘   控制台

 

     分析案例

           讲一个文本文件中的数据储存到另一个文件中(复制文本)

 

 

    开始分析:  源,以为是源,所以使用读取流 Inputstream或者Reader,因为是操作文本所以就选择Reader,这样体系就明确了,这样接下来明确要使用流体系的哪个对象。

       明确设备,因为是硬盘上的一个文件,Reader体系中可以操作文件是FileReader

              FileReader  fr =new  FileReader(”a.txt“)

    目的:wrter 体系中可以操作文件的对象FileWriter

                 FileWriter  =new  FileWriter(“a.txt”)

 Flie常见的方法
         1 创建

           boolean createNewFile()  在指定的位置创建文件,如果文件已近存在就不创建,返回false.和流输出不一样,输出流对象一建立,在建立会覆盖前一个。

     boolean mkdir();创建文件夹

     boolean mkdir();创建文件

         2 删除

       boolean    delet(); 删除失败返回false,如果文件正在使用,则删除不了,返回false ,

      void deleterExit(); 在程序运行时删除指定的文件。

   3   判断

            boolean     exists()

             isFile();

           isDirestory();  

  4获取信息

      getpath();

     getParent()

 

 

Properties 基本知识

  如果不熟悉 java.util.Properties 类,那么现在告诉您它是用来在一个文件中存储键-值对的,其中键和值是用等号分隔的.

 

JAVA轻松操作properties文件的示例程序:


package control;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.Properties;

public class TestMain {
 
 //根据key读取value
 public static String readValue(String filePath,String key) {
  Properties props = new Properties();
        try {
         InputStream in = new BufferedInputStream (new FileInputStream(filePath));
         props.load(in);
         String value = props.getProperty (key);
            System.out.println(key+value);
            return value;
        } catch (Exception e) {
         e.printStackTrace();
         return null;
        }
 }
 
 //读取properties的全部信息
    public static void readProperties(String filePath) {
     Properties props = new Properties();
        try {
         InputStream in = new BufferedInputStream (new FileInputStream(filePath));
         props.load(in);
            Enumeration en = props.propertyNames();
             while (en.hasMoreElements()) {
              String key = (String) en.nextElement();
                    String Property = props.getProperty (key);
                    System.out.println(key+Property);
                }
        } catch (Exception e) {
         e.printStackTrace();
        }
    }

    //写入properties信息
    public static void writeProperties(String filePath,String parameterName,String parameterValue) {
     Properties prop = new Properties();
     try {
      InputStream fis = new FileInputStream(filePath);
            //从输入流中读取属性列表(键和元素对)
            prop.load(fis);
            //调用 Hashtable 的方法 put。使用 getProperty 方法提供并行性。
            //强制要求为属性的键和值使用字符串。返回值是 Hashtable 调用 put 的结果。
            OutputStream fos = new FileOutputStream(filePath);
            prop.setProperty(parameterName, parameterValue);
            //以适合使用 load 方法加载到 Properties 表中的格式,
            //将此 Properties 表中的属性列表(键和元素对)写入输出流
            prop.store(fos, "Update '" + parameterName + "' value");
        } catch (IOException e) {
         System.err.println("Visit "+filePath+" for updating "+parameterName+" value error");
        }
    }

    public static void main(String[] args) {
     readValue("info.properties","url");
        writeProperties("info.properties","age","21");
        readProperties("info.properties" );
        System.out.println("OK");
    }
}

RandomAccessFile

RandomAccessFile是一个很有用的类,可以将字节流写入到磁盘文件中,对应的也可以从磁盘文件中读取出字节流,在API中关于RandomAccessFile的描述如下:

此类的实例支持对随机访问文件的读取和写入。随机访问文件的行为类似存储在文件系统中的一个大型 byte 数组。存在指向该隐含数组的光标或索引,称为文件指针 ;输入操作从文件指针开始读取字节,并随着对字节的读取而前移此文件指针。如果随机访问文件以读取/写入模式创建,则输出操作也可用;输出操作从文件指针开始写入字节,并随着对字节的写入而前移此文件指针。写入隐含数组的当前末尾之后的输出操作导致该数组扩展。该文件指针可以通过getFilePointer 方法读取,并通过 seek 方法设置。

 

通常,如果此类中的所有读取例程在读取所需数量的字节之前已到达文件末尾,则抛出 EOFException (是一种 IOException )。如果由于某些原因无法读取任何字节,而不是在读取所需数量的字节之前已到达文件末尾,则抛出IOException ,而不是 EOFException 。需要特别指出的是,如果流已被关闭,则可能抛出 IOException

以下是两个RandomAccessFile的写入和读取的简单例子:

1、  将字节流写入到磁盘中

 

    

private static void testCreateFile(){

String directory = “D:/program/test”;

String name = “t.gen”;

File f = new File(directory, name);

RandomAccessFile file = null;

try {

file = new RandomAccessFile(f, “rw”);

byte[] b = {5,10,15,20};

try {

//如果没有这行,文件也会生成,只是文件为空

file.write(b,0,4);

} catch (IOException e) {

e.printStackTrace();

}

} catch (FileNotFoundException e) {

e.printStackTrace();

}finally{

if (null!=file){

try {

file.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

   

2、  从磁盘文件中读取字节流

private static void testReadFile(){

String directory = “D:/program/luceneDemo3.0/test”;

String name = “t.gen”;

File f = new File(directory, name);

RandomAccessFile file = null;

try {

file = new RandomAccessFile(f, “rw”);

byte[] b = new byte[4];

try {

long len = file.length();

file.read(b);

//设置要读取的字节位置

file.seek(1);

System.out.println(file.readByte()+”>>FilePointer>>”+file.getFilePointer());

for (int i=0;i<b.length;i++){

System.out.println(“>>>”+b[i]);

}

} catch (IOException e) {

e.printStackTrace();

}

} catch (FileNotFoundException e) {

e.printStackTrace();

}finally{

if (null!=file){

try {

file.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

说明

1、  这个类依我看来,用来处理字节流(byte)是很好的,如果用来处理字符(串)或其他数据类型,比如int、long,我试了感觉效果并不好,尤其是处理中文字符串的时候,那简直就是一个灾难,你会又碰上纠缠不清的乱码!

2、 seek(long pos)方法

是在读取的时候用来设置读取到哪一个字节的,比如在例子中有5,10,15,20字节,在byte数组中分别对应0、1、2、3位置,同样在文件 file = new RandomAccessFile(f, “rw”);中,也对应着0、1、2、3位置,所以如果设置file.seek(1);就表示通过file.readByte()读取的时候,读取的是第 1位置的数据,也就是10了。

3、  getFilePointer()方法

在通过上面说的seek (long pos)设置后,getFilePointer()得到的就是当前文件中的字节位置,也就是所说的偏移量了。比如在这个例子中,getFilePointer()的值就是1.

4、文件模式

“r” 以只读方式打开。调用结果对象的任何 write 方法都将导致抛出 IOException。

“rw” 打开以便读取和写入。如果该文件尚不存在,则尝试创建该文件。

“rws” 打开以便读取和写入,对于 “rw”,还要求对文件的内容或元数据的每个更新都同步写入到底层存储设备。

“rwd”   打开以便读取和写入,对于 “rw”,还要求对文件内容的每个更新都同步写入到底层存储设备。

 

附录

void close ()
关闭此随机访问文件流并释放与该流关联的所有系统资源。
FileChannel getChannel ()
返回与此文件关联的唯一 FileChannel 对象。
FileDescriptor getFD ()
返回与此流关联的不透明文件描述符对象。
long getFilePointer ()
返回此文件中的当前偏移量。
long length ()
返回此文件的长度。
int read ()
从此文件中读取一个数据字节。
int read (byte[] b)
将最多 b.length 个数据字节从此文件读入 byte 数组。
int read (byte[] b, int off, int len)
将最多 len 个数据字节从此文件读入 byte 数组。
boolean readBoolean ()
从此文件读取一个 boolean。
byte readByte ()
从此文件读取一个有符号的八位值。
char readChar ()
从此文件读取一个字符。
double readDouble ()
从此文件读取一个 double。
float readFloat ()
从此文件读取一个 float。
void readFully (byte[] b)
将 b.length 个字节从此文件读入 byte 数组,并从当前文件指针开始。
void readFully (byte[] b, int off, int len)
将正好 len 个字节从此文件读入 byte 数组,并从当前文件指针开始。
int readInt ()
从此文件读取一个有符号的 32 位整数。
String readLine ()
从此文件读取文本的下一行。
long readLong ()
从此文件读取一个有符号的 64 位整数。
short readShort ()
从此文件读取一个有符号的 16 位数。
int readUnsignedByte ()
从此文件读取一个无符号的八位数。
int readUnsignedShort ()
从此文件读取一个无符号的 16 位数。
String readUTF ()
从此文件读取一个字符串。
void seek (long pos)
设置到此文件开头测量到的文件指针偏移量,在该位置发生下一个读取或写入操作。
void setLength (long newLength)
设置此文件的长度。
int skipBytes (int n)
尝试跳过输入的 n 个字节以丢弃跳过的字节。
void write (byte[] b)
将 b.length 个字节从指定 byte 数组写入到此文件,并从当前文件指针开始。
void write (byte[] b, int off, int len)
将 len 个字节从指定 byte 数组写入到此文件,并从偏移量 off 处开始。
void write (int b)
向此文件写入指定的字节。
void writeBoolean (boolean v)
按单字节值将 boolean 写入该文件。
void writeByte (int v)
按单字节值将 byte 写入该文件。
void writeBytes (String s)
按字节序列将该字符串写入该文件。
void writeChar (int v)
按双字节值将 char 写入该文件,先写高字节。
void writeChars (String s)
按字符序列将一个字符串写入该文件。
void writeDouble (double v)
使用 Double 类中的 doubleToLongBits 方法将双精度参数转换为一个 long,然后按八字节数量将该 long 值写入该文件,先定高字节。
void writeFloat (float v)
使用 Float 类中的 floatToIntBits 方法将浮点参数转换为一个 int,然后按四字节数量将该 int 值写入该文件,先写高字节。
void writeInt (int v)
按四个字节将 int 写入该文件,先写高字节。
void writeLong (long v)
按八个字节将 long 写入该文件,先写高字节。
void writeShort (int v)
按两个字节将 short 写入该文件,先写高字节。
void writeUTF (String str)
使用 modified UTF-8 编码以与机器无关的方式将一个字符串写入该文件。

 

DataInputStream和DataOutputStream 

这个是数据流.给我们直接处理基本数据类型的接口

举个最基本的例子,如果我们要将一个float类型的数据写入文件,我们需要先转换成String类型,然后转换成字节数组,这样才能存入..现在我们可以直接用DataInputStream和DataOutputStream来解决这个问题

直接看下面的例子.

package com.test.Stream;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;

/**
 * @author 陈静波 E-mail:jingbo2759@163.com
 * @version 创建时间:Aug 29, 2009 2:36:26 PM
 * 类说明
 */
public class DataStreamTest
{

 public static void main(String[] args)
 {
  ByteArrayOutputStream baos = new ByteArrayOutputStream();
  DataOutputStream dos = new DataOutputStream(baos);
  
  try
  {
   dos.writeChar('d');
   dos.writeInt(10);
   dos.writeShort(50);
  } catch (IOException e)
  {
   e.printStackTrace();
  }
  
  ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
  DataInputStream dis = new DataInputStream(bais);
  
  try
  {
   System.out.println(dis.available());
   System.out.println(dis.readChar());
   System.out.println(dis.readInt());
   System.out.println(dis.readShort());
  } catch (IOException e)
  {
   e.printStackTrace();
  }
  
  try
  {
   dos.close();
   dis.close();
  } catch (IOException e)
  {
   e.printStackTrace();
  }
  
 }

}

ByteArrayOutputStream的用法

字节数组流:
ByteArrayOutputStream:    可以捕获内存缓冲区的数据,转换成字节数组。
ByteArrayoutputStream bout=new ByteArrayOutputStream();
bout.write(int a);  bout.write(int b);  bout.write(int c);
byte[] buf=bout.toByteArray();//获取内存缓冲中的数据
for(int i=0;i<=buf.length;i++)
{
  System.out.println(buf);
}
bout.close();
注:通过调用reset()方法可以重新定位。
ByteArrayInputStream: 可以将字节数组转化为输入流
ByteArrayInputStream bin=new ByteArrayInputStream(byte[] buf);
int data=0;
while( (b=bin.read())!=-1)
{
  System.out.println(b);
}
bin.close();

与DataOutputStream&DataInputStream联合使用:

ByteArrayOutputStream bout=new ByteArrayOutputStream();
DataOutputStream dos=new DataOutputStream(bout);
String name="suntao";
int age=19;
dos.writeUTF(name);
dos.writeInt(age);
byte[] buf=bout.toByteArray();//获取内存缓冲区中的数据
dos.close();
bout.close();

ByteArrayInputStream bin=new ByteArrayInputStream(byte[] buf);
DataInputStream dis=new DataInputStream(bin);
String name=dis.readUTF();//从字节数组中读取
int age=dis.readInt();
dis.close();
bin.close();

注:  DataInputStream&DataOutputStream还可以与FileInputStream&FileOutputStream
联合使用。
其中:
DataInputStream&DataOutputStream关心如何将数据从高层次的形式转化成低层次的形式.
FileInputStream&FileOutputStream关心如何操作存储单元以接受和产生数据。

 

编码:   字符串变成字节数组  string  ------------->byte[]

解码: 字节数组变成字符串。byte---------------->string

关于io的学习,还是要多用运才能不忘记,希望上面的一些小小的总结能给我和大家带来帮助。

 

 

 

 

 

 ---------------------- android培训java培训、期待与您交流! ----------------------