kotlin 中的文件字节错误。如何正确转移?
File byte error in kotlin. How to transfer correctly?
我想用tcp客户端传输文件到服务器,但是图像文件出错了。
我的客户端代码是
import com.sun.xml.internal.messaging.saaj.util.ByteOutputStream
import org.msgpack.core.MessageBufferPacker
import org.msgpack.core.MessagePack
import org.msgpack.core.MessageUnpacker
import java.io.*
import java.net.Socket
import java.util.*
fun main(args: Array<String>) {
fileClient("localhost",1988,"fruit.jpg")
}
class fileClient (host:String, port:Int, file:String){
var s : Socket ?= null
var out = ByteArrayOutputStream()
var msg : MessageBufferPacker = MessagePack.newDefaultBufferPacker()
init {
try {
s = Socket(host,port)
sendFile(file)
}catch (e:Exception){
e.printStackTrace()
}
}
@Throws(IOException::class)
fun sendFile(file: String) {
val dos = DataOutputStream(s!!.getOutputStream())
val buffer = ByteArray(4096)
val filebytes = File(file).readBytes()
var msgdata = ByteOutputStream()
msg.packString(file)
msg.packBinaryHeader(filebytes.size)
msg.writePayload(filebytes)
msg.close()
val data = msg.toByteArray()
val datasize = data.size
val ins = ByteArrayInputStream(data)
dos.writeInt(datasize)
while (ins.read(buffer) > 0) {
dos.write(buffer)
}
dos.close()
}
}
我的服务器代码是
import com.sun.xml.internal.messaging.saaj.util.ByteOutputStream
import org.msgpack.core.MessagePack
import org.msgpack.core.MessageUnpacker
import java.awt.List
import java.io.*
import java.net.ServerSocket
import java.net.Socket
import java.text.SimpleDateFormat
import java.util.*
fun main(args: Array<String>) {
var fs = FileServer(1988)
fs.start()
}
class FileServer(port: Int) : Thread() {
private var ss: ServerSocket? = null
var fileRealName : String ?= null
init {
try {
ss = ServerSocket(port)
} catch (e: IOException) {
e.printStackTrace()
}
}
override fun run() {
while (true) {
try {
val clientSock = ss!!.accept()
saveFile(clientSock)
} catch (e: IOException) {
e.printStackTrace()
}
}
}
@Throws(IOException::class)
private fun saveFile(clientSock: Socket) {
var msgList = ArrayList<Any>()
val dis = DataInputStream(clientSock.inputStream)
val msgdata = ByteOutputStream()
val buffer = ByteArray(4096)
var read = 0
while (true) {
val datalen = dis.readInt() // data length
if(datalen!= null && datalen >0){
var finaldata = ByteArray(datalen)
var process = 0;
while (process <= datalen) {
read = dis.read(buffer)
if (read < 0) {
return
}
msgdata.write(buffer)
process += 4096
}
println(process.toString() + " "+ datalen.toString())
var allData = msgdata.toByteArray().slice(0..datalen).toByteArray()
unpackByte(allData)
}
}
msgdata.close()
dis.close()
}
private fun unpackByte(data:ByteArray){
var unpacker : MessageUnpacker = MessagePack.newDefaultUnpacker(data)
var fileName = unpacker.unpackString().toString()
var filesize = unpacker.unpackBinaryHeader()
var buffer = ByteArray(filesize)
unpacker.readPayload(buffer)
var fos = FileOutputStream(fileName)
fos.write(buffer)
fos.close()
unpacker.close()
}
}
我要传输的文件是
但是传输后,服务器上的图像是这样的。
如何正确传输此文件?
我没有成功重现你的问题。但是我想我已经找到了可能导致文件传输损坏的错误。
在您的服务器代码中有一个无限循环,returns 立即退出方法,使其余方法无法访问。这是关闭连接和流的清理代码。 OutputStream
很可能没有正确关闭,这就是文件写入损坏的原因。
服务器代码应该是这样的:
val datalen = dis.readInt() // data length
if (datalen > 0) {
var finaldata = ByteArray(datalen)
var process = 0;
while (process <= datalen) {
read = dis.read(buffer)
if (read < 0) {
break
}
msgdata.write(buffer)
process += 4096
}
println(process.toString() + " " + datalen.toString())
val allData = msgdata.toByteArray().slice(0..datalen).toByteArray()
unpackByte(allData)
}
msgdata.close()
dis.close()
while
循环是不必要的。此外,您可能应该只 break
循环,而不是 return
来自函数。
P.S。
您是否考虑过使用 IOUtils 来处理所有 IO read/writes?使用这个库,你的一半代码可以被替换为几行代码。
我想用tcp客户端传输文件到服务器,但是图像文件出错了。
我的客户端代码是
import com.sun.xml.internal.messaging.saaj.util.ByteOutputStream
import org.msgpack.core.MessageBufferPacker
import org.msgpack.core.MessagePack
import org.msgpack.core.MessageUnpacker
import java.io.*
import java.net.Socket
import java.util.*
fun main(args: Array<String>) {
fileClient("localhost",1988,"fruit.jpg")
}
class fileClient (host:String, port:Int, file:String){
var s : Socket ?= null
var out = ByteArrayOutputStream()
var msg : MessageBufferPacker = MessagePack.newDefaultBufferPacker()
init {
try {
s = Socket(host,port)
sendFile(file)
}catch (e:Exception){
e.printStackTrace()
}
}
@Throws(IOException::class)
fun sendFile(file: String) {
val dos = DataOutputStream(s!!.getOutputStream())
val buffer = ByteArray(4096)
val filebytes = File(file).readBytes()
var msgdata = ByteOutputStream()
msg.packString(file)
msg.packBinaryHeader(filebytes.size)
msg.writePayload(filebytes)
msg.close()
val data = msg.toByteArray()
val datasize = data.size
val ins = ByteArrayInputStream(data)
dos.writeInt(datasize)
while (ins.read(buffer) > 0) {
dos.write(buffer)
}
dos.close()
}
}
我的服务器代码是
import com.sun.xml.internal.messaging.saaj.util.ByteOutputStream
import org.msgpack.core.MessagePack
import org.msgpack.core.MessageUnpacker
import java.awt.List
import java.io.*
import java.net.ServerSocket
import java.net.Socket
import java.text.SimpleDateFormat
import java.util.*
fun main(args: Array<String>) {
var fs = FileServer(1988)
fs.start()
}
class FileServer(port: Int) : Thread() {
private var ss: ServerSocket? = null
var fileRealName : String ?= null
init {
try {
ss = ServerSocket(port)
} catch (e: IOException) {
e.printStackTrace()
}
}
override fun run() {
while (true) {
try {
val clientSock = ss!!.accept()
saveFile(clientSock)
} catch (e: IOException) {
e.printStackTrace()
}
}
}
@Throws(IOException::class)
private fun saveFile(clientSock: Socket) {
var msgList = ArrayList<Any>()
val dis = DataInputStream(clientSock.inputStream)
val msgdata = ByteOutputStream()
val buffer = ByteArray(4096)
var read = 0
while (true) {
val datalen = dis.readInt() // data length
if(datalen!= null && datalen >0){
var finaldata = ByteArray(datalen)
var process = 0;
while (process <= datalen) {
read = dis.read(buffer)
if (read < 0) {
return
}
msgdata.write(buffer)
process += 4096
}
println(process.toString() + " "+ datalen.toString())
var allData = msgdata.toByteArray().slice(0..datalen).toByteArray()
unpackByte(allData)
}
}
msgdata.close()
dis.close()
}
private fun unpackByte(data:ByteArray){
var unpacker : MessageUnpacker = MessagePack.newDefaultUnpacker(data)
var fileName = unpacker.unpackString().toString()
var filesize = unpacker.unpackBinaryHeader()
var buffer = ByteArray(filesize)
unpacker.readPayload(buffer)
var fos = FileOutputStream(fileName)
fos.write(buffer)
fos.close()
unpacker.close()
}
}
我要传输的文件是
但是传输后,服务器上的图像是这样的。
如何正确传输此文件?
我没有成功重现你的问题。但是我想我已经找到了可能导致文件传输损坏的错误。
在您的服务器代码中有一个无限循环,returns 立即退出方法,使其余方法无法访问。这是关闭连接和流的清理代码。 OutputStream
很可能没有正确关闭,这就是文件写入损坏的原因。
服务器代码应该是这样的:
val datalen = dis.readInt() // data length
if (datalen > 0) {
var finaldata = ByteArray(datalen)
var process = 0;
while (process <= datalen) {
read = dis.read(buffer)
if (read < 0) {
break
}
msgdata.write(buffer)
process += 4096
}
println(process.toString() + " " + datalen.toString())
val allData = msgdata.toByteArray().slice(0..datalen).toByteArray()
unpackByte(allData)
}
msgdata.close()
dis.close()
while
循环是不必要的。此外,您可能应该只 break
循环,而不是 return
来自函数。
P.S。 您是否考虑过使用 IOUtils 来处理所有 IO read/writes?使用这个库,你的一半代码可以被替换为几行代码。