FileUtils.mv throwing Invalid char \302 and \255 exception
You have an invisible non-ASCII character in your source code, likely added by copy-and-pasting code off a website somewhere.
To be specific, you've got a rogue soft-hyphen in your code, encoded as UTF-8 (soft-hyphen = C2 AD in UTF-8, or \302\255 in octal escape notation).
Best thing to do would be to "show invisibles" in your text editor and see if you can find a space that isn't like the others.
EDIT Pasting your snippet into my text editor reveals a soft-hyphen right after FileUtils.
(between .
and mv
). Delete FileUtils.mv
and retype it to get rid of the character if you can't see it.
Unable to copy files using FileUtils
File srcFile = new File("/path/to/src/file.txt"); // path + filename
File destDir = new File("/path/to/dest/directory"); // path only
FileUtils.copyFileToDirectory(srcFile, destDir);
Try copyFileToDirectory(srcFile, destDir)
, you have to provide the source file absolute path with the file name, and the absolute path to the destination directory.
In addition, make sure you have write permission to copy the file to the destination. I am always on Linux system don't know how to achieve that, similarly you should be have Administrator privilege on Windows or some similar roles which is able to write files.
How do I move a file with Ruby?
You can use FileUtils to do this.
#!/usr/bin/env ruby
require 'fileutils'
FileUtils.mv('/tmp/your_file', '/opt/new/location/your_file')
Remember; if you are moving across partitions, "mv" will copy the file to new destination and unlink the source path.
UTF-8 characters in 'filename' for 'Content-Disposition' yield IllegalArgumentException: Unexpected char
The default character set for HTTP headers is ISO-8859-1. There is however RFC 6266, describing how you can encode the file name in a Content-Disposition
header. Basically, you specify the character set name and then percent-encode the UTF-8 characters. Instead of fileName="my-simple-filename"
you use a parameter starting with filename*=utf-8''
like
import java.net.URLEncoder;
// ...
String fileName = "3$ Mù F'RANçé_33902_Country_5_202105";
String contentDisposition = "attachment;filename*=utf-8''" + encodeFileName(fileName);
// ...
private static String encodeFileName(String fileName) throws UnsupportedEncodingException {
return URLEncoder.encode(fileName, "UTF-8").replace("+", "%20");
}
Using the URL encoder and then modifying the result for "+" is a cheap trick I found here, if you want to avoid using Guava, Spring's ContentDisposition
class or any other library and simply work with JRE classes.
Update: Here is a full MCVE, showing how to send an UTF-8 string both as a POST body and as a content disposition file name. The demo server shows how to decode that header manually - usually HTTP servers should do that automatically.
Maven POM showing used dependencies:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>SO_Java_OkHttp3SendUtf8_70804280</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.9.3</version>
</dependency>
<dependency>
<groupId>org.nanohttpd</groupId>
<artifactId>nanohttpd</artifactId>
<version>2.3.1</version>
</dependency>
</dependencies>
</project>
OkHttp demo client:
import okhttp3.Headers;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import java.io.IOException;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Objects;
public class Client {
public static void main(String[] args) throws IOException {
String fileName = "3$ Mù F'RANçé_33902_Country_5_202105";
String contentDisposition = "attachment;filename*=utf-8''" + encodeFileName(fileName);
RequestBody requestBody = RequestBody.create(fileName.getBytes(StandardCharsets.UTF_8));
Headers headers = new Headers.Builder()
.add("Content-Disposition", contentDisposition)
.add("Content-type", "application/octet-stream; charset=utf-8")
.build();
Request request = new Request.Builder()
.headers(headers)
.post(requestBody)
.url(new URL("http://localhost:8080/"))
.build();
OkHttpClient client = new OkHttpClient();
Response response = client.newCall(request).execute();
System.out.println(Objects.requireNonNull(response.body()).string());
}
private static String encodeFileName(String fileName) {
return URLEncoder.encode(fileName, StandardCharsets.UTF_8).replace("+", "%20");
}
}
NanoHTTPD demo server:
import fi.iki.elonen.NanoHTTPD;
import java.io.IOException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
public class Server extends NanoHTTPD {
public Server() throws IOException {
super(8080);
start(NanoHTTPD.SOCKET_READ_TIMEOUT, false);
System.out.println("\nRunning! Point your browsers to http://localhost:8080/ \n");
}
public static void main(String[] args) throws IOException {
new Server();
}
private static final String UTF_8_FILE_NAME_PREFIX = ";filename*=utf-8''";
private static final int UTF_8_FILE_NAME_PREFIX_LENGTH = UTF_8_FILE_NAME_PREFIX.length();
@Override
public Response serve(IHTTPSession session) {
try {
Map<String, String> files = new HashMap<>();
session.parseBody(files);
String postBody = files.get("postData");
String contentDisposition = session.getHeaders().get("content-disposition");
String fileName = decodeFileName(
contentDisposition.substring(
contentDisposition.indexOf(UTF_8_FILE_NAME_PREFIX) + UTF_8_FILE_NAME_PREFIX_LENGTH
)
);
System.out.println("POST body: " + postBody);
System.out.println("Content disposition: " + contentDisposition);
System.out.println("UTF-8 file name: " + fileName);
return newFixedLengthResponse(postBody + "\n" + fileName);
}
catch (IOException | ResponseException e) {
e.printStackTrace();
return newFixedLengthResponse(e.toString());
}
}
private static String decodeFileName(String fileName) {
return URLDecoder.decode(fileName.replace("%20", "+"), StandardCharsets.UTF_8);
}
}
If first you run the server and then the client, you will see this on the server console:
Running! Point your browsers to http://localhost:8080/
POST body: 3$ Mù F'RANçé_33902_Country_5_202105
Content disposition: attachment;filename*=utf-8''3%24%20M%C3%B9%20F%27RAN%C3%A7%C3%A9_33902_Country_5_202105
UTF-8 file name: 3$ Mù F'RANçé_33902_Country_5_202105
On the client console, you see:
3$ Mù F'RANçé_33902_Country_5_202105
3$ Mù F'RANçé_33902_Country_5_202105
Decode Base64 data in Java
As of v6, Java SE ships with JAXB. javax.xml.bind.DatatypeConverter
has static methods that make this easy. See parseBase64Binary()
and printBase64Binary()
.
UPDATE: JAXB is no longer shipped with Java (since Java 11). If JAXB is required for your project, you will need to configure the relevant libraries via your dependency management system, for example Maven. If you require the compiler (xjc.exe
) you also need to download that separately.
Related Topics
How to Execute 2 or More Commands in the Same Ssh Session
Handle Check Box Forms with an ':Has_Many :Through' Record Association
Rails 4 Error with Every Command "'Load': No Implicit Conversion of Nil into String" (MAC Os X 10.9)
Ruby on Rails: Converting "Somewordhere" to "Some Word Here"
Fresh Install of Rails and Getting Openssl Errors: "Already Initialized Constant Openssl"
Ruby Equivalent of C#'s 'Yield' Keyword, Or, Creating Sequences Without Preallocating Memory
How to Compare Private Attributes in Ruby
Can't All or Most Cases of 'Each' Be Replaced with 'Map'
Rails Reload Dynamic Routes on Multiple Instances/Servers
Why Does Hash#Select and Hash#Reject Pass a Key to a Unary Block
Selenium Webdriver Getting a Cookie Value
How to Create an Operator for Deep Copy/Cloning of Objects in Ruby
Can't Find Gem Railties (>= 0.A) with Executable Rails (Gem::Gemnotfoundexception)
How to Change Environment Variables When Running Rspec for Ruby
Why Does the Break Statement in Ruby Behave Differently When Using Proc.New V. the Ampersand Sign
How to Specify a Regex Character Range That Will Work in European Languages Other Than English