2017-06-10 19 views
1

ファイル転送機能を備えたメッセンジャーを作成しようとしていましたが、最後にヌル文字が多すぎます。何らかの理由でファイルの長さを使用してファイルを削除すると、ファイルの多くが削除され、完全に混乱するようになります。私はJava 6やWindows 98(おばあちゃんのPC)と互換性があるので、Java 7以上の要素は使用していません。ソケット経由のJavaファイル転送最後のバイトをトリム

私はまた、ランダムなヌル文字の多くは、これが私のコードである

にこれを回避する方法イムわからない、ファイルに追加されます: 送信

package com.androdome.lunacoffee.management; 

import java.io.DataOutputStream; 
import java.io.FileInputStream; 
import java.io.IOException; 
import java.io.PrintWriter; 
import java.io.StringWriter; 
import java.net.InetAddress; 
import java.net.Socket; 
import java.net.UnknownHostException; 

import com.androdome.lunacoffee.ErrorScreen; 
import com.androdome.lunacoffee.SendScreen; 

public class FileTransmitter implements Runnable{ 
    String adds; 
    FileInputStream message; 
    int filecut = 4096; 
    byte[] fileName; 
    long fileSize; 
    SendScreen send; 
    public FileTransmitter(String address, FileInputStream msg, byte[] fnme, SendScreen snd, long l) { 
      adds = address; 
      send = snd; 
      message = msg; 
      fileName = fnme; 
      fileSize = l; 
    } 




    public void run() 
    { 
     try { 
      InetAddress add = InetAddress.getByName(adds); 
      Socket sock = new Socket(add, 11001); 
      DataOutputStream da = new DataOutputStream(sock.getOutputStream()); 
      PrintWriter output = new PrintWriter(da); 
      da.write(fileName); 


      da.writeLong(message.getChannel().size()); 

      byte[] filebuffer = new byte[filecut]; 
      int g = 0; 
      int back = 0; 
      while((g = message.read(filebuffer)) != -1) 
      { 
       if(g != filecut && g > 0) 
       { 
        back = g; 
       } 
       da.write(filebuffer); 
       filebuffer = new byte[filecut]; 
      } 
      da.writeInt(back); 
      System.out.print(back); 

      output.flush(); 
      output.close(); 
      send.incrementSent(); 
     } catch (UnknownHostException e) { 
      send.incrementError(); 
      // TODO Auto-generated catch block 
      StringWriter sw = new StringWriter(); 
      PrintWriter pw = new PrintWriter(sw); 
      e.printStackTrace(pw); 
      new ErrorScreen("Unable to send file", "Your file was not able to send because the host \"" + adds + "\" was not availible!", sw.toString()); 
      pw.close(); 
      try { 
       sw.close(); 
      } catch (IOException e1) { 
       // TODO Auto-generated catch block 
       e1.printStackTrace(); 
      } 

     } catch (IOException e) { 
      send.incrementError(); 
      // TODO Auto-generated catch block 
      new ErrorScreen("Unable to send file", "Your file was not able to send due to a bad output stream!", e.getMessage()); 
     } 
    } 

} 

レシーブ:

package com.androdome.lunacoffee.management; 

import java.io.DataInputStream; 
import java.io.File; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.PrintWriter; 
import java.io.StringWriter; 
import java.net.ServerSocket; 
import java.net.Socket; 
import java.util.Arrays; 

import com.androdome.lunacoffee.ErrorScreen; 
import com.androdome.lunacoffee.FileScreen; 
import com.androdome.lunacoffee.Main; 

public class FileReciever implements Runnable { 
    int bufferSize = 4096; 
    int headerSize = 32; 
    byte[] filebuffer = new byte[bufferSize]; 
    byte[] fileheader = new byte[headerSize]; 
    Main main; 
    File downloadfile = new File("tmp"); 
    File transferFile = new File("dnl.ldf"); 
    public FileReciever(Main mn) 
    { 
     main = mn; 
    } 


    static byte[] trim(byte[] bytes) 
    { 
     int i = bytes.length - 1; 
     while (i >= 0 && bytes[i] == 0) 
     { 
      --i; 
     } 

     return Arrays.copyOf(bytes, i + 1); 
    } 

    public void run() { 


     try { 
      ServerSocket recieveSocket = new ServerSocket(11001); 
      while (this != null) { 
       try{ 
       downloadfile.createNewFile(); 
       Socket connectionSocket = recieveSocket.accept(); 
       DataInputStream reader = new DataInputStream(connectionSocket.getInputStream()); 
       reader.read(fileheader); 
       long fileSize = reader.readLong(); 
       System.out.println(bufferSize); 
       filebuffer = new byte[bufferSize]; 

       String fileName = new String(fileheader); 
       fileheader = new byte[headerSize]; 
       FileOutputStream fw = new FileOutputStream(downloadfile); 
       while(reader.read(filebuffer) != -1) 
        { 
         fw.write(filebuffer); 
         filebuffer = new byte[bufferSize]; 
        }   
       //reader.readInt(); 
       reader.close(); 
       fw.close(); 
       //RandomAccessFile file = new RandomAccessFile(downloadfile, "Rwd"); 
       //file.setLength(fileSize); // Strip off the last _byte_, not the last character 
       //file.close(); 

       connectionSocket.close(); 
       FileScreen fs = new FileScreen(downloadfile, fileName, connectionSocket.getInetAddress().getHostName()); 
       fs.setVisible(true); 
       fs.setLocationRelativeTo(null); 
       } 
       catch(Exception ex) 
       {} 
      } 
     } catch (IOException e) { 
      StringWriter sw = new StringWriter(); 
      PrintWriter pw = new PrintWriter(sw); 
      e.printStackTrace(pw); 
      new ErrorScreen("Unable to start the File Recieve Thread", "Luna Messenger may already be running, or another program is using port 11001. Please close any program running on port 11001.", sw.toString()); 
      pw.close(); 
      try { 
       sw.close(); 
      } catch (IOException e1) { 
       // TODO Auto-generated catch block 
       e1.printStackTrace(); 
      } 
     } 
    } 

} 
+0

gは読み込まれたバイト数であり、したがって書き込む必要があります。しかし、代わりにバッファ全体を書きます。そして、あなたは役に立たない新しいバッファを再作成します。 –

+0

これらのもののいくつかは残されています – Hello234

+0

コードはほぼランダムに見えます。 –

答えて

0

あなたの上記のコードでは、私はそれが間違いを起こすと思います。 まず、あなたはこのファイル名のlength.likeを示す番号を追加する必要がありますFileRecieverオン

da.writeInt(fileName.length); //the added code 
da.write(fileName); 

を、受け取るコードは次のとおりです。

int fileNameLength = reader.readInt(); 
fileheader=new byte[fileNameLength]; 
read(reader,fileheader,0,fileNameLength); 

read方法は、長さバイトまで読み取ることができますストリームが終了するまで、入力ストリームからバイト配列に変換します。

public static int read(InputStream in, byte[] b, int off, int len) throws IOException { 
    if (len < 0) { 
     throw new IndexOutOfBoundsException("len is negative"); 
    } 
    int total = 0; 
    while (total < len) { 
     int result = in.read(b, off + total, len - total); 
     if (result == -1) { 
      break; 
     } 
     total += result; 
    } 
    return total; 
} 

秒を、それがFileTransmitterFileRecieverへのファイルの日付を変換し、ちょうどFileTransmitterでのOutputStreamソケットために、ファイルデータを書き込んでいるend.The適切なアプローチで番号を追加してはならない、とドンという正しくありませんortherまた

while((g = message.read(filebuffer)) != -1) 
{ 
    da.write(filebuffer,0,g); 
} 

、そしてどのように多くのバイトreadedする必要がありますあなたがからバイトを読んだとき、あなたの、前にソケットの入力ストリームからreadedバイトの長さに依存:「がtは、他のthings.Likeこれを行いますソケットoupustreamにfilebuffer。受信者コード:

int readLength; 
int sumLength=0; 
while((readLength=reader.read(filebuffer,0,(int)(fileSize-sumLength>filebuffer.length?filebuffer.length:fileSize-sumLength))) != -1){ 
     sumLength+=readLength; 
     fw.write(filebuffer,0,readLength); 
     if(sumLength==fileSize){ 
      break; 
     } 
} 
+0

なぜ整数長を書いているのか気にしないでください。ソケットからEOFまで読んでみませんか? –

+0

@JamesKPolk受信者は、ファイル名のバイト数を読み取る必要があることを知らないため、ファイルバイトを読み取るときに、ファイルデータバイトの一部または元のファイル名バイト未満を読み取ります。 – dabaicai

関連する問題