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);
}
}
请大家帮忙~谢谢! 呃,差别没这么大吧?
读取文件最好用一下缓冲。
而且你的操作:
{
content += Integer.toHexString(0);
content += Integer.toHexString(strLine);
}else{
content += Integer.toHexString(strLine);
}
也是很费时间的,因为String是不可更改的对象。
优化一下就没啥问题了。 不太明白,为何读取时间差距这么大。随便剽了几段程序,测试了一下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]