1. 程式人生 > >如何在windows下和linux下獲取檔案(如exe檔案)的詳細資訊和屬性

如何在windows下和linux下獲取檔案(如exe檔案)的詳細資訊和屬性

程式設計師都很懶,你懂的!

最近在專案開發中,由cs開發的exe的程式,需要自動升級,該exe程式放在linux下,自動升級時檢測不到該exe程式的版本號資訊,但是我們客戶端的exe程式需要獲取伺服器上新程式的版本號資訊。最後由我用java實現linux上exe檔案的版本號讀取功能。下面是詳細程式碼:

package com.herman.utils;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
/**
 * @see 獲取檔案資訊的工具類
 * @author Herman.Xiong
 * @date 2014年5月12日 15:01:26
 * @version V1.0
 * @since tomcat 6.0 , jdk 1.6
 */
public class FileUtil {
	/**
	 * @see 獲取版本資訊
	 * @param filePath
	 * @return
	 */
	public static String getVersion(String filePath) {
		File file = new File(filePath);
		RandomAccessFile raf = null;
		byte[] buffer;
		String str;
		try {
			raf = new RandomAccessFile(file, "r");
			buffer = new byte[64];
			raf.read(buffer);
			str = "" + (char) buffer[0] + (char) buffer[1];
			if (!"MZ".equals(str)) {
				return null;
			}

			int peOffset = unpack(new byte[] { buffer[60], buffer[61],
					buffer[62], buffer[63] });
			if (peOffset < 64) {
				return null;
			}

			raf.seek(peOffset);
			buffer = new byte[24];
			raf.read(buffer);
			str = "" + (char) buffer[0] + (char) buffer[1];
			if (!"PE".equals(str)) {
				return null;
			}
			int machine = unpack(new byte[] { buffer[4], buffer[5] });
			if (machine != 332) {
				return null;
			}

			int noSections = unpack(new byte[] { buffer[6], buffer[7] });
			int optHdrSize = unpack(new byte[] { buffer[20], buffer[21] });
			raf.seek(raf.getFilePointer() + optHdrSize);
			boolean resFound = false;
			for (int i = 0; i < noSections; i++) {
				buffer = new byte[40];
				raf.read(buffer);
				str = "" + (char) buffer[0] + (char) buffer[1]
						+ (char) buffer[2] + (char) buffer[3]
						+ (char) buffer[4];
				if (".rsrc".equals(str)) {
					resFound = true;
					break;
				}
			}
			if (!resFound) {
				return null;
			}

			int infoVirt = unpack(new byte[] { buffer[12], buffer[13],
					buffer[14], buffer[15] });
			int infoSize = unpack(new byte[] { buffer[16], buffer[17],
					buffer[18], buffer[19] });
			int infoOff = unpack(new byte[] { buffer[20], buffer[21],
					buffer[22], buffer[23] });
			raf.seek(infoOff);
			buffer = new byte[infoSize];
			raf.read(buffer);
			int numDirs = unpack(new byte[] { buffer[14], buffer[15] });
			boolean infoFound = false;
			int subOff = 0;
			for (int i = 0; i < numDirs; i++) {
				int type = unpack(new byte[] { buffer[i * 8 + 16],
						buffer[i * 8 + 17], buffer[i * 8 + 18],
						buffer[i * 8 + 19] });
				if (type == 16) { // FILEINFO resource
					infoFound = true;
					subOff = unpack(new byte[] { buffer[i * 8 + 20],
							buffer[i * 8 + 21], buffer[i * 8 + 22],
							buffer[i * 8 + 23] });
					break;
				}
			}
			if (!infoFound) {
				return null;
			}

			subOff = subOff & 0x7fffffff;
			infoOff = unpack(new byte[] { buffer[subOff + 20],
					buffer[subOff + 21], buffer[subOff + 22],
					buffer[subOff + 23] }); // offset of first FILEINFO
			infoOff = infoOff & 0x7fffffff;
			infoOff = unpack(new byte[] { buffer[infoOff + 20],
					buffer[infoOff + 21], buffer[infoOff + 22],
					buffer[infoOff + 23] }); // offset to data
			int dataOff = unpack(new byte[] { buffer[infoOff],
					buffer[infoOff + 1], buffer[infoOff + 2],
					buffer[infoOff + 3] });
			dataOff = dataOff - infoVirt;

			int version1 = unpack(new byte[] { buffer[dataOff + 48],
					buffer[dataOff + 48 + 1] });
			int version2 = unpack(new byte[] { buffer[dataOff + 48 + 2],
					buffer[dataOff + 48 + 3] });
			int version3 = unpack(new byte[] { buffer[dataOff + 48 + 4],
					buffer[dataOff + 48 + 5] });
			int version4 = unpack(new byte[] { buffer[dataOff + 48 + 6],
					buffer[dataOff + 48 + 7] });
			System.out.println(version2 + "." + version1 + "." + version4 + "."
					+ version3);
			return version2 + "." + version1 + "." + version4 + "." + version3;
		} catch (FileNotFoundException e) {
			return null;
		} catch (IOException e) {
			return null;
		} finally {
			if (raf != null) {
				try {
					raf.close();
				} catch (IOException e) {
				}
			}
		}
	}

	public static int unpack(byte[] b) {
		int num = 0;
		for (int i = 0; i < b.length; i++) {
			num = 256 * num + (b[b.length - 1 - i] & 0xff);
		}
		return num;
	}
}
執行效果圖(window上和linux的filePath自己改正正確即可):


點選下載詳細的演示專案http://download.csdn.net/detail/xmt1139057136/7335155

相關推薦

何在windowslinux獲取檔案(exe檔案)的詳細資訊屬性

程式設計師都很懶,你懂的! 最近在專案開發中,由cs開發的exe的程式,需要自動升級,該exe程式放在linux下,自動升級時檢測不到該exe程式的版本號資訊,但是我們客戶端的exe程式需要獲取伺服器上新程式的版本號資訊。最後由我用java實現linux上exe檔案的版本號

何在WindowsLinux獲取當前執行緒的ID號

Linux下獲取當前執行緒ID號函式: pthread_t pthread_self(); 返回:當前執行緒的ID號 pthread_t 資料型別的定義如下: typedef unsigned long int pthread_t; sizeof(pthread_t) =

windowslinux讀取檔案換行符的一個坑——\r\n\n

      拿同事的一個windows下的C程式,在Linux下跑,結果不正確。定位為讀取.ini配置檔案錯誤。該配置檔案是在windows下編輯的,網上查到資料,說是windows和linux下對換行符處理不同導致的。      

maven打包pom檔案節點在windowslinux的格式差異

<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>mave

hadoop安裝步驟之:windowslinux的hosts檔案的使用

1,linux下hosts檔案在:/etc/hosts,切換到root使用者下新增節點。 如配置hadoop叢集時,將主機ip和主機名的對應關係寫到hosts檔案末尾後,就可以在配置檔案中方便的用主機名來代替繁瑣的ip地址了。 內容形式如下: 192.168.188.16

Windows Linux 生成以當前時間命名的檔案

 在 Windows、Linux 作業系統,分別利用BAT批處理檔案和Shell指令碼,生成類似“20110228_082905.txt”以“年月日_時分秒”命名的檔案。   Windows BAT批處理檔案: @echo off set time_hh=%time:~0,2

maven打包pom檔案windowslinux的格式差異

<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><versio

獲取C++異常的名稱 (WindowsLinux)

前一陣子在群裡探討到C++異常上能否應用模板,目前來看答案是不能。但是難道異常就不能更靈活一些麼?難道只能try...catch已知的基於類繼承體系的異常,對未知的異常re-throw麼?(雖然那是經典且正確的方法)經過一番探索,找到了某些黑魔法。先來看一段程式碼:int t

windowsLinux定時啟動或關閉服務

ref sta article start 處理程序 window pin blog win http://blog.csdn.net/clare504/article/details/17410643 1、Windows下的定時啟動程序可以采用系統的計劃和任務,定時

windowslinux的抓包工具

gpo tcpdump linu window clas dst post blog windows Linux 抓包工具 tcpdump 示例 tcpdump -i bond0 host 10.70.11.182 -w ./sms.cap windows抓包

windowsLinux安裝nodejs

兩個文件 tro window 顯示 name 測試 分享 如圖所示 運行 在windows下安裝nodejs 1.首先下載nodejs安裝包, https://nodejs.org/en/download/ 點擊下載相應的版本 然後將文件夾解壓到安裝目錄(任

python在windowslinux的安裝配置

str net .net cat ria 技術 連接 top 成功 一、windows下安裝python3.6 安裝編輯器:Ecplise+pydev插件 Eclipse是寫JAVA的IDE, 這樣就可以通用了,學習代價小。 學會了Eclipse, 以後寫Pytho

SpringBoot熱部署linux通過vim修改jar裡面的檔案

解決問題: 1、在專案測試或者部署後,經常會遇到需要更改一些配置檔案或者java類,這時使用SpringBoot熱部署可以快速的修改後重啟,方便開發測試; 2、在專案上線後,會遇到一些需要修改的地方,使用linux下的vim工具可以快速的修改已部署好的專案。 一、引入熱部署依賴 &l

ffmpeg windowslinux轉換格式

import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList;

webpack build 在windowsLinuxbuild需注意路徑的大小寫

如:route/index.js 實際路徑:/page/WanHG/index.vue 在index.js中寫法 const ImageList = () => import('/page/Admin/imgaeList.vue') const WanHgIndex = (

Windows的路徑分隔符Linux的路徑分隔符是不一樣的

比如說要在temp目錄下建立一個test.txt檔案,在Windows下應該這麼寫: File file1 = new File ("C:\tmp\test.txt"); 在Linux下則是這樣的: File file2 = new File ("/tmp/test.txt"); 如果要考慮跨平

Mysql 在 windows linux 的安裝配置

這篇文章講解 Mysql 在 Windows 下的手動安裝和在 Linux(CentOs) 下的下載、配置、連線。還包括預設字符集等的設定。 首先,都要執行移除資料庫的操作 mysqld --remov

Windows linux CUnit編譯安裝教程

本文大部分均參看以下連結,安裝當中有些地方不詳細,我添加了 首先要安裝mingw和msys,下載地址:點選開啟連結 1. 安裝  1)準備環境:Win7安裝MinGW 1.1)Win7已就緒 1.2)下載 MinGW:www.mingw.org =>

C++ Boost在WindowsLinux的編譯安裝

C++作為歷史上最成功的語言之一,除了它具有面向物件的性質之外,還有一個非常重要的創新,那就是泛型程式設計。泛型的思想其實是為所有問題提供一個解決方案的模版,程式設計師只需把每次的具體問題放到模版裡面,那麼就可以獲得該問題的解決方案,利用模版做到具體問題具體分析。C++ STL毫無疑問是泛型思想的一

不區分大小寫的串比較---Windows的stricmpLinux的strcasecmp

 不區分大小寫的串比較, 在實戰中的應用還是很廣泛的, 有時候可以增強程式的容錯性, 下面我們來分別看看Windows下的stricmp和Linux下的strcasecmp       Windows下的stricmp: #in