Skip to content

Instantly share code, notes, and snippets.

@nobeans
Last active September 5, 2018 15:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nobeans/fad3a84e608d6c7a469af2a4467eaa5f to your computer and use it in GitHub Desktop.
Save nobeans/fad3a84e608d6c7a469af2a4467eaa5f to your computer and use it in GitHub Desktop.
//
// Helpers
//
void log(String message, boolean linefeed = true) {
if (linefeed) {
System.err.println message
} else {
System.err.print message
}
}
String formatNumber(long number) {
String.format("%,d", number)
}
//
// Main
//
// 引数をパースする。
if (args.size() != 4) {
log "usage: groovy slowCopy.groovy <SRC_FILE_PATH> <DEST_FILE_PATH> <DURATION(sec)> <WRITE_INTERVAL(msec)>"
return
}
def srcFile = new File(args[0])
def destFile = new File(args[1])
def durationSecString = args[2]
def intervalMsecString = args[3]
if (!srcFile.exists()) {
log "ERROR: SRC_FILE_PATH not found: $srcFile"
return
}
if (destFile.exists()) {
log "ERROR: DEST_FILE_PATH already exists: $destFile"
return
}
if (!durationSecString.isInteger()) {
log "ERROR: DURATION must be an integer value: $durationSecString"
return
}
if (!intervalMsecString.isInteger()) {
log "ERROR: WRITE_INTERVAL must be an integer value: $intervalMsecString"
return
}
def durationSec = durationSecString as int
def intervalMsec = intervalMsecString as int
// ビットレートを算出する。
int bitrate = Math.round(srcFile.size() / durationSec)
log "Calculated bitrate: ${formatNumber(bitrate)} (bytes/s) = ${formatNumber(bitrate * 8)} (bits/s)"
// ビットレートを満たしつつ適度な大きさとなるバッチサイズを算出する。
int writingTimes = Math.round((durationSec * 1000) / intervalMsec)
int batchSize = Math.ceil(srcFile.size() / writingTimes)
log "Batch size: ${formatNumber(batchSize)} (Total times: ${formatNumber(writingTimes)})"
// 指定されたビットレートでゆっくりコピーする。
// TODO 現状はざっくり計算で
def startTime = new Date()
byte[] buffer = new byte[batchSize]
log "Copying $srcFile (${formatNumber(srcFile.size())} bytes) to ${destFile}..."
srcFile.withInputStream { ins ->
destFile.withOutputStream { out ->
int readSize
while (readSize = ins.read(buffer)) {
if (readSize == -1) {
log "EOF"
return
}
out.write(buffer, 0, readSize)
log ".", false
Thread.sleep intervalMsec
}
}
}
log "Total time: ${formatNumber(new Date().time - startTime.time)} (msec)"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment