2017-03-20 2 views
0

Ich lese gerade eine Datei von dann schreiben es auf eine HTTP-Verbindung, die die Datei lokal auf der Festplatte speichert - es funktioniert gut.Wie ByteArrayOutputStream über HTTP

Aufgrund der Umgebung, in der ich arbeite, kann ich Dateien nicht von der Festplatte lesen, sondern sie werden aus einer Datenbank gezogen und in einem ByteArrayOutputStream in meinem Java-Code gespeichert.

Also anstatt durch das Lesen einer Datei von der Festplatte zu starten, muss ich einen ByteOutputArrayStream verwenden und schreibe das stattdessen auf eine HTTP-Verbindung.

Ich brauche eine effiziente Methode, dies zu tun - Wenn ich meinen aktuellen Code (bloew) das ist in Ordnung ändern - ich bin bereit, alles verschrotten, wenn nötig ...

 // This is the primary call from jsp 
     public String postServer(String[] args)throws Exception{ 
      System.out.println("******* HTTPTestJPO inside postServer"); 

      String requestURL = "http://MyServer:8080/TransferTest/UploadServlet"; 
      String charset = "UTF-8"; 
      String sTest=args[0]; 
      String sResponse=""; 

      System.out.println("******* HTTPTestJPO incoming file string sTest:"+sTest); 

      MultipartUtility multipart = new MultipartUtility(requestURL, charset); 
      StringTokenizer inFiles=new StringTokenizer(sTest,","); 
      while(inFiles.hasMoreTokens()){ 
       String tmpFileName=inFiles.nextToken(); 
       System.out.println("******* tokenized tmpFileName:"+tmpFileName); 
       File uploadFile1 = new File(tmpFileName); 
       try { 
        multipart.addFilePart("fileUpload", uploadFile1); 
       } catch (IOException ex) { 
        System.err.println("******* HTTPTestJPO EXCEPTION: "+ex); 
       } 
      } 

      sResponse = multipart.handleFinish(); 
      System.out.println("******* HTTPTestJPO SERVER REPLIED:"+sResponse); 
      return sResponse; 
     } 

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
    // Multipart utility 
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
     /** 
     * This utility class provides an abstraction layer for sending multipart HTTP 
     * POST requests to a web server. 
     * @author www.codejava.net 
     * 
     */ 
     public class MultipartUtility { 
      private final String boundary; 
      private static final String LINE_FEED = "\r\n"; 
      private HttpURLConnection httpConn; 
      private String charset; 
      private OutputStream outputStream; 
      private PrintWriter writer; 

      /** 
      * This constructor initializes a new HTTP POST request with content type 
      * is set to multipart/form-data 
      * @param requestURL 
      * @param charset 
      * @throws IOException 
      */ 
      public MultipartUtility(String requestURL, String charset)throws IOException { 
       this.charset = charset; 

       // creates a unique boundary based on time stamp 
       boundary = "===" + System.currentTimeMillis() + "==="; 

       URL url = new URL(requestURL); 
       httpConn = (HttpURLConnection) url.openConnection(); 
       httpConn.setUseCaches(false); 
       httpConn.setDoOutput(true); // indicates POST method 
       httpConn.setDoInput(true); 
       httpConn.setRequestProperty("Content-Type","multipart/form-data; boundary=" + boundary); 
       //httpConn.setRequestProperty("User-Agent", "CodeJava Agent"); 
       //httpConn.setRequestProperty("Test", "Bonjour"); 
       outputStream = httpConn.getOutputStream(); 
       writer = new PrintWriter(new OutputStreamWriter(outputStream, charset),true); 
      } 

      /** 
      * Adds a upload file section to the request 
      * @param fieldName name attribute in <input type="file" name="..." /> 
      * @param uploadFile a File to be uploaded 
      * @throws IOException 
      */ 

      public void addFilePart(String fieldName, File uploadFile)throws IOException { 
       String fileName = uploadFile.getName(); 
       writer.append("--" + boundary).append(LINE_FEED); 
       writer.append("Content-Disposition: form-data; name=\"" + fieldName + "\"; filename=\"" + fileName + "\"").append(LINE_FEED); 
       writer.append("Content-Type: "+ URLConnection.guessContentTypeFromName(fileName)).append(LINE_FEED); 
       writer.append("Content-Transfer-Encoding: binary").append(LINE_FEED); 
       writer.append(LINE_FEED); 
       writer.flush(); 

    // HOW CAN I MODIFY THIS TO SEND AN EXISTING BYTEARRAYOUTPUTSTREAM INSTEAD OF A DISK FILE?? 
       FileInputStream inputStream = new FileInputStream(uploadFile); 
       byte[] buffer = new byte[4096]; 
       int bytesRead = -1; 
       while ((bytesRead = inputStream.read(buffer)) != -1) { 
        outputStream.write(buffer, 0, bytesRead); 
       } 
       outputStream.flush(); 
       inputStream.close(); 

       writer.append(LINE_FEED); 
       writer.flush();  
      } 

      /** 
      * Completes the request and receives response from the server. 
      * @return a list of Strings as response in case the server returned 
      * status OK, otherwise an exception is thrown. 
      * @throws IOException 
      */ 
      private String handleFinish() throws IOException { 
       String sResponse = ""; 

       //close out the multipart send 
       writer.append(LINE_FEED).flush(); 
       writer.append("--" + boundary + "--").append(LINE_FEED); 
       writer.close(); 

       // checks server's status code first 
       int status = httpConn.getResponseCode(); 
       sResponse=Integer.toString(status); 
       System.out.println("******* HTTPTestJPO http response code:"+status); 
       // if (status == HttpURLConnection.HTTP_OK) { 
        // BufferedReader reader = new BufferedReader(new InputStreamReader(
          // httpConn.getInputStream())); 
        // String line = reader.readLine(); 
        // while ((line = reader.readLine()) != null) { 
         // sResponse+=line; 
        // } 
        // reader.close(); 
        httpConn.disconnect(); 
       // } else { 
        // throw new IOException("Server returned non-OK status: " + status); 
       // } 

       return sResponse; 
      } 
     } 
    } 

Antwort

2

der Inhalt eines ByteArrayOutputStream kann auf einen anderen Output geschrieben werden mit der writeTo Methode, wie folgt aus:

byteArrayOutputStream.writeTo(outputStream); 

eine andere Möglichkeit wäre eine neue Input zu erstellen:

InputStream inputStream = new ByteArrayInputStream(
     byteArrayOutputStream.toByteArray()); 

aber Aufruf toByteArray macht eine Kopie der Byte-Array, so ist teurer.

+0

Wow, das war schnell - ok ich werde es jetzt versuchen und melden. Vielen Dank. – wayneh

+0

Eine kurze Frage - werden die Daten auf der Empfängerseite genauso behandelt, als ob der Ausgangsstrom ein FileInputStream wäre? Ich meine, wird es korrekt auf der Festplatte gespeichert, einschließlich des Dateinamens? – wayneh

+0

Das Empfangsende weiß nicht, woher die Bytes kommen. – dnault