Java——读写文件

读写文件

       如果想要数据存储在硬盘中的文件和Web服务器中的文档,可使用java.io包中的类。其中的io表示input/output,这些类用于访问数据源,如硬盘、CD-ROM或计算机内存。可以使用称为流的通信系统,将数据传入程序或从程序中传出数据。

1、流

       要在Java程序中永久地保存数据或要检索已储存的数据,至少必须有一个流。流可以连接到各种数据源,包括计算机程序、硬盘、Internet服务器、计算机内存和DVD-ROM。由于他们都使用流,因此学会如何使用其中的一种数据后,就能够以相同的方式处理其他类型的数据。有如下两种类型的流:

       >输入流:从数据源读取数据;

       >输出流:讲数据写入数据源。

       所有输入和输出流都由字节(是0~255的整数)组成,可以用这种格式来表述数据,如可执行程序、字处理文档和MP3音乐文件,但这只是字节可表示的一小部分数据。直接留用于读写这种数据。

       字符流是一种更专用的流,顾名思义就是用来读写字符的,特别是读写文本数据源。

       无论是使用字节流、字符流还是其他类型的信息,整体过程是相同的:

       >创建一个与数据相关联的流对象;

       >调用流的方法,将信息加入流中或从流中取出信息;

       >调用流对象的close()方法关闭流。

       1)、文件

              在Java中,文件用File类表示,可以读取硬盘、CD-ROM或其他存储设备中的文件。File对象可表示已有的文件或要创建的文件,如下:

              File filename = new File(“xiaowu.txt”);

              这条语句在程序所在的文件夹下创建一个叫做xiaowu.txt的文件,也可以在文件中包括路径:

              Filefilename = new File(“test01\\data\\xiaowu.txt”);

       (注意:上述代码适用于windows系统,因为它使用反斜杠作为文件名和路径的分隔符。要在任何系统都适用,请使用File.pathSeparator,例如:

              File name = new File(“test01”+ File.pathSepataor + “xiaowu.txt”);)

       有了File对象后,就可以调用该对象的几个有用的方法:

             >exist():判断文件是否存在;

              >getName():返回文件名;

             >getAbsolutePath():获得文件名+文件的的绝对路径

              >length():将文件的长度作为long值返回;

              >createNewFile():如果文件不存在,创建它;

              >delete():如果文件存在,将删除他;

              >renameTo(File):适用通过参数指定的File对喜爱那个的名称来重命名文件;

              >mkdir()/mkdirs():如果路径中文件夹不存在,则创建最后一个文件夹/路径下的所有文件夹。

              也可以使用File对象表示系统中的文件夹而不是文件。为此,在构造函数File中指定文件夹名,这可以使绝对路径(如C:\\MyDocuments\\),也可以是相对路径(如java\\database)。有了代表文件夹的对象后,就可以调用其listFiles()方法来看文件夹的内容。该方法返回一个File对象数组,表示文件夹包含的每个文件和子文件夹。

       2)、从流中读取数据

              我们可以使用FileInputStream类从文件中读取字节的输入流。要创建文件输入流,可调用FileInputStream()构造函数并将一个文件名或File对象作为参数。注意创建输入流时对应的文件必须存在,否则将引发IOException异常。代码如下:

       

try {
            File filePath = new File("D:\\桌面\\桌面\\安卓开发工具\\学习笔记\\");
            File file = new File(filePath ,"xiaowu.txt");
            System.out.println(file.getName() +"");
            if (!filePath.exists() &&filePath.isDirectory()) {
                System.out.println("路径不存在");
                filePath.mkdirs();
            }
            else
            {
                System.out.println("路径存在");
                if (!file.exists()) {
                    System.out.println("文件不存在");
                    file.createNewFile();
                                   FileInputStream stream = newFileInputStream(file);
                }
                else{
                    System.out.println("文件存在");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

              代码很简单我就不讲了,有人可能会问文件刚创建里面没东西怎么读呢?其实这里是为了演示文件操作的过程才这样写的,这个不用管哈。

              读取输入流时,从流中的第一个字节开始读取,如文件的第一个字节。可以调用带有一个参数的skip()方法来跳过一些字节,该参数是一个int参数,表示要跳过的字节数,例如stream.skip(1024)就是跳过流中接下来的1024个字节。

              如果要一次读取多个字节,可以这样做:

              >创建一个字节数组,其大小等于要读取的字节数;

              >使用该数组作为参数调用read()方法,将使用从流中读取的字节填充该数组

              下面创建一个读取MP3音频文件的应用程序,并将读取到的内容打印出来:

      

try {
            File file = new File("D:\\桌面\\桌面\\安卓开发工具\\学习笔记\\", "碎玻璃声.MP3");
            FileInputStream fileInputStream =new FileInputStream(file);
            int size = (int)file.length();
            byte[] bt = new byte[128];
            String string = "";
            while (true) {               
                int temp =fileInputStream.read(bt);
                if (temp <= 0) break;
                string += new String(bt);
            }
            System.out.println("结果:" + string);
        } catch (Exception e) {
            e.printStackTrace();
        }finally{ fileInputStream.close();}

       3)、缓冲输入流

             对于读取输入流的程序,提高其性能的一个方法是将输入放到缓冲区中。缓冲(buffering)是将数据放到内存中供应用程序需要时使用的一个过程。当程序需要缓冲输入流中的数据时,将首先在缓冲区中查找,这比从文件等数据源读取数据快。

             要使用缓冲输入流,就要创建一个输入流如FileInputStream对象,然后使用该对象创建缓冲的流。为此,将输入流作为唯一的参数调用BufferedInputStream(InputStream)构造函数,这样从输入流中读取数据时,数据将被存储到缓冲区中。

             要从缓冲的流中读取数据,可调用其read()方法且不指定任何参数。这将返回一个0~255的整数,表示该流中下一字节的数据。如果没有字节可读取,将返回-1。

             下面是一个使用缓冲流读取文件的例子:

public classJavaApplication1

{

    public static String readLine()

    {

        StringBuffer response = newStringBuffer();

        try {

            File file = new File("D:\\桌面\\桌面\\安卓开发工具\\学习笔记\\碎玻璃声.MP3");

            FileInputStream fileInputStream =new FileInputStream(file);

            BufferedInputStream bin = newBufferedInputStream(fileInputStream);

            int in = 0;

           char inChar;

            do {               

                in = bin.read();

                inChar = (char)in;

                if (in != -1) {

                    response.append(inChar);

                }

            } while ((in != -1));

            bin.close();

            return  response.toString();

        } catch (Exception e) {

           System.err.println("Exception:" + e.getMessage());

            return null;

        }

    }

    

    public static void main(String[] args)

    {

        String input =JavaApplication1.readLine();

        System.out.println(input +"");

    }

}


       虽然看起来这段程序跟刚才那段很相似,但效率提高了不知多少倍。

2、将数据写入流中

       在java.io包中,与流相关的类都是成对出现的。对于字节流,有FileInputStream类和FileOutputStream类;对于字符流,有FileReader类和FileWriter类,还有很多其他成对的用于处理流数据的类。

      要将数据写入字节流中,首先需要创建一个与输出流相关联的File对象。该文件不必是系统中现有的文件。

      可以通过两种方式创建FileOutputStream。如果要在现在的文件中追加字节,使用两个参数调用构造函数FileOutputStream:一个是代表文件的File对象,另一个是布尔值true。这样写入流中的字节就会追加到文件的末尾。

      如果要讲字节写入一个新文件中,只使用一个File对象作为参数调用构造函数FileOutputStream()。

      有了输出流后就可以调用不同的write()方法来写入字节:

            >用一个字节作为参数调用write()方法时,将该字节写入流中。

            >用一个字节数组作为参数调用write()方法时,将该字节写入流中。

            >给write(byte[] , int ,int)方法指定3个参数:一个字节数组、一个表示要写入流中的数组的第一个元素的整数、要写入的字节总数。

      下面的语句创建一个包含10个字节的字节数组,并将最后5个字节写入到输出流中:

            File data = newFile("data.dat");

            FileOutputStream fileOutputStream =new FileOutputStream(data);

            byte[] dt = new byte[]{5, 12 , 4 ,13 , 3 , 15 , 2 , 17 , 1 , 18};

            fileOutputStream.write(dt , 5 , 5);

      将数据写入到流中后,调用流的close()方法关闭它。

             String name = “小武灵灵”;

             Byte[] name = name.getByte[];

      现在编写一个简单的应用程序,他通过将字节写入到文件输出流中的方式,将几行文本存储到一个文件中。代码如下:

public classJavaApplication1

{

    String newline =System.getProperty("line.separator");

    public JavaApplication1() {

        try {

            File file = new File("program.properties");

            FileOutputStream fileOutputStream =new FileOutputStream(file);

            write(fileOutputStream,"username = max");

            write(fileOutputStream, "score= 12550");

            write(fileOutputStream, "level= 5");

            

        } catch (Exception e) {

            System.err.println("不能写入文件");

        }

    }

    

    void write(FileOutputStream stream , Stringoutput) throws IOException

    {

        output += newline;

        byte[] data = output.getBytes();

        stream.write(data , 0 , data.length);

    }

    public static void main(String[] args)

    {

        JavaApplication1 application1 = newJavaApplication1();

        System.out.println("完毕");

    }

}


3、读写配置属性

       当使用命令行参数对Java程序进行配置之后,Java程序将更有用。Java.util包中有一个properties类,可用于从源文件中载入配置设置。

      在Java中,可以像其他文件那样读取属性文件:

             >创建一个代表该文件的File对象;

             >使用该File对象创建一个FileInputStream对象;

             >调用load()方法从输入流中检索属性。

      属性文件有一组属性名、等号和属性值组成,如下所示:

             Username = asd

             lastCommand = open database

             windowSize = 32

       每个属性占一行,因此上述内容将属性username、lastCommand和windowSize的值分别设置为asd、open database和32(我们自己建的类也是用相同的格式)

      下面的代码载入一个名为config.dat的属性文件:

             File configFile = new File("config.dat");

              FileInputStream fileInputStream = new FileInputStream(configFile);

              Properties config = new Properties();

             config.load(fileInputStream);

      配置设置也称为属性,作为字符串存储在Properties对象中。每个属性都用一个类似于applet参数的键标识。方法getProperty()根据键来检索属性,如下面的语句所示:

             String username = config.getProperty(“username”);

      由于属性被存储为字符串,要将其用作数字值,必须采用某种方式对其进行转换,如下面的代码所示:

             String windowProp = config.getProperty(“windowSize”);

             Int windowSize = 24;

             Try{

                    windowSize = Integer.parseInt(windowProp);

             }catch(NumberFormatException exception){}

      要存储属性,可调用setProperty()方法并指定两个参数——键和值:

            Config.setProperty(“username” , “asd”);

      可以调用Properties对象的list(PrintStream)方法来显示所有的属性。PrintStream是System类中out类的变量。下面的代码将调用list()方法来显示所有的属性。

             Config.list(System.out);

      在对属性做出修改之后,可将其存回到文件中:

             >创建一个代表文件的File对象;

            >根据该File对象创建一个FileOutputStream个;

             >调用方法store(OutputStream , String)将属性存储到指定的输出流中,而且参数String是属性文件的描述。

        接下来创建一个ConfigWrite应用程序,它将多个文件属性设置写入到一个文件中。而Configurator应用程序将这些属性设置读入到一个Java属性文件中,并添加一个名为runtime的心属性(具有当前日期和时间),然后保存该文件。下面是全部代码:

package javaapplication1;

 

import java.io.File;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.util.Date;

import java.util.Properties;

 

public class Configurator {

 

    public Configurator() {

        try {

            //载入properties文件

            File configFile = new File("program.properties");

            FileInputStream fileInputStream = new FileInputStream(configFile);

            Properties config = new Properties();

            config.load(fileInputStream);

            //创建一个新的property

            Date current = new Date();

            config.setProperty("runtime", current.toString());

            //保存properties文件

            FileOutputStream fileOutputStream = new FileOutputStream(configFile);

            config.store(fileOutputStream, "Properties settings");

            fileInputStream.close();

            config.list(System.out);

        } catch (Exception e) {

            System.out.println("IO error" + e.getMessage());

        }

    }

    

    public static void main(String[] args)

    {

        Configurator configurator = new Configurator();

    }

    

}


打开文件program.properties应该包含如下文本:

       #Properties settings

      #Fri Mar 22 00:14:38 CST 2013

      runtime=Fri Mar 22 00\:14\:38 CST 2013

      score=12550

      level=5

      username=max

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值