Java讀寫二進位制檔案到String,再寫入二進位制檔案
概述
java讀寫檔案的有很多種方式,基本都是採用java.io的inputStream和各種基於inputstream的封裝實現對檔案的讀寫,最原始的介面提供的便是基於byte的讀寫,而String可以看做是char[],一個char是8個byte。在最原始的ASCII編碼中,我們採用一個位元組 也就時8位來表示一個字元(圖形字元或者控制字元),而後來1個位元組不足以表示現實中的所有字元,於是出現了各種各樣的編碼格式,常見的比如UTF-8,GBK,UNICODE等。java中的string也是遵循jre中定義的預設字符集(基本為UTF-8),而在byte[]轉化成String的過程中可能會由於編碼字符集問題導致String逆向回來的byte[]與原來的陣列不一致。
問題描述
使用Java 讀取一個zip檔案,轉化成String從客戶端傳輸到伺服器,客戶端儲存到本地檔案中,發現客戶端得到zip檔案不能使用,提示檔案損壞或者結尾損壞。比較原始檔和生成檔案的字元,發現字元不一致。
測試程式
public class Test_Keyczar {
public static void main(String[] args) {
try {
byte[] out = readFileInBytesToString("D:\\下載\\a+b.zip");
File outfile = new File("D:\\下載\\a-b1221.zip");
if (!outfile.exists()) {
outfile.createNewFile();
}
DataOutputStream fw = new DataOutputStream(new FileOutputStream(
outfile));
fw.write(new String(out).getBytes());
fw.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static byte[] readFileInBytesToString(String filePath) {
final int readArraySizePerRead = 4096;
File file = new File(filePath);
ArrayList<Byte> bytes = new ArrayList<>();
try {
if (file.exists()) {
DataInputStream isr = new DataInputStream(new FileInputStream(
file));
byte[] tempchars = new byte[readArraySizePerRead];
int charsReadCount = 0;
while ((charsReadCount = isr.read(tempchars)) != -1) {
for(int i = 0 ; i < charsReadCount ; i++){
bytes.add (tempchars[i]);
}
}
isr.close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return toPrimitives(bytes.toArray(new Byte[0]));
}
static byte[] toPrimitives(Byte[] oBytes) {
byte[] bytes = new byte[oBytes.length];
for (int i = 0; i < oBytes.length; i++) {
bytes[i] = oBytes[i];
}
return bytes;
}
}
測試結果
- 如果以byte[]讀入檔案 不加修改直接寫入檔案,原始檔和生成檔案一致
- 如果以byte[]讀入檔案 採用new String(byte[])的方式轉化成String,之後在用String.getBytes()的方式轉化為byte[]寫檔案,原始檔和生成檔案字元不一致
問題原因分析
java的預設字符集為UTF-8,所以在new String(byte[])的時候發生了字符集的轉化,在原始的二進位制檔案中,字元是按照ascii的形式組織的,而utf-8採用的是一種可變長的編碼,對於原始的ascii的資料的解碼會導致字元陣列的改變,而在String.getBytes()也是得到經過UTF-8編碼過後的字元陣列。
解決方案
為了排除字符集的問題,可以採用以下兩種方案
- 以byte陣列的方式讀取和處理字元陣列,不加轉化
- 在byte[]轉化成String的時候指定字符集為 ISO-8859-1,在String再轉化成byte[]的時候也指定字符集為ISO-8859-1
參考
相關推薦
Java讀寫二進位制檔案到String,再寫入二進位制檔案
概述 java讀寫檔案的有很多種方式,基本都是採用java.io的inputStream和各種基於inputstream的封裝實現對檔案的讀寫,最原始的介面提供的便是基於byte的讀寫,而String可以看做是char[],一個char是8個byte。在最原始
[轉載]java讀寫word文檔,完美解決方案
重點 app PE 列表 mage too 介紹 代碼 而且 做項目的過程中,經常需要把數據裏裏的數據讀出來,經過加工,以word格式輸出。 在網上找了很多解決方案都不太理想,偶爾發現了PageOffice,一個國產的Office插件,開發調用非常簡單!比網上介紹的poi,
java讀寫excel(POI,支援xls和xlsx兩種格式)
這應該是一個比較全的示例了,更加複雜的功能可以在此基礎上擴充套件。此示例基於apache的POI類庫,相關jar包就不列舉了。這個類庫很通用,網上很好找。 1、不包含單元格合併的寫excel /** * excel匯出到輸出流 * 誰呼叫誰負責關閉輸出流 *
java讀寫word文件,完美解決方案
java2word 是一個在java程式中呼叫 MS Office Word 文件的元件(類庫)。該元件提供了一組簡單的介面,以便java程式呼叫他的服務操作Word 文件。 這些服務包括: 開啟文件、新建文件、 查詢文字、替換文字, 插入文字、插入圖片、插入表格, 在書籤處插入文字、插入圖片、插入表格等
Java讀寫檔案,中文亂碼解決
讀檔案:使用new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8")); StringBuffer strBuf = new StringBuffer(); BufferedRead
Java讀寫檔案,在檔案中搜索內容,並輸出含有該內容的所有行
1.問題描述 在一個目錄及子目錄下查詢 TXT或Java檔案,從中搜索所有“物件”字樣的行。 在D盤中的所有檔案中搜索含有“物件”的行。 2.解題思路 先找出D盤下所有檔案 再對每個檔案中的每行內容進行,進行查詢,若含有“物件”兩字,輸出該行。 3.程式程式碼 im
位元組流與字元流,位元組流和字元流的使用哪個多? java 讀寫操作大檔案 BufferedReader和RandomAccessFile
一 首先我們要知道 在程式中所有的資料都是以流的方式進行傳輸或儲存的 而流有兩種 位元組流用來處理位元組或二進位制物件 字元流主要用來處理字元或字串,一個字元佔兩個位元組 而上一篇的java 讀寫操作大檔案 BufferedReader和RandomAccessFile Buf
java讀寫properties檔案,解決系統找不到指定路徑,解決寫入後讀取正常,但檔案資料未更新問題
properties屬性檔案:config.properties # #Tue Aug 13 15:30:56 CST 2013 timeInterval=33 name=holdOn filepath=bb ip=192.168.1.1 類例項:Configuration.java package
java讀寫檔案,讀超大檔案
一直在處理爬蟲,經常能遇到讀寫檔案的操作,很多時候都是讀寫超大檔案,記錄如下: 一、讀檔案 import java.io.BufferedOutputStream; import java.io.BufferedReader; import jav
java 讀寫json檔案
json檔案放在maven工程的resource 的html 檔案下面 package com.dl.utils; import java.io.File; import java.io.IOException; import org.apache.commons.io.FileUt
Java讀寫文件,中文亂碼解決
中文亂碼解決 eat 存在 讀文件 如果 清空 writer 讀寫 utf 讀文件:使用new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8")); StringBu
Java讀寫檔案的方法
Java讀寫檔案的方法有很多種形式,分享一下我整理出來的一種情況。 一、讀檔案: public static void ReadFile() { String file_path = "data/newFilename.txt"; try (FileReader reader = n
Java 讀寫 hdfs檔案或者目錄
1.讀取單個檔案 [java] view plain copy Date date = DateUtil.getSpecifiedDayBefore(); String&
Android-Java讀寫檔案到自身APP目錄
介面: Layout: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" and
Java 讀寫Properties配置檔案
1.Properties類與Properties配置檔案 Properties類繼承自Hashtable類並且實現了Map介面,也是使用一種鍵值對的形式來儲存屬性集。不過Properties有特殊的地方,就是它的鍵和值都是字串型別。 2.Properties中的主要方
將圖片寫入二進位制檔案,再從二進位制檔案還原圖片(c++)
1 #include "string" 2 #include "iostream" 3 #include "fstream" 4 using namespace std; 5 #define MAX 20480 6 void main() 7 { 8 string sPicPat
Java讀寫Properties配置檔案小案例
在軟體專案開發中需要讀取配置檔案,下面就簡單的演示一下如何從配置檔案中讀取資料以及修改其中的資料 一,建立一個新的Java專案,並命名為 propertiesdemo &n
(java筆記)java讀寫CSV檔案的方法
CSV檔案 逗號分隔值(Comma-Separated Values,CSV,有時也稱為字元分隔值,因為分隔字元也可以不是逗號),其檔案以純文字形式儲存表格資料(數字和文字)。純文字意味著該檔案是一個字元序列,不含必須像二進位制數字那樣被解讀的資料。CSV檔案由任意數目的記錄組成,記
java讀寫檔案時nio、bio對比
1. 基本 概念 IO 是主存和外部裝置 ( 硬碟、終端和網路等 ) 拷貝資料的過程。 IO 是作業系統的底層功能實現,底層通過 I/O 指令進行完成。所有語言執行時系統提供執行 I/O 較高級別的工具。 (c 的 printf scanf,java 的面向物
java 讀寫 yaml 檔案
簡介 Yaml是一種“是一個可讀性高並且容易被人類閱讀,容易和指令碼語言互動,用來表達資料序列的程式語言。”類似於XML但比XML更簡潔,適合編寫配置檔案。 基本語法規則 大小寫敏感 使用縮排表示層級關係 縮排時不允許使用Tab鍵,只允許使用空格 縮排的