2010-12-13 24 views
16

バイナリファイル(video/audio/imageなど)をそれぞれ100kbのチャンクに分割し、それらのチャンクに戻って元のファイルに戻そうとしています。 私のコードは、ファイルを分割してチャンクに参加するという意味で、動作しているようですが、戻ってくるファイルはオリジナルと同じサイズです。しかし、問題は、コンテンツが切り詰められることです。つまり、ビデオファイルの場合は2秒後に停止し、画像ファイルの場合は上部のみが正しいように見えます。分割してJavaでバイナリファイルを返す

分割する:

File ifile = new File(fname); 
FileInputStream fis; 
String newName; 
FileOutputStream chunk; 
int fileSize = (int) ifile.length(); 
int nChunks = 0, read = 0, readLength = Chunk_Size; 
byte[] byteChunk; 
try { 
    fis = new FileInputStream(ifile); 
    StupidTest.size = (int)ifile.length(); 
    while (fileSize > 0) { 
     if (fileSize <= Chunk_Size) { 
      readLength = fileSize; 
     } 
     byteChunk = new byte[readLength]; 
     read = fis.read(byteChunk, 0, readLength); 
     fileSize -= read; 
     assert(read==byteChunk.length); 
     nChunks++; 
     newName = fname + ".part" + Integer.toString(nChunks - 1); 
     chunk = new FileOutputStream(new File(newName)); 
     chunk.write(byteChunk); 
     chunk.flush(); 
     chunk.close(); 
     byteChunk = null; 
     chunk = null; 
    } 
    fis.close(); 
    fis = null; 

し、ファイルを結合するため、私はすべてのチャンクの名前を入れてここ

は、私は(あなたが好きなら、私は全体のコードを投稿することができます)を使用していたコードですリストを作成して名前でソートし、次のコードを実行します。

File ofile = new File(fname); 
FileOutputStream fos; 
FileInputStream fis; 
byte[] fileBytes; 
int bytesRead = 0; 
try { 
    fos = new FileOutputStream(ofile,true);    
    for (File file : files) { 
     fis = new FileInputStream(file); 
     fileBytes = new byte[(int) file.length()]; 
     bytesRead = fis.read(fileBytes, 0,(int) file.length()); 
     assert(bytesRead == fileBytes.length); 
     assert(bytesRead == (int) file.length()); 
     fos.write(fileBytes); 
     fos.flush(); 
     fileBytes = null; 
     fis.close(); 
     fis = null; 
    } 
    fos.close(); 
    fos = null; 

答えて

10

は、私がコードにのみ2つの潜在的なミスを見つけることができます。

int fileSize = (int) ifile.length(); 

は、上記の時に失敗しましたintはそれ以上保持できないため、ファイルは2GBを超えています。

newName = fname + ".part" + Integer.toString(nChunks - 1); 

このように構成されたファイル名は、非常に特殊な方法でソートする必要があります。デフォルトの文字列ソートを使用する場合、name.part10は、name.part2の前に来ます。Comparatorというカスタムを提供したい場合は、パーツ番号をintとして抽出して解析し、代わりにそれを比較します。

+0

ファイルは2GBよりもはるかに少ないですが、ソートの部分については、0,1,10,11,12、...、2,20、などを取っています - これは厄介です。 –

+0

これは動作します!どうもありがとう! –

+0

ようこそ。 – BalusC

0

ファイルのバイナリ比較を実行するとどうなりますか。例えばdiffと。最初のファイルの後に相違点がありますか?

テキストTXTファイルを分割できますか?バイトが適切でない場合は、何が問題になるのかがはっきりしているはずです。例えば繰り返しブロック/ファイル/またはヌルバイトでいっぱいのデータ。 ??

EDIT:他の人が気づいたように、あなたは特定の順序でファイルを読んでいません。あなたができることは、のようなパッド付きのファイル番号を使用することです。

newName = String.format("%s.part%09d", fname, nChunks - 1); 

これにより、最大10億のファイルが数字順に表示されます。

ファイルを読むときに、ファイルを並べ替える必要があります。他の人がパディングされた数字の大きさを減らすことを提案していますが、正しい順序を取得するには名前でソートすることができることは素晴らしいことができよう

Arrays.sort(files); 
for (File file : files) { 

カスタムコンパレータを使用しました。例えばエクスプローラーで。

+0

ちょっとした修正:format内の ".part"を "%s"に置き換えるか、 ".part"パラメータを削除する必要があります。 –

+0

@ Sergey、その点に感謝します。 –

3

し、ファイルを結合するために、私は、リスト内のすべてのチャンクの名前を入れて、名前によって、それを並べ替えた後、次のコードを実行します。

をしかし、あなたの名前は次の形式をとります。

newName = fname + ".part" + Integer.toString(nChunks - 1); 

11個以上の部品がある場合はどうなるか慎重に考えてください。どの文字列がアルファベット順に最初に来るか: ".part10"または ".part2"? (回答:」.part10" は、以降 『1』は 『2』の文字エンコーディングで前に来る。)

+0

これは機能します!どうもありがとう! –

1

10個以上のチャンクがありますか?次にプログラムは* .part1 + * .part10 + * .part2を連結します。

+0

ありがとう!本当に助けていただきありがとうございます! –

1

ファイル分割の場合:----->

import java.io.*; 

class Split 
{ 


    public static void main(String args[])throws IOException 
    { 

    Console con=System.console(); 
    System.out.println("enter the file name"); 
    String path=con.readLine(); 
    File f= new File(path); 
    int filesize=(int)f.length(); 
    FileInputStream fis= new FileInputStream(path); 

    int size; 
    System.out.println("enter file size for split"); 
     size=Integer.parseInt(con.readLine()); 


    byte b[]=new byte[size]; 

    int ch,c=0; 




    while(filesize>0) 
      { 
       ch=fis.read(b,0,size); 


     filesize = filesize-ch; 


       String fname=c+"."+f.getName()+""; 
     c++; 
     FileOutputStream fos= new FileOutputStream(new File(fname)); 
     fos.write(b,0,ch); 
     fos.flush(); 
     fos.close(); 

     } 

fis.close(); 

} 

} 
0

をそれは、(バイトで)&先のファイルサイズフォームのユーザーを分割し、ファイル名を取り、サブファイルへのようなファイルのすべてのタイプのためにその作業を、それを分割(.binファイル、.JPG、.RAR)

import java.io.*; 
class split{ 
public static void main(String args[])throws IOException { 
String a; 
int b; 
long len; 
Console con=System.console(); 
System.out.println("Enter File Name: "); 
File f=new File(con.readLine()); 
System.out.println("Enter Destination File Size: "); 
b=Integer.parseInt(con.readLine()); 
FileInputStream fis=new FileInputStream(f); 
len=f.length(); 
int c=(int)len/b; 
if(((int)len%b)!=0) 
c++; 
for(int i=0;i<c;i++){ 
File f1=new File(i+""+"."+f); 
FileOutputStream fos=new FileOutputStream(f1); 
for(int j=0;j<b;j++){ 
int ch; 
if((ch=fis.read())!=-1) 
fos.write(ch); } } 
fis.close(); 
System.out.println("Operation Successful"); }} 

と別のプログラムが唯一の分割ファイル名を取得し、すべてのファイルをマージfiles.Itすべての分割をマージします。

import java.io.*; 
class merge{ 
static int i; 
public static void main(String args[])throws IOException{ 
String a; 
int b; 
long len; 
Console con=System.console(); 
System.out.println("Enter File to be retrived: "); 
File f=new File(con.readLine()); 
FileOutputStream fos=new FileOutputStream(f,true); 
try { 
File f1=new File(i+""+"."+f); 
while((f1.exists())!=false) { 
int ch; 
FileInputStream fis=new FileInputStream(i+""+"."+f); 
i++; 
while((ch=fis.read())!=-1){ 
fos.write(ch); }}} 
catch(FileNotFoundException e1){} }} 
+0

あなたのコードをちょっとフォーマットする必要があります – AbcAeffchen

0
public class FileSplitter { 
    private static final int BUFSIZE = 4*1024; 
    public boolean needsSplitting(String file, int chunkSize) { 
     return new File(file).length() > chunkSize; 
    } 
    private static boolean isASplitFileChunk(String file) { 
     return chunkIndexLen(file) > 0; 
    } 
    private static int chunkIndexLen(String file) { 
     int n = numberOfTrailingDigits(file); 
     if (n > 0) { 
      String zeroes = new String(new char[n]).replace("\0", "0"); 
      if (file.matches(".*\\.part[0-9]{"+n+"}?of[0-9]{"+n+"}?$") && !file.endsWith(zeroes) && !chunkNumberStr(file, n).equals(zeroes)) { 
       return n; 
      } 
     } 
     return 0; 
    } 
    private static String getWholeFileName(String chunkName) { 
     int n = chunkIndexLen(chunkName); 
     if (n>0) { 
      return chunkName.substring(0, chunkName.length() - 7 - 2*n); // 7+2n: 1+4+n+2+n : .part012of345 
     } 
     return chunkName; 
    } 
    private static int getNumberOfChunks(String filename) { 
     int n = chunkIndexLen(filename); 
     if (n > 0) { 
      try { 
       String digits = chunksTotalStr(filename, n); 
       return Integer.parseInt(digits); 
      } catch (NumberFormatException x) { // should never happen 
      } 
     } 
     return 1; 
    } 
    private static int getChunkNumber(String filename) { 
     int n = chunkIndexLen(filename); 
     if (n > 0) { 
      try { 
       // filename.part001of200 
       String digits = chunkNumberStr(filename, n); 
       return Integer.parseInt(digits)-1; 
      } catch (NumberFormatException x) { 
      } 
     } 
     return 0; 
    } 
    private static int numberOfTrailingDigits(String s) { 
     int n=0, l=s.length()-1; 
     while (l>=0 && Character.isDigit(s.charAt(l))) { 
      n++; l--; 
     } 
     return n; 
    } 
    private static String chunksTotalStr(String filename, int chunkIndexLen) { 
     return filename.substring(filename.length()-chunkIndexLen); 
    } 
    protected static String chunkNumberStr(String filename, int chunkIndexLen) { 
     int p = filename.length() - 2 - 2*chunkIndexLen; // 123of456 
     return filename.substring(p,p+chunkIndexLen); 
    } 
    // 0,8 ==> part1of8; 7,8 ==> part8of8 
    private static String chunkFileName(String filename, int n, int total, int chunkIndexLength) { 
     return filename+String.format(".part%0"+chunkIndexLength+"dof%0"+chunkIndexLength+"d", n+1, total); 
    } 
    public static String[] splitFile(String fname, long chunkSize) throws IOException { 
     FileInputStream fis = null; 
     ArrayList<String> res = new ArrayList<String>(); 
     byte[] buffer = new byte[BUFSIZE]; 
     try { 
      long totalSize = new File(fname).length(); 
      int nChunks = (int) ((totalSize + chunkSize - 1)/chunkSize); 
      int chunkIndexLength = String.format("%d", nChunks).length(); 
      fis = new FileInputStream(fname); 
      long written = 0; 
      for (int i=0; written<totalSize; i++) { 
       String chunkFName = chunkFileName(fname, i, nChunks, chunkIndexLength); 
       FileOutputStream fos = new FileOutputStream(chunkFName); 
       try { 
        written += copyStream(fis, buffer, fos, chunkSize); 
       } finally { 
        Closer.closeSilently(fos); 
       } 
       res.add(chunkFName); 
      } 
     } finally { 
      Closer.closeSilently(fis); 
     } 
     return res.toArray(new String[0]); 
    } 
    public static boolean canJoinFile(String chunkName) { 
     int n = chunkIndexLen(chunkName); 
     if (n>0) { 
      int nChunks = getNumberOfChunks(chunkName); 
      String filename = getWholeFileName(chunkName); 
      for (int i=0; i<nChunks; i++) { 
       if (!new File(chunkFileName(filename, i, nChunks, n)).exists()) { 
        return false; 
       } 
      } 
      return true; 
     } 
     return false; 
    } 
    public static void joinChunks(String chunkName) throws IOException { 
     int n = chunkIndexLen(chunkName); 
     if (n>0) { 
      int nChunks = getNumberOfChunks(chunkName); 
      String filename = getWholeFileName(chunkName); 
      byte[] buffer = new byte[BUFSIZE]; 
      FileOutputStream fos = new FileOutputStream(filename); 
      try { 
       for (int i=0; i<nChunks; i++) { 
        FileInputStream fis = new FileInputStream(chunkFileName(filename, i, nChunks, n)); 
        try { 
         copyStream(fis, buffer, fos, -1); 
        } finally { 
         Closer.closeSilently(fis); 
        } 
       } 
      } finally { 
       Closer.closeSilently(fos); 
      } 
     } 
    } 
    public static boolean deleteAllChunks(String chunkName) { 
     boolean res = true; 
     int n = chunkIndexLen(chunkName); 
     if (n>0) { 
      int nChunks = getNumberOfChunks(chunkName); 
      String filename = getWholeFileName(chunkName); 
      for (int i=0; i<nChunks; i++) { 
       File f = new File(chunkFileName(filename, i, nChunks, n)); 
       res &= (f.delete() || !f.exists()); 
      } 
     } 
     return res; 
    } 
    private static long copyStream(FileInputStream fis, byte[] buffer, FileOutputStream fos, long maxAmount) throws IOException { 
     long chunkSizeWritten; 
     for (chunkSizeWritten=0; chunkSizeWritten<maxAmount || maxAmount<0;) { 
      int toRead = maxAmount < 0 ? buffer.length : (int)Math.min(buffer.length, maxAmount - chunkSizeWritten); 
      int lengthRead = fis.read(buffer, 0, toRead); 
      if (lengthRead < 0) { 
       break; 
      } 
      fos.write(buffer, 0, lengthRead); 
      chunkSizeWritten += lengthRead; 
     } 
     return chunkSizeWritten; 
    } 
} 

Closerhereまたはfrom org.apache.logging.log4j.core.utilを借ります。

関連する問題