我是编程新手,我遇到了一个无法解决的问题。我创建了一个共享文件的程序,比如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);
}
}
}
这就是我正在做的事情。我在后台工作者上下载。 首先,我在流上写下我正在做的事情,然后打开文件流,然后开始读取流并写入文件。
@Ňuf我试过你所说的但仍然无法运作 代码如下所示, qtdDown 和 size 中的字节不相等。很抱歉,如果有一些葡萄牙语部分,我的母语是葡萄牙语。
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;
答案 0 :(得分:0)
通过调用read.ReadLine()来丢失字节。虽然此函数仅返回来自一行的数据,但它在内部从网络流中读取更多数据到内部缓冲区,并为后续的read.Read()调用保留剩余数据,这在您的代码中永远不会发生。
使用StreamReader读取数据或直接从NetworkStrem读取数据,但不要将两者的读数混合在一起。
答案 1 :(得分:0)
我在最后的中添加了这一行,如果,* || (fileSize - qtdDown)< 1024 *和文件现在可以工作,我不知道那些最后的字节是否重要,但文件现在可以工作。