2012-05-15 6 views
0

저는 pogramming을 처음 접했고 해결할 수없는 문제가 있습니다. Dropbox와 같은 파일을 공유하는 프로그램을 만들었습니다. 나는 잘 작동하는 서버와 클라이언트를 가지고있다. 문제는 서버에서 파일을 다운로드하려고 할 때 스트림에서 일부 바이트가 누락 된 것 같습니다.파일의 마지막 바이트가 누락되었습니다.

clientSocket = new TcpClient(Program.host, Program.port); 
NetworkStream networkStream = clientSocket.GetStream(); 
StreamWriter write = new StreamWriter(networkStream); 
write.WriteLine(need); 
write.Flush(); 
write.WriteLine(loca); 
write.Flush(); 
StreamReader read = new StreamReader(networkStream); 
Int64 size = Convert.ToInt64(read.ReadLine()); 
long blocks = size/1024; 
long blocksDown = 0; 
try 
{ 
    string fileName = string.Empty; 
    int qtd = 0; 
    int blockSize = 1024; 
    double progress = 0; 
    Int64 qtdDown = 0; 
    Byte[] dataByte = new Byte[blockSize]; 
    bool download = true; 
    lock (this) 
    { 
     networkStream.Read(dataByte, 0, dataByte.Length); 
     int fileNameLen = BitConverter.ToInt32(dataByte, 0); 
     fileName = Encoding.ASCII.GetString(dataByte, 4, fileNameLen); 
     if (File.Exists(Program.loc + fileName)) 
      switch (MessageBox.Show("Ficheiro já existente!\r\nDeseja Substituir?", "Aviso", MessageBoxButtons.YesNo, 
       MessageBoxIcon.Warning)) 
      { 
       case DialogResult.Yes: 
        File.Delete(Program.loc + fileName); 
        download = true; 
        break; 
       case DialogResult.No: 
        download = false; 
        break; 
      } 
     if (download) 
     { 
      Stream fileStream = File.OpenWrite(Program.loc + fileName); 
      fileStream.Write(dataByte, 4 + fileNameLen, (1024 - (4 + fileNameLen))); 
      bool progChanged = false; 
      backWork.WorkerReportsProgress = true; 
      double progAnt = 0; 
      while (true) 
      { 
       qtd = networkStream.Read(dataByte, 0, blockSize); 
       qtdDown += qtd; 
       progress = (double)qtdDown * (double)100/(double)size; 
       if (Math.Round(progress) > Math.Round(progAnt)) 
       { 
        progChanged = true; 
        progAnt = progress; 
       } 
       if (Math.Round(progress) > 0 && progChanged) 
       { 
        backWork.ReportProgress(((int)Math.Round(progress))); 
        progChanged = false; 
       } 
       fileStream.Write(dataByte, 0, qtd); 
       fileStream.Flush(); 
       blocksDown++; 
       if (qtd == 0) 
       { 
        backWork.ReportProgress(100); 
        qtd = networkStream.Read(dataByte, 0, blockSize); 
        networkStream.Close(); 
        fileStream.Close(); 
        break; 
       } 
      } 
      MessageBox.Show("O ficheiro " + fileName + " foi guardado em " + Program.loc + ".", "Download", 
       MessageBoxButtons.OK, MessageBoxIcon.Information); 
     } 
    } 
} 

이것은 내가하고있는 일이다. 나는 배경 작업자에게 다운로드를하고있다. 먼저 스트림에 파일의 스트림을 열고 스트림을 읽고 파일에 쓰기 시작합니다.


는 NUF @ 난 당신이 말을하려고했지만 잘 나던 작업 는 코드는 다음과 같습니다 및 qtdDown크기에서 바이트는 동일하지 않다. 미안 일부 부품이 포르투갈어로되어 있다면, 내 원래 langage는 포르투갈어입니다.

btnAct.Enabled = false; 
    btnBro.Enabled = false; 
    btnDown.Enabled = false; 
    btnSend.Enabled = false; 
    menuStrip1.Enabled = false; 
    pBar.Value = 0; 
    clientSocket = new TcpClient(Program.host, Program.port); 
    NetworkStream networkStream = clientSocket.GetStream(); 
    StreamWriter write = new StreamWriter(networkStream); 
    write.WriteLine(need); 
    write.Flush(); 
    write.WriteLine(loca); 
    write.Flush(); 
    int blockSize = 1024; 
    byte[] fileSizeBytes = new byte[blockSize]; 
    networkStream.Read(fileSizeBytes, 0, blockSize); 
    string fileSizeString = Encoding.ASCII.GetString(fileSizeBytes, 0, fileSizeBytes.Length); 
    fileSize = Convert.ToInt64(fileSizeString); 
    qtdDown = 0; 
    try 
    { 
     string fileName = string.Empty; 
     int qtd = 0; 
     double progress = 0; 
     Byte[] dataByte = new Byte[blockSize]; 
     bool download = true; 
     lock (this) 
     { 
      networkStream.Read(dataByte, 0, dataByte.Length); 
      int fileNameLen = BitConverter.ToInt32(dataByte, 0); 
      fileName = Encoding.ASCII.GetString(dataByte, 4, fileNameLen); 
      if (File.Exists(Program.loc + fileName)) 
       switch (MessageBox.Show("Ficheiro já existente!\r\nDeseja Substituir?", "Aviso", MessageBoxButtons.YesNo, 
        MessageBoxIcon.Warning)) 
       { 
        case DialogResult.Yes: 
         File.Delete(Program.loc + fileName); 
         download = true; 
         break; 
        case DialogResult.No: 
         download = false; 
         break; 
       } 
      if (download) 
      { 
       Stream fileStream = File.OpenWrite(Program.loc + fileName); 
       fileStream.Write(dataByte, 4 + fileNameLen, (1024 - (4 + fileNameLen))); 
       networkStream.ReadTimeout = 60; 
       backWork.WorkerReportsProgress = true; 
       double progAnt = 0; 
       while (true) 
       { 
        qtd = networkStream.Read(dataByte, 0, blockSize); 
        qtdDown += qtd; 
        progress = (double)qtdDown * (double)100/(double)fileSize; 
        if (Math.Round(progress) > Math.Round(progAnt)) 
        { 
         progAnt = progress; 
         backWork.ReportProgress(((int)Math.Round(progress))); 
        } 
        fileStream.Write(dataByte, 0, qtd); 
        if (qtdDown == fileSize) 
        { 
         backWork.ReportProgress(100); 
         fileStream.Close(); 
         networkStream.Close(); 
         break; 
        } 
       } 
       MessageBox.Show("O ficheiro " + fileName + " foi guardado em " + Program.loc + ".", "Download", 
        MessageBoxButtons.OK, MessageBoxIcon.Information); 
      } 
     } 
    } 

    catch (Exception ex) 
    { 
     menuStrip1.Enabled = true; 
     btnAct.Enabled = true; 
     btnBro.Enabled = true; 
     btnDown.Enabled = true; 
     btnSend.Enabled = true; 
     MessageBox.Show("Ocorreu um erro!" + "\r\nBytes Downloaded: " 
      + qtdDown.ToString() + "\\" + fileSize.ToString() + "\r\nDetalhes do Erro: " + ex.Message, "Download", 
      MessageBoxButtons.OK, MessageBoxIcon.Error); 
    } 

    menuStrip1.Enabled = true; 
    btnAct.Enabled = true; 
    btnBro.Enabled = true; 
    btnDown.Enabled = true; 
    btnSend.Enabled = true; 
+1

스트림에서 누락 된 바이트가 있다고 생각하는 이유는 무엇입니까? –

+0

@Ramhound 파일을 다운로드하기 전에 진행률 표시 줄의 값을 변경하기위한 파일 크기를 얻었고 qtdDown이라는 다른 변수가 있습니다.이 변수는 이미 만들어진 다운로드를 나타냅니다. 개울에서 모든 것을 읽은 후에 나는 그것들을 비교하지만 그들은 결코 동일하지 않습니다. – droidsz

답변

0

read.ReadLine()을 호출하면 바이트가 손실됩니다. 이 함수는 한 줄의 데이터 만 반환하지만 내부적으로 네트워크 스트림에서 더 많은 데이터를 내부 버퍼로 읽은 다음 코드에서 결코 발생하지 않는 다음 read.Read() 호출을 위해 남아있는 데이터를 유지합니다.

StreamReader를 사용하여 데이터를 읽거나 NetworkStrem에서 직접 데이터를 읽지 만 둘 다 함께 읽지는 않습니다.

0

에이 라인을 추가 한 경우, * || (fileSize - qtdDown) < 1024 *와 파일이 이제 작동하지만, 마지막 바이트가 중요한지는 모르지만 파일은 이제 작동합니다.

관련 문제