我继承了一些代码:
Process p = new ProcessBuilder("/bin/chmod", "777", path).start();
p.waitFor();
Run Code Online (Sandbox Code Playgroud)
基本上,存在一些古老且高度基于巫术的原因,用于将键/值对作为文件存储在磁盘上.我真的不想进入它.
但是,我留下了一堆IO异常:
Exception :Cannot run program "/bin/chmod": java.io.IOException: error=24, Too many open files
Message: Cannot run program "/bin/chmod": java.io.IOException: error=24, Too many open files
Run Code Online (Sandbox Code Playgroud)
一堆我的意思是在1万亿的领域
我感觉waitFor调用是阻止这些进程等待进程完成它并退出,但我认为chmod在文件实际关闭之前返回结果.有谁知道这是否会导致这些例外?
我的另一个倾向是数千个文件的打开和关闭在java端没有快速发生,并且还有其他事情发生,可能是某种形式的文件缓冲区没有被清除掉正在调用fw.close().
我对java很新,这是一个让我难过的地狱怪异的东西.(很高兴应用程序仍以某种方式运行..吐出一个非常大的日志文件后)
任何人都可以想办法解决这个问题,清除缓冲区或增加文件打开限制,以便jvm可以跟上自己(假设这是问题)
在写入套接字时,我有一种非常奇怪的行为.在我的移动客户端中,我使用的套接字初始化如下:
private void initSocket()
{
socket = new Socket();
socket.connect(new InetSocketAddress(host, port));
os = new DataOutputStream(socket.getOutputStream());
is = new DataInputStream(socket.getInputStream());
}
Run Code Online (Sandbox Code Playgroud)
然后定期(每60秒)我读取一些数据到这个套接字(这里的代码有点简化):
if(!isSocketInitialized())
{
initSocket();
}
byte[] msg = getMessage();
os.write(msg);
os.flush();
int bytesAvailable = is.available( );
if(bytesAvailable>0)
{
byte[] inputBuffer = new byte[bytesAvailable];
int numRead = is.read(inputBuffer, 0, bytesAvailable);
processServerReply(inputBuffer, numRead);
}
Run Code Online (Sandbox Code Playgroud)
它有效.但是......有时(很少,每天可能是1或2次)我的服务器不接收数据.我的客户端日志如下:
Written A
Written B
Written C
Written D
Written E
Run Code Online (Sandbox Code Playgroud)
等等.但在服务器端看起来像:
Received A
Received E
Run Code Online (Sandbox Code Playgroud)
没有收到B,C,D数据记录,尽管事实上在客户端看起来所有数据都是在没有任何例外的情况下发送的!
这样的间隙可能很小(2-3分钟),这不是很糟糕,但有时它们可能非常大(1-2小时= 60-120个周期),这对我的客户来说确实是一个问题.
我真的不知道什么是错的.数据似乎是由客户端发送的,但它永远不会到达服务器端.我也用代理检查了它.
我只有日志而且我无法重现这个问题(但是我的客户每天都会发生一次这种情况)并且在日志中有时我看到连接因异常而被破坏"发送失败:ECONNRESET(连接由同行重置) )".之后,程序关闭套接字,重新初始化它:
// close
is.close();
os.close();
socket.close(); …Run Code Online (Sandbox Code Playgroud) Android Developer参考(本页)说:
Throws FileNotFoundException
Run Code Online (Sandbox Code Playgroud)
但在一开始,它说:
打开与此Context的应用程序包关联的私有文件以进行写入.如果文件尚不存在,则创建该文件.
如果是这种情况,为什么会抛出FileNotFoundException?
我只是想确保我正确处理所有案件.我正在使用默认功能,所以我可以将它包装在try..catch块中没有任何内容的catch块中,因为它不可能FileNotFoundException被抛出默认功能吗?
编辑: '默认功能'的示例:
String FILENAME = "hello_file";
String string = "hello world!";
FileOutputStream fos = context.openFileOutput(FILENAME, Context.MODE_PRIVATE);
fos.write(string.getBytes());
fos.close();
Run Code Online (Sandbox Code Playgroud) 我面临一点奇怪的情况.
我正在从FileInputStream复制到FileOutputStream一个大小约为500MB的文件.它很顺利(需要大约500毫秒).当我第一次关闭这个FileOutputStream 时,大约需要1ms.
但是接下来,当我再次运行时,每次连续关闭大约需要1500-2000毫秒!删除此文件时,持续时间将减少到1毫秒.
java.io我缺少一些基本知识吗?
它似乎与操作系统有关.我在ArchLinux上运行(在Windows 7上运行的相同代码一直在20ms以下).请注意,它是否在OpenJDK或Oracle的JDK中运行并不重要.硬盘驱动器是一个带有ext4文件系统的固态驱动器.
这是我的测试代码:
public void copyMultipleTimes() throws IOException {
copy();
copy();
copy();
new File("/home/d1x/temp/500mb.out").delete();
copy();
copy();
// Runtime.getRuntime().exec("sync") => same results
// Thread.sleep(30000) => same results
// combination of sync & sleep => same results
copy();
}
private void copy() throws IOException {
FileInputStream fis = new FileInputStream("/home/d1x/temp/500mb.in");
FileOutputStream fos = new FileOutputStream("/home/d1x/temp/500mb.out");
IOUtils.copy(fis, fos); // copyLarge => same results
// copying takes always the same amount of time, only close "enlarges" …Run Code Online (Sandbox Code Playgroud) 请转到第二次更新.我不想改变此问题的先前背景.
我正在使用Java应用程序中的wkhtmltoimage.
使用它的标准方法是 - path-to-exe http://url.com/ image.png.
根据他们的文档,如果我们写一个-而不是输入URL,输入转移到STDIN.
我正在使用ProcessBuilder- 开始这个过程-
ProcessBuilder pb = new ProcessBuilder(exe_path, " - ", image_save_path);
Process process = pb.start();
Run Code Online (Sandbox Code Playgroud)
现在我无法弄清楚如何将输入流传递给此进程.
我有一个模板文件读入a DataInputStream,我在最后附加一个字符串:
DataInputStream dis = new DataInputStream (new FileInputStream (currentDirectory+"\\bin\\template.txt"));
byte[] datainBytes = new byte[dis.available()];
dis.readFully(datainBytes);
dis.close();
String content = new String(datainBytes, 0, datainBytes.length);
content+=" <body><div id='chartContainer'><small>Loading chart...</small></div></body></html>";
Run Code Online (Sandbox Code Playgroud)
我怎么管content的STDIN过程中?
UPDATE ---
在Andrzej Doyle的回答之后:
我用过了getOutputStream()这个过程:
ProcessBuilder pb = new ProcessBuilder(full_path, " - ", image_save_path);
pb.redirectErrorStream(true); …Run Code Online (Sandbox Code Playgroud) 可能重复:
在Java文件中间写入字节的最佳方法
我有一个文件,我需要写入字节.
我知道文件中的哪个位置需要插入特定的字节.为了清楚起见,我需要在文件中间写入字节而不删除任何现有字节.然后整个操作应该增加文件的长度.
这样做的最佳方法是什么?
我使用以下代码:
final File newFile = new File("/mnt/sdcard/test/");
newFile.mkdir(); // if I use mkdirs() result is the same
Run Code Online (Sandbox Code Playgroud)
它会创建一个空文件!为什么?
我正在制作一个简单的TCP/IP套接字应用程序
这样做有什么不同:
DataInputStream in = new DataInputStream(clientSocket.getInputStream());
byte[] buffer = new byte[100];
in.readFully(buffer);
Run Code Online (Sandbox Code Playgroud)
与这样做:
DataInputStream in = new DataInputStream(clientSocket.getInputStream());
byte[] buffer = new byte[100];
in.read(buffer);
Run Code Online (Sandbox Code Playgroud)
我看了一下文档,他们有完全相同的描述.readFully()并且read()
因此我可以假设它是一回事吗?
我注意到,java.io和java.nio随机访问文件的实施对于略有不同如何FileLocks进行处理.
看起来好像(在Windows上)java.io为您提供强制文件锁定,并java.nio在分别请求时为您提供建议文件锁定.强制文件锁定意味着锁定适用于所有进程,并且建议适用于遵循相同锁定协议的良好行为进程.
如果我运行以下示例,我可以*.nio手动删除该文件,而*.io文件拒绝删除.
import java.io.*;
import java.lang.management.ManagementFactory;
import java.nio.*;
import java.nio.channels.*;
import java.nio.file.*;
public class NioIoLock {
public static void main(String[] args) throws IOException, InterruptedException {
String workDir = System.getProperty("user.dir");
FileChannel channelIo, channelNio;
FileLock lockIo, lockNio;
// use io
{
String fileName = workDir
+ File.separator
+ ManagementFactory.getRuntimeMXBean().getName()
+ ".io";
File lockFile = new File(fileName);
lockFile.deleteOnExit();
RandomAccessFile file = new RandomAccessFile(lockFile, "rw");
channelIo = file.getChannel();
lockIo …Run Code Online (Sandbox Code Playgroud) 它看起来像java.io.File.(File,String)依赖于JDK版本.代码示例在Windows 10上运行.
代码示例:
public static void main(String... args) {
String path = "C:\\Workspace\\project";
File file = null;
for (String part : path.split("\\\\")) {
file = new File(file, part);
}
System.out.println(file);
// prints "C:Workspace\project" for JDK 9+
// prints "C:\Workspace\project" for JDK 8
}
Run Code Online (Sandbox Code Playgroud)
您能否解决该案件的任何已知问题或解决方案