Armin
迷茫的话 TRY AGAIN 多少次都能重新再来

为了实现,并发写操作,首先实验一下在本地情况下,

将一个文件切分成若干个 文件块 然后将文件块

通过多线程的并发的方式写入到指定目录下的文件中。

下面是简单的试着实现代码,暂时 先进行记录一下:

import java.io.FileInputStream ;
import java.io.FileOutputStream ;
import java.io.File;
import java.io.IOException ;
import java.nio.channels.FileChannel ;
import java.nio.ByteBuffer ;

import java.lang.Thread;

public class paralle 
{
    
   
    public static void main(String[] args) throws Exception 
    {
         int MB64 = 1024 ;
         File main_f = new File("d:\\test.txt") ;
         System.out.println("success create file"+ main_f.getName()) ;
         int pieceNum = (int)(main_f.length()/MB64) ;
         System.out.println("we will divide the file into "+pieceNum+"pieces") ;
         ByteBuffer [] blocks = new ByteBuffer[pieceNum];
         
         File [] subFiles = new File[pieceNum] ;
         
         ThreadWrite [] subThread = new ThreadWrite [pieceNum] ;
         
         FileChannel finChannel = new FileInputStream (main_f).getChannel() ;
         
           
         for ( int i = 0 ; i < pieceNum ; i++)
         {
             blocks[i] = ByteBuffer.allocate(MB64);
             finChannel.read(blocks[i]) ;
             blocks[i].flip();
             
           
             subThread[i] = new ThreadWrite(subFiles[i] , blocks[i] , i,main_f.getName()) ;
            
             
             subThread[i].start() ;
         }         
 
    }

}

class ThreadWrite extends Thread
{
    File f ;
    int currentNum ;
    String name ;
    ByteBuffer buffer ;
    FileChannel foutChannel ;
    
    ThreadWrite(File f ,ByteBuffer buffer , int currentNum,String name)
    {
        this.f = f ;
        this.currentNum = currentNum ;
        this.buffer = buffer ;
        this.name = name ;
    }
    
   public void run()
   {
       try
       {
           name = new String ( "d:\\test1\\"+name +"_"+currentNum+".txt") ;
           f = new File(name);
           f.createNewFile();
           foutChannel = new FileOutputStream (f).getChannel() ;
           foutChannel.write(buffer);
           buffer.clear() ;
           
           System.out.println("create new file :"+name) ;
       }
       catch (IOException e )
       {
           e.printStackTrace();
       }
   }
    
    
}

思路很简单, 就是 实现设置一个 MB64 的整数值 对应的就是 block的单位 大小, 然后 获取待分割 的所谓的大文件,

然后 根据 block的大小 将大文件 分割成 n 份 , n = File.length() / MB64 ;

接下来, 创建一个 长度 为 n 的 继承了 Thread 可以实现多线程的 类的数组,

进行一个 n 的循环, 在循环中 为 分割的 每个File 的block 创建一个 子文件, 该文件中存放的是

File 中的各个 分割的 block 的内容, 并且在 文件输出的时候, 是以线程并发的方式 写进 子文件中的,

并且 子文件 的命名方式 是以 大文件+当前循环码(第几个block-1)+".txt"的生成方式,进行文件的生成的。

这样,在进行整体文件分割的时候, 可以很容易看出来, 那个是主文件, 那个是子文件。

 ------------------------------修改版---------------------------------

package parallel_write;

import java.io.FileInputStream ;
import java.io.FileOutputStream ;
import java.io.File ;
import java.io.IOException ;
import java.nio.channels.FileChannel ;
import java.nio.ByteBuffer ;

import java.lang.Thread ;



 
public class Main {

    
    public static void main(String[] args) throws Exception
    {
        String path = new String ("test.txt") ;
        //test.txt file in included in the project floder
        
        Divide_LargeFile divFile = new Divide_LargeFile(path) ;
        
        divFile.divideFile();
        
    }

}

class Divide_LargeFile
{
    final static int MB64 = 1024 ;
    File main_f ;
    int blockNum ;
    ByteBuffer [] blocks ;
    File [] subFiles ;
    ThreadWrite [] subThread ;
   
    
    Divide_LargeFile ( String path ) 
    {
        this.main_f = new File ( "test.txt" ) ;
        System.out.println("success create file "+main_f.getName()) ;
        
        
        
    }
    
    public void divideFile ()throws Exception
    {
        this.blockNum = (int)(main_f.length()/MB64) ;
        System.out.println("large file is divided into "+blockNum+" blocks") ;
        
        ByteBuffer [] blocks = new ByteBuffer[blockNum] ;
        //we can regard block as a contianer which gets size MB64 bytes everytime from large fine
        
        this.subFiles = new File[blockNum] ;
        // new some File objects , but system didn't allocate capacity for 
        //each File objects in the array
        
        this.subThread = new ThreadWrite[blockNum] ;
        //number of subThread equals to the subFile's number
       
        FileChannel finChannel = new FileInputStream(main_f).getChannel() ;
        
        for ( int i = 0 ; i < blockNum; i++)
        {
            blocks[i]  = ByteBuffer.allocate(MB64);
            
            finChannel.read(blocks[i]);
            blocks[i].flip() ;
            
            subThread[i] = new ThreadWrite(subFiles[i] , blocks[i],i, main_f.getName()) ;
            
            subThread[i].start(); 
        }
  
     finChannel.close() ;
} }
class ThreadWrite extends Thread { File f ; int currentNum ; String fileName ; ByteBuffer buffer ; FileChannel foutChannel ; ThreadWrite ( File f , ByteBuffer buffer , int curNum , String fileName) { this.f = f ; this.buffer = buffer ; this.currentNum = curNum ; this.fileName = fileName ; } public void run () { try { fileName = new String (fileName+"_"+currentNum+".txt") ; f = new File (fileName) ; f.createNewFile(); foutChannel = new FileOutputStream(f).getChannel() ; foutChannel.write(buffer) ; buffer.clear() ; System.out.println("create new file"+fileName) ; } catch (IOException e ) { e.printStackTrace(); } } }

 

接下来要进行分析的是,

如何在Client 端 调用 相关的hadoop 方法 来根据 相关Path 在HDFS 端 创建一个 File,

并一次性 为该 File 在NameNode上面 添加 相关的节点, 并且可以 通过 相关调用 在Datanode 上面

一次性为 File 分割成 block 的数目 n 分配相应数量 的 replica。

 

相关类有:

FSDirectory.addFile.java

FSDirectory.addNode.java

FSDirector.addBlock.java

 

 

 

 

posted on 2014-01-05 22:02  Armin  阅读(2297)  评论(0编辑  收藏  举报