alexlifan 发表于 2012-08-17 04:29

Java读binary file

大家好,我有下列perl程序, $input_file是binary file:

open( IN, $input_file );
binmode IN;
undef $/;
$content = unpack("H*",<IN>);
close IN;

我要把这段写成java, 大家有什么建议?

这是我写的, 问题是速度很慢, perl用了几乎1秒钟不到,但java要将近1小时。

FileInputStream in= new FileInputStream(input);
int strLine;
while((strLine = in.read()) != -1){
    if (strLine<16){
                                    content += Integer.toHexString(0);
                                    content += Integer.toHexString(strLine);
                            }else{
                                    content += Integer.toHexString(strLine);
                            }
                  }

请大家帮忙~谢谢!

_Rayx 发表于 2012-08-17 14:18

呃,差别没这么大吧?
读取文件最好用一下缓冲。

而且你的操作:
{
                                    content += Integer.toHexString(0);
                                    content += Integer.toHexString(strLine);
                            }else{
                                    content += Integer.toHexString(strLine);
                            }
也是很费时间的,因为String是不可更改的对象。
优化一下就没啥问题了。

isaacxu 发表于 2012-08-17 18:55

不太明白,为何读取时间差距这么大。随便剽了几段程序,测试了一下Java对Binary文件的读取,感觉不是Java本身的问题。测试的程序是读取一个有1百万数据的文本文件,然后生成Binary文件,接着读取这个Binary文件,并将结果输出的另一个文件里。上述两次读,两次写,总共耗时不到3秒。测试数据文件largeT.txt在algs4-data.zip这个包里。/**
* File:ReadWriteBF.java
* -------------------------
* Read from a large txt file ,have 1000000 data, and create a binary file;
* Then Read created binary file, write a binary file again
* total cost less 3 seconds
*/
package org.cudemo;

import java.io.*;

import org.cudemo.In;
/**
* @author isaacxu
*
*/
public class ReadWriteBF {
        private static String filename = "data.bf";
        private static String copyfilename = "back.bf";
        private static String largefilename="largeT.txt";//1000000 data
        /**
       * @param args
       */
        public static void main(String[] args) {
                //read a txt file for create a binary file
                double[] numberlist = In.readDoubles(largefilename);
                //Create a binary file
                writeToBinary(numberlist, filename);
                //read a binary file               
      double[] readD = readFromBinaryFile(filename);
      writeToBinary(readD, copyfilename);
      
       //print to console what about Binary file, cost 5 minutes
      //for(double i:readD){
                //System.out.println(i);
                //}*/

        }
        //read a binary file
       @SuppressWarnings ("unchecked")
          public static <T> T readFromBinaryFile(String filename) {
                T obj = null;
                File file = new File(filename);
                if (file.exists()) {
                    ObjectInputStream ois = null;
                    try {
                      ois = new ObjectInputStream(new FileInputStream(filename));
                      obj = (T)ois.readObject();
                    } catch (IOException e) {
                    } catch (ClassNotFoundException e) {
                    } finally {
                      try {
                            if (ois != null)
                                ois.close();
                      } catch (IOException e) {
                      }
                    }
                }
                return obj;
          }
   //write a binary file
          public static <T> void writeToBinary(T obj, String filename)
          {
                try {
                    FileOutputStream fis = new FileOutputStream(filename);
                    ObjectOutputStream oos = new ObjectOutputStream(fis);
                    oos.writeObject(obj);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
          }

}
/*************************************************************************
*Compilation:javac In.java
*Execution:    java In
*
*Reads in data of various types from: stdin, file, URL.
*
*% java In
*
*Remarks
*-------
*    - isEmpty() returns true if there is no more input or
*      it is all whitespace. This might lead to surprising behavior
*      when used with readChar()
*
*************************************************************************/
package org.cudemo;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.net.URL;
import java.net.URLConnection;
import java.util.Locale;
import java.util.Scanner;


/**
*<i>Input</i>. This class provides methods for reading strings
*and numbers from standard input, file input, URL, and socket.
*<p>
*The Locale used is: language = English, country = US. This is consistent
*with the formatting conventions with Java floating-point literals,
*command-line arguments (via <tt>Double.parseDouble()</tt>)
*and standard output (via <tt>System.out.print()</tt>). It ensures that
*standard input works the number formatting used in the textbook.
*<p>
*For additional documentation, see <a href="http://introcs.cs.princeton.edu/31datatype">Section 3.1</a> of
*<i>Introduction to Programming in Java: An Interdisciplinary Approach</i> by Robert Sedgewick and Kevin Wayne.
*/
public final class In {
    private Scanner scanner;

    // assume Unicode UTF-8 encoding
    //private String charsetName = "UTF-8";

    private String charsetName = "ISO-8859-1";

    // assume language = English, country = US for consistency with System.out.
    private Locale usLocale = new Locale("en", "US");

   /**
   * Create an input stream for standard input.
   */
    public In() {
      scanner = new Scanner(new BufferedInputStream(System.in), charsetName);
      scanner.useLocale(usLocale);
    }

   /**
   * Create an input stream from a socket.
   */
    public In(Socket socket) {
      try {
            InputStream is = socket.getInputStream();
            scanner = new Scanner(new BufferedInputStream(is), charsetName);
            scanner.useLocale(usLocale);
      }
      catch (IOException ioe) {
            System.err.println("Could not open " + socket);
      }
    }

   /**
   * Create an input stream from a URL.
   */
    public In(URL url) {
      try {
            URLConnection site = url.openConnection();
            InputStream is   = site.getInputStream();
            scanner            = new Scanner(new BufferedInputStream(is), charsetName);
            scanner.useLocale(usLocale);
      }
      catch (IOException ioe) {
            System.err.println("Could not open " + url);
      }
    }

   /**
   * Create an input stream from a file.
   */
    public In(File file) {

      try {
            scanner = new Scanner(file, charsetName);
            scanner.useLocale(usLocale);
      }
      catch (IOException ioe) {
            System.err.println("Could not open " + file);
      }
    }


   /**
   * Create an input stream from a filename or web page name.
   */
    public In(String s) {

      try {
            // first try to read file from local file system
            File file = new File(s);
            if (file.exists()) {
                scanner = new Scanner(file, charsetName);
                scanner.useLocale(usLocale);
                return;
            }

            // next try for files included in jar
            URL url = getClass().getResource(s);

            // or URL from web
            if (url == null) { url = new URL(s); }

            URLConnection site = url.openConnection();
            InputStream is   = site.getInputStream();
            scanner            = new Scanner(new BufferedInputStream(is), charsetName);
            scanner.useLocale(usLocale);
      }
      catch (IOException ioe) {
            System.err.println("Could not open " + s);
      }
    }

   /**
   * Does the input stream exist?
   */
    public boolean exists(){
      return scanner != null;
    }

   /**
   * Is the input stream empty?
   */
    public boolean isEmpty() {
      return !scanner.hasNext();
    }

   /**
   * Does the input stream have a next line?
   */
    public boolean hasNextLine() {
      return scanner.hasNextLine();
    }

   /**
   * Read and return the next line.
   */
    public String readLine() {
      String line;
      try               { line = scanner.nextLine(); }
      catch (Exception e) { line = null;               }
      return line;
    }

   /**
   * Read and return the next character.
   */
    public char readChar() {
      // (?s) for DOTALL mode so . matches any character, including a line termination character
      // 1 says look only one character ahead
      // consider precompiling the pattern
      String s = scanner.findWithinHorizon("(?s).", 1);
      return s.charAt(0);
    }



    // return rest of input as string
   /**
   * Read and return the remainder of the input as a string.
   */
    public String readAll() {
      if (!scanner.hasNextLine()) { return null; }

      // reference: http://weblogs.java.net/blog/pat/archive/2004/10/stupid_scanner_1.html
      return scanner.useDelimiter("\\A").next();
    }



   /**
   * Return the next string from the input stream.
   */
    public StringreadString() {
      return scanner.next();
    }

   /**
   * Return the next int from the input stream.
   */
    public int readInt() {
      return scanner.nextInt();
    }

   /**
   * Return the next double from the input stream.
   */
    public double readDouble() {
      return scanner.nextDouble();
    }

   /**
   * Return the next float from the input stream.
   */
    public double readFloat() {
      return scanner.nextFloat();
    }

   /**
   * Return the next long from the input stream.
   */
    public long readLong() {
      return scanner.nextLong();
    }

   /**
   * Return the next byte from the input stream.
   */
    public byte readByte() {
      return scanner.nextByte();
    }


   /**
   * Return the next boolean from the input stream, allowing "true" or "1"
   * for true and "false" or "0" for false.
   */
    public boolean readBoolean() {
      String s = readString();
      if (s.equalsIgnoreCase("true"))return true;
      if (s.equalsIgnoreCase("false")) return false;
      if (s.equals("1"))               return true;
      if (s.equals("0"))               return false;
      throw new java.util.InputMismatchException();
    }

   /**
   * Read ints from file
   */
    public static int[] readInts(String filename) {
      In in = new In(filename);
      String[] fields = in.readAll().trim().split("\\s+");
      int[] vals = new int;
      for (int i = 0; i < fields.length; i++)
            vals = Integer.parseInt(fields);
      return vals;
    }

   /**
   * Read doubles from file
   */
    public static double[] readDoubles(String filename) {
      In in = new In(filename);
      String[] fields = in.readAll().trim().split("\\s+");
      double[] vals = new double;
      for (int i = 0; i < fields.length; i++)
            vals = Double.parseDouble(fields);
      return vals;
    }

   /**
   * Read strings from a file
   */
    public static String[] readStrings(String filename) {
      In in = new In(filename);
      String[] fields = in.readAll().trim().split("\\s+");
      return fields;
    }

   /**
   * Read ints from standard input
   */
    public static int[] readInts() {
      In in = new In();
      String[] fields = in.readAll().trim().split("\\s+");
      int[] vals = new int;
      for (int i = 0; i < fields.length; i++)
            vals = Integer.parseInt(fields);
      return vals;
    }

   /**
   * Read doubles from standard input
   */
    public static double[] readDoubles() {
      In in = new In();
      String[] fields = in.readAll().trim().split("\\s+");
      double[] vals = new double;
      for (int i = 0; i < fields.length; i++)
            vals = Double.parseDouble(fields);
      return vals;
    }

   /**
   * Read strings from standard input
   */
    public static String[] readStrings() {
      In in = new In();
      String[] fields = in.readAll().trim().split("\\s+");
      return fields;
    }

   /**
   * Close the input stream.
   */
    public void close() { scanner.close();}



   /**
   * Test client.
   */
    public static void main(String[] args) {
      In in;
      String urlName = "http://introcs.cs.princeton.edu/stdlib/InTest.txt";

      // read from a URL
      System.out.println("readAll() from URL " + urlName);
      System.out.println("---------------------------------------------------------------------------");
      try {
            in = new In(urlName);
            System.out.println(in.readAll());
      }
      catch (Exception e) { System.out.println(e); }
      System.out.println();

      // read one line at a time from URL
      System.out.println("readLine() from URL " + urlName);
      System.out.println("---------------------------------------------------------------------------");
      try {
            in = new In(urlName);
            while (!in.isEmpty()) {
                String s = in.readLine();
                System.out.println(s);
            }
      }
      catch (Exception e) { System.out.println(e); }
      System.out.println();

      // read one string at a time from URL
      System.out.println("readString() from URL " + urlName);
      System.out.println("---------------------------------------------------------------------------");
      try {
            in = new In(urlName);
            while (!in.isEmpty()) {
                String s = in.readString();
                System.out.println(s);
            }
      }
      catch (Exception e) { System.out.println(e); }
      System.out.println();


      // read one line at a time from file in current directory
      System.out.println("readLine() from current directory");
      System.out.println("---------------------------------------------------------------------------");
      try {
            in = new In("./InTest.txt");
            while (!in.isEmpty()) {
                String s = in.readLine();
                System.out.println(s);
            }
      }
      catch (Exception e) { System.out.println(e); }
      System.out.println();


      // read one line at a time from file using relative path
      System.out.println("readLine() from relative path");
      System.out.println("---------------------------------------------------------------------------");
      try {
            in = new In("../stdlib/InTest.txt");
            while (!in.isEmpty()) {
                String s = in.readLine();
                System.out.println(s);
            }
      }
      catch (Exception e) { System.out.println(e); }
      System.out.println();

      // read one char at a time
      System.out.println("readChar() from file");
      System.out.println("---------------------------------------------------------------------------");
      try {
            in = new In("InTest.txt");
            while (!in.isEmpty()) {
                char c = in.readChar();
                System.out.print(c);
            }
      }
      catch (Exception e) { System.out.println(e); }
      System.out.println();
      System.out.println();

      // read one line at a time from absolute OS X / Linux path
      System.out.println("readLine() from absolute OS X / Linux path");
      System.out.println("---------------------------------------------------------------------------");
      in = new In("/n/fs/csweb/introcs/stdlib/InTest.txt");
      try {
            while (!in.isEmpty()) {
                String s = in.readLine();
                System.out.println(s);
            }
      }
      catch (Exception e) { System.out.println(e); }
      System.out.println();


      // read one line at a time from absolute Windows path
      System.out.println("readLine() from absolute Windows path");
      System.out.println("---------------------------------------------------------------------------");
      try {
            in = new In("G:\\www\\introcs\\stdlib\\InTest.txt");
            while (!in.isEmpty()) {
                String s = in.readLine();
                System.out.println(s);
            }
            System.out.println();
      }
      catch (Exception e) { System.out.println(e); }
      System.out.println();

    }

}
页: [1]
查看完整版本: Java读binary file