欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java實現(xiàn)較大二進制文件的讀、寫方法

 更新時間:2017年02月21日 14:06:39   作者:瑣碎之人  
本篇文章主要介紹了Java實現(xiàn)較大二進制文件的讀、寫方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

由于項目需要,需要對二進制文件進行讀寫、轉(zhuǎn)換。

文件說明:由其他程序得到的二進制文件,文件內(nèi)容為:包含23543個三角形、13270個頂點的三角網(wǎng)所對應(yīng)的721組流速矢量(u、v)文件,通俗些說,一條數(shù)據(jù)包含兩個雙精度型的數(shù)值,每組數(shù)組包含23543條數(shù)據(jù),如果以一個雙精度數(shù)值為單位,則總共有23543 * 721 * 2 =33,949,006條數(shù)據(jù)。由Fortran程序以每 8 Byte存儲一個數(shù)值的二進制文件存儲,最終文件大小為下圖所示:

              

測試:從該文件讀出數(shù)據(jù)之后,轉(zhuǎn)換為十進制,存儲到另一個文件中。

/**
 * 針對大文件存儲,請依次調(diào)用beginSave、AddSave、endSave。
 * 
 * @author CK
 *
 */
public class DataUtil {

  DataOutputStream BinaryOut=null;
  BufferedWriter TextOut=null;
  String FilePath=null;
  enum SaveFileType{Text,Binary};
  SaveFileType SaveFileType;

  /**
   * double轉(zhuǎn)byte[]
   * 
   * @param d
   * @return
   */
  public static byte[] double2Bytes(double d) {
    long value = Double.doubleToRawLongBits(d);
    byte[] byteRet = new byte[8];
    for (int i = 0; i < 8; i++) {
      byteRet[i] = (byte) ((value >> 8 * i) & 0xff);
    }
    return byteRet;
  }

  /**
   * byte[]轉(zhuǎn)double
   * 
   * @param arr
   * @return
   */
  public static double bytes2Double(byte[] arr) {
    long value = 0;
    for (int i = 0; i < 8; i++) {
      value |= ((long) (arr[i] & 0xff)) << (8 * i);
    }
    return Double.longBitsToDouble(value);
  }
  /**
   * 大型數(shù)據(jù)存儲之開始存儲
   * @param FilePath 文件路徑
   * @param saveFileType 保存的文件類型,文本文件、雙精度所存的二進制文件
   * @return
   * @throws IOException
   */
  public boolean BeginSave(String FilePath,SaveFileType saveFileType) throws IOException {
    if (FilePath == "" || FilePath == null) {
      System.out.println("the SavePath is null.");
      return false;
    }
    this.FilePath=FilePath;
    this.SaveFileType=saveFileType;
    File dataFile = new File(FilePath);
    if (!dataFile.getParentFile().exists()) {
      dataFile.getParentFile().mkdirs();
    }
    if (dataFile.exists()) {
      dataFile.delete();
    }
    dataFile.createNewFile();
    switch(this.SaveFileType){
    case Text:
      TextOut= new BufferedWriter(new FileWriter(dataFile,true));
      break;
    case Binary:
      BinaryOut = new DataOutputStream(new FileOutputStream(dataFile,true));
      break;
    default:
      break;
      
    }    
    return true;
  }
/**
 * 大型文件存儲之追加存儲
 * @param DataStr 若是文本存儲則無要求,若是雙精度的二進制文件,以若干空格隔開
 * @return
 * @throws IOException
 */
  public boolean AddSave(String DataStr) throws IOException{
    switch(this.SaveFileType){
    case Text:
      this.TextOut.append(DataStr);
      break;
    case Binary:
      DataStr=DataStr.trim();
      String[] dataArray=DataStr.split("\\s+");
      for(int i=0;i<dataArray.length;i++){
        this.BinaryOut.write(double2Bytes(Double.parseDouble(dataArray[i])));
      }          
      break;
    default:
      break;
    
    }
    
    return true;
  }
  /**
   * 大型文件存儲之結(jié)束保存,清空緩存、關(guān)閉文件。
   * @return
   * @throws IOException
   */
  public boolean EndSave() throws IOException{
    switch(this.SaveFileType){
    case Text:
      this.TextOut.flush();
      this.TextOut.close();
      break;
    case Binary:
      this.BinaryOut.flush();
      this.BinaryOut.close();
      break;
    default:
      break;    
    }
    
    return true;
  }
 /**
   * 將字符串保存為文本文件(一次完成)
   * 
   * @param DataStr
   *      文件內(nèi)容
   * @param SavePath
   *      文件路徑,包含文件名、后綴
   * @return
   * @throws IOException
   */
  public boolean saveTextFile(String DataStr, String SavePath)
      throws IOException {
    if (DataStr == "" || DataStr == null) {
      System.out.println("the dataStr is null.");
      return false;
    }
    if (SavePath == "" || SavePath == null) {
      System.out.println("the SavePath is null.");
      return false;
    }
    File dataFile = new File(SavePath);
    if (!dataFile.getParentFile().exists()) {
      dataFile.getParentFile().mkdirs();
    }
    if (dataFile.exists()) {
      dataFile.delete();
    }
    dataFile.createNewFile();
    BufferedWriter out;

    out = new BufferedWriter(new FileWriter(dataFile));

    out.append(DataStr);
    out.flush();
    out.close();

    return true;
  }

  /**
   * 雙精度存為二進制數(shù)據(jù)(一次存儲)
   * 
   * @param DataStr 雙精度數(shù)據(jù)組成的字符串,以若干空格隔開
   * @param OutputPath
   * @return
   * @throws IOException
   */
  public boolean saveBinaryFile(String DataStr, String OutputPath) throws IOException {

    if (DataStr == "" || DataStr == null) {
      System.out.println("the dataStr is null.");
      return false;
    }
    if (OutputPath == "" || OutputPath == null) {
      System.out.println("the OutputPath is null.");
      return false;
    }
    File dataFile = new File(OutputPath);

    if (!dataFile.getParentFile().exists()) {
      dataFile.getParentFile().mkdirs();
    }
    if (dataFile.exists()) {
      dataFile.delete();
    }
    dataFile.createNewFile();
    DataOutputStream out;
    out = new DataOutputStream(new FileOutputStream(dataFile));
    // 數(shù)據(jù)處理
    DataStr=DataStr.trim();
    String[] dataArray=DataStr.split("\\s+");
    for(int i=0;i<dataArray.length;i++){
      out.write(double2Bytes(Double.parseDouble(dataArray[i])));
    }    
    out.flush();
    out.close();
    return true;

  }
}

代碼說明:其中byte[]與double互轉(zhuǎn)為在互聯(lián)網(wǎng)上查到的方法,具體是哪位大神的我忘記了,在這里為了記錄就貼出來啦,上述代碼包含了處理小型文件時,將所有內(nèi)容存在緩存中,之后再一次性寫入文本文件、二進制文件中的方法,還包含了對較大型文件的讀寫方法,下面是自己的一個讀寫測試。

/**
 * 測試二進制大文件讀寫(200M左右)
 * @author ck
 *
 */
public class FileTest {
  static String inputFilePath=""; //輸入文件路徑,包含文件名后綴
  static String outputFilePath=""; //輸出文件名,包含文件名后綴
  
  public static void file2file() throws IOException{
    DataUtil dataUtil=new DataUtil(); 
     DataInputStream br=new DataInputStream( 
         new BufferedInputStream( 
         new FileInputStream(inputFilePath))); 
        dataUtil.BeginSave(outputFilePath, SaveFileType.Text); //初始化,創(chuàng)建文件,采用文件追加存儲的思路
         byte[] oneData=new byte[8];
         int i=0,count =0 ;
        while(br.read(oneData, 0, 8)!=-1){  
          i=i+1;
          dataUtil.AddSave(String.valueOf(DataUtil.bytes2Double(oneData)));          
          if(i/23543==0){
            count++;
            System.out.println(count+"\n");

          }
        }
        dataUtil.EndSave();    //將還在緩存中的數(shù)據(jù)寫入到文件中,關(guān)閉文件。 
  }
}

 此次測試代碼很快就run完了,但是輸出文件的生成大概用了近半分鐘(刻意秒表計時了一次),嘗試用一次性讀寫的辦法,卡很久,也沒有出結(jié)果。所得的十進制文本文件,大小為這么多:

我想,原來Fortran程序作者的初衷應(yīng)該是覺得二進制存儲比十進制節(jié)省空間吧,事實上也確實節(jié)省了一半多的空間。

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java中的CyclicBarrier、CountDownLatch和Semaphore的具體使用

    Java中的CyclicBarrier、CountDownLatch和Semaphore的具體使用

    本文主要介紹了Java中的CyclicBarrier、CountDownLatch和Semaphore的具體使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-05-05
  • SpringBoot中如何打印Http請求日志

    SpringBoot中如何打印Http請求日志

    所有針對第三方的請求都強烈推薦打印請求日志,本文主要介紹了SpringBoot中如何打印Http請求日志,具有一定的參考價值,感興趣的可以了解一下
    2024-06-06
  • java編程幾行代碼實現(xiàn)買菜自由

    java編程幾行代碼實現(xiàn)買菜自由

    這篇文章主要為大家介紹了java編程幾行代碼實現(xiàn)買菜自由,需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-05-05
  • java如何獲取視頻文件的編解碼器代碼示例

    java如何獲取視頻文件的編解碼器代碼示例

    這篇文章主要給大家介紹了關(guān)于java如何獲取視頻文件的編解碼器的相關(guān)資料,文中通過代碼介紹的非常詳細,對大家學習或者使用java具有一定的參考借鑒價值,需要的朋友可以參考下
    2024-05-05
  • List、Map、Set接口在Java中的存取元素特點詳細探討

    List、Map、Set接口在Java中的存取元素特點詳細探討

    在Java編程語言中集合框架是處理對象組的重要工具,主要包括List、Set和Map接口,這些接口及其實現(xiàn)類提供了豐富的功能,這篇文章主要給大家介紹了關(guān)于List、Map、Set接口在Java中的存取元素特點,需要的朋友可以參考下
    2024-08-08
  • java中MultipartFile互轉(zhuǎn)File的方法

    java中MultipartFile互轉(zhuǎn)File的方法

    本文主要介紹了java中MultipartFile互轉(zhuǎn)File的方法,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • 使用java執(zhí)行定時任務(wù)示例

    使用java執(zhí)行定時任務(wù)示例

    這篇文章主要介紹了使用java執(zhí)行定時任務(wù)示例,需要的朋友可以參考下
    2014-04-04
  • Spring Boot定時任務(wù)單線程多線程實現(xiàn)代碼解析

    Spring Boot定時任務(wù)單線程多線程實現(xiàn)代碼解析

    這篇文章主要介紹了Spring Boot定時任務(wù)單線程多線程實現(xiàn)代碼解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-08-08
  • SpringMVC中轉(zhuǎn)發(fā)與重定向的區(qū)別淺析

    SpringMVC中轉(zhuǎn)發(fā)與重定向的區(qū)別淺析

    這篇文章主要給大家介紹了關(guān)于SpringMVC中轉(zhuǎn)發(fā)與重定向的區(qū)別,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-12-12
  • 如何在springboot中使用定時任務(wù)

    如何在springboot中使用定時任務(wù)

    這篇文章主要介紹了如何在springboot中使用定時任務(wù),幫助大家更好的理解和使用springboot框架,感興趣的朋友可以了解下
    2020-12-12

最新評論