如何使用Scalaj Http和Hadoop HttpFs流式下载

如何使用Scalaj Http和Hadoop HttpFs流式下载,scala,hadoop,hdfs,httpfs,scalaj-http,Scala,Hadoop,Hdfs,Httpfs,Scalaj Http,我的问题是在使用Scalaj Http时如何使用缓冲流 我已经编写了以下代码,这是一个完整的工作示例,将使用HttpFS从Hadoop HDFS下载一个文件。我的目标是处理非常大的文件,这将需要使用缓冲方法对本地文件进行多个I/O写入 我还没有找到关于如何使用ScalaJ Http接口的流的文档。我对一个可以处理大型多GB文件的下载和上传示例感兴趣。我下面的代码使用内存缓冲,这只适用于原型设计 import scalaj.http._ import ujson.Js import java.te

我的问题是在使用Scalaj Http时如何使用缓冲流

我已经编写了以下代码,这是一个完整的工作示例,将使用HttpFS从Hadoop HDFS下载一个文件。我的目标是处理非常大的文件,这将需要使用缓冲方法对本地文件进行多个I/O写入

我还没有找到关于如何使用ScalaJ Http接口的流的文档。我对一个可以处理大型多GB文件的下载和上传示例感兴趣。我下面的代码使用内存缓冲,这只适用于原型设计

import scalaj.http._
import ujson.Js
import java.text.SimpleDateFormat
import java.net.SocketTimeoutException
import java.io.InputStream
import java.io.BufferedOutputStream
import java.io.FileOutputStream
import java.io.FileNotFoundException

object CopyFileFromHdfs {
    def main(args: Array[String]) {
        val host = "hadoop.example.com"
        val user = "root"
        var dstFile = ""
        var srcFile = ""
        val operation = "OPEN"
        val port = 14000

        System.setProperty("sun.net.http.allowRestrictedHeaders", "true")

        if (args.length != 2)
        {
            println("Error: Missing or too many arguments")
            println("Usage: CopyFileFromHdfs <srcfile> <dstfile>")

            System.exit(1)
        }

        srcFile = args(0)
        dstFile = args(1)


        // ********************************************************************************
        // Create the URL string that we will use to connect to Hadoop HttpFS
        //
        // The string will look like this:
        // http://root@123.456.789.012:14000/webhdfs/v1/?user.name=root&op=OPEN
        // ********************************************************************************

        val url = makeHttpfsUrl(host, user, srcFile, operation, port)

        // ********************************************************************************
        // Using HTTP, call the HttpFS server
        //
        // Exceptions:
        //  java.net.SocketTimeoutException
        //  java.net.UnknownHostException
        //  java.lang.IllegalArgumentException
        // Remote Exceptions:
        //  java.io.FileNotFoundException
        //  com.sun.jersey.api.NotFoundException
        // ********************************************************************************

        try {
            var response = Http(url)
                .timeout(connTimeoutMs = 1000, readTimeoutMs = 5000)
                .asBytes

            // ********************************************************************************
            // Check for an error. We are expecting an HTTP 200 response
            // ********************************************************************************

            if (response.code < 200 || response.code > 299)
            {
                val data = ujson.read(response.body)

                printf("Error: Cannot download file: %s\n", dstFile)
                println(removeQuotes(data("RemoteException")("message").str))
                println(removeQuotes(data("RemoteException")("exception").str))

                System.exit(1)
            }

            val is = new FileOutputStream(dstFile)
            val bs = new BufferedOutputStream(is)

            bs.write(response.body, 0, response.body.length)

            bs.close()
            is.close()
        } catch {
            case e: SocketTimeoutException => {
                printf("Error: Cannot connect to host %s on port %d\n", host, port)
                println(e)
                System.exit(1);
            }
            case e: Exception => {
                printf("Error (other): Cannot download file %s\n", srcFile)
                println(e)
                System.exit(1);
            }
        }

        printf("Success: File downloaded. %s -> %s\n", srcFile, dstFile)

        System.exit(0)
    }

    // ********************************************************************************
    // The Json strings are surrounded by quotes.
    // This function will remove them (only at the start and the end).
    // ********************************************************************************

    def removeQuotes(str: String): String = {
        // This expression will delete quotes at the beginning and end of a string
        return str.replaceAll("^\"|\"$", "");
    }

    // ********************************************************************************
    // Create the URL string that we will use to connect to Hadoop HttpFS
    //
    // The string will look like this:
    // http://root@123.456.789.012:14000/webhdfs/v1/?user.name=root&op=LISTSTATUS
    // ********************************************************************************

    def makeHttpfsUrl(
            host: String,
            user: String,
            hdfsPath: String,
            operation: String,
            port: Integer) : String = {

        var url = "http://" + user + "@" + host + ":" + port.toString + "/webhdfs/v1"

        if (hdfsPath(0) == '/')
            url += hdfsPath
        else
            url += "/" + hdfsPath

        url += "?user.name=" + user + "&op=" + operation

        return url
    }
}
导入scalaj.http_
导入ujson.Js
导入java.text.simpleDataFormat
导入java.net.SocketTimeoutException
导入java.io.InputStream
导入java.io.BufferedOutputStream
导入java.io.FileOutputStream
导入java.io.FileNotFoundException
对象CopyFileFromHdfs{
def main(参数:数组[字符串]){
val host=“hadoop.example.com”
val user=“root”
var dstFile=“”
var srcFile=“”
val operation=“打开”
val端口=14000
System.setProperty(“sun.net.http.AllowerPrictedHeaders”,“true”)
如果(参数长度!=2)
{
println(“错误:缺少或参数太多”)
println(“用法:CopyFileFromHdfs”)
系统出口(1)
}
srcFile=args(0)
dstFile=args(1)
// ********************************************************************************
//创建用于连接Hadoop HttpFS的URL字符串
//
//字符串将如下所示:
// http://root@123.456.789.012:14000/webhdfs/v1/?user.name=root&op=OPEN
// ********************************************************************************
val url=makeHttpfsUrl(主机、用户、srcFile、操作、端口)
// ********************************************************************************
//使用HTTP调用HttpFS服务器
//
//例外情况:
//java.net.SocketTimeoutException
//java.net.UnknownHostException
//java.lang.IllegalArgumentException
//远程异常:
//java.io.FileNotFoundException
//com.sun.jersey.api.NotFoundException
// ********************************************************************************
试一试{
var response=Http(url)
.超时(connTimeoutMs=1000,readTimeoutMs=5000)
.asBytes
// ********************************************************************************
//检查错误。我们期待HTTP 200响应
// ********************************************************************************
如果(response.code<200 | | response.code>299)
{
val data=ujson.read(response.body)
printf(“错误:无法下载文件:%s\n”,dstFile)
println(removeQuotes(数据(“远程异常”)(“消息”).str))
println(removeQuotes(数据(“远程异常”)(“异常”).str))
系统出口(1)
}
val is=新文件输出流(dstFile)
val bs=新的缓冲输出流(is)
写入(response.body,0,response.body.length)
bs.close()
is.close()
}抓住{
案例e:SocketTimeoutException=>{
printf(“错误:无法连接到端口%d上的主机%s\n”,主机,端口)
println(e)
系统出口(1);
}
案例e:例外=>{
printf(“错误(其他):无法下载文件%s\n”,srcFile)
println(e)
系统出口(1);
}
}
printf(“成功:已下载文件。%s->%s\n”,srcFile,dstFile)
系统退出(0)
}
// ********************************************************************************
//Json字符串用引号括起来。
//此功能将删除它们(仅在开始和结束时)。
// ********************************************************************************
def removeQuotes(str:String):String={
//此表达式将删除字符串开头和结尾的引号
返回str.replaceAll(“^\”|\“$”,”);
}
// ********************************************************************************
//创建用于连接Hadoop HttpFS的URL字符串
//
//字符串将如下所示:
// http://root@123.456.789.012:14000/webhdfs/v1/?user.name=root&op=LISTSTATUS
// ********************************************************************************
def makeHttpfsUrl(
主持人:字符串,
用户:字符串,
hdfsPath:String,
操作:字符串,
端口:整数):字符串={
var url=“http://”+user+“@”+host+:“+port.toString+”/webhdfs/v1”
如果(hdfsPath(0)='/')
url+=hdfsPath
其他的
url+=“/”+hdfsPath
url+=“?user.name=“+user+”&op=“+操作
返回url
}
}