通过webHDFS REST API上传到HDFS的图像问题(Issues with Uploadi

2019-10-19 23:22发布

我做HttpPut与MultiPartEntity通过webHDFS REST API写一个文件到HDFS。 请求自身经历,给我正确的反应,307和201.然而,图像具有多报头也可以写成它的一部分如下图所示,它不是一个有效的图像检索和开放。

--8DkJ3RkUHahEaNE9Ktw8NC1TFOqegjfA9Ps
内容处置:形状数据; NAME = “文件”; 文件名= “advert.jpg”
内容类型:应用/八位字节流

图像内容的ÿØÿàJFIFHHÿÛC//休息
--8DkJ3RkUHahEaNE9Ktw8NC1TFOqegjfA9Ps

去除图像文件的多头,使它成为一个有效的图像,但我不知道我怎么能避免它开始。 我甚至不知道我是否有在这个控制权,因为webHDFS负责实际写入文件。

这是我为它的代码。 有没有别的东西,我应该做的事?

final String LOCATION = "Location";
final String writeURI = "http://<ip>:50070/webhdfs/v1/user/hadoop/advert.jpg"; 

HttpPut put = new HttpPut(writeURI);
HttpClient client = HttpClientBuilder.create().build();        
HttpResponse response = client.execute(put);
put.releaseConnection();

String redirectUri = null;
Header[] headers = response.getAllHeaders();
for(Header header : headers)
{
    if(LOCATION.equalsIgnoreCase(header.getName()))
    {
         redirectUri = header.getValue();
    }                    
}

HttpPut realPut = new HttpPut(redirectUri);
realPut.setEntity(buildMultiPartEntity("advert.jpg"));
HttpResponse response2 = client.execute(realPut);


private HttpEntity buildMultiPartEntity(String fileName)
{
   MultipartEntityBuilder multipartEntity = MultipartEntityBuilder.create();
   multipartEntity.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
   multipartEntity.addPart("file", new FileBody(new File(fileName)));
   return multipartEntity.build();
}    

任何帮助表示赞赏。

Answer 1:

我使用python请求会见了同样的问题。 我做了什么,以最终解决它在发送之前读取图像到内存中。 并采用一步调用API webhdfs而不是两个。 希望这能有点帮助。

host_url = current_app.config.get('HDFS_URL', '')
adx_img_path = current_app.config.get('ADX_CUSTOMER_IMAGE', '')
real_path = adx_img_path + remotefile
hdfs_username = current_app.config.get('HDFS_USERNAME', 'xdisk')
parameters = '?user.name=' + hdfs_username + '&op=CREATE&data=true'
img = open(localfile, 'rb').read()
url = host_url + real_path + parameters
r = requests.put(url, data=img, headers={"Content-Type": "application/octet-stream"})

似乎通过读取图像作为二进制/字节,怪异的头不会被添加到文件头。 对于HttpClient的你正在使用,我建议你尝试InputStreamBodyByteArrayBody



Answer 2:

添加该图像作为FileEntity,ByteArrayEntity或InputStreamEntity与内容类型的“application /八位字节流”。



Answer 3:

这是对我底座上公认的答案工作的代码:

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.FileEntity;
import org.apache.http.impl.client.HttpClientBuilder;

import java.io.File;
import java.io.IOException;

public class Test {

    public void Test(){
        try {

            final String writeURI = "http://<IP>:50075/webhdfs/v1/user/sample.xml?op=CREATE&user.name=istvan&namenoderpcaddress=quickstart.cloudera:8020&overwrite=true";

            HttpClient client = HttpClientBuilder.create().build();

            HttpPut put = new HttpPut(writeURI);
            put.setEntity(buildFileEntity("C:\\sample.xml"));
            put.setHeader("Content-Type", "application/octet-stream");
            HttpResponse response = client.execute(put);

            System.out.println(response);

        }catch(IOException e){
            e.printStackTrace();
        }
    }


    private static FileEntity buildFileEntity (String fileName)
    {
        FileEntity inputData = new FileEntity(new File(fileName));

        return inputData;
    }

    public static void main(String[] args) {
        new Test().Test();
    }
}

Maven的:

        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.4</version>
        </dependency>

        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpmime</artifactId>
            <version>4.3.1</version>
        </dependency>


文章来源: Issues with Uploading an image to HDFS via webHDFS REST API